about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/bin/rustc.rs3
-rw-r--r--src/bootstrap/bin/rustdoc.rs5
-rw-r--r--src/bootstrap/bootstrap.py9
-rw-r--r--src/bootstrap/builder.rs57
-rw-r--r--src/bootstrap/builder/tests.rs20
-rw-r--r--src/bootstrap/check.rs65
-rw-r--r--src/bootstrap/compile.rs10
-rw-r--r--src/bootstrap/config.rs52
-rw-r--r--src/bootstrap/dist.rs99
-rw-r--r--src/bootstrap/flags.rs32
-rw-r--r--src/bootstrap/lib.rs16
-rw-r--r--src/bootstrap/native.rs5
-rw-r--r--src/bootstrap/test.rs54
-rw-r--r--src/bootstrap/tool.rs11
-rw-r--r--src/ci/github-actions/ci.yml4
-rwxr-xr-xsrc/ci/scripts/symlink-build-dir.sh18
-rw-r--r--src/doc/rustc/src/linker-plugin-lto.md49
-rw-r--r--src/doc/rustc/src/lints/listing/allowed-by-default.md3
-rw-r--r--src/doc/rustdoc/src/what-is-rustdoc.md23
-rw-r--r--src/doc/unstable-book/src/language-features/ffi-const.md5
-rw-r--r--src/doc/unstable-book/src/language-features/ffi-pure.md5
-rw-r--r--src/doc/unstable-book/src/language-features/rustc-attrs.md4
-rw-r--r--src/doc/unstable-book/src/library-features/slice-check-range.md10
-rw-r--r--src/etc/gdb_lookup.py4
-rw-r--r--src/etc/gdb_providers.py14
-rw-r--r--src/etc/lldb_lookup.py2
-rw-r--r--src/etc/lldb_providers.py13
-rw-r--r--src/etc/natvis/libstd.natvis20
-rw-r--r--src/librustc_llvm/Cargo.toml19
-rw-r--r--src/librustc_llvm/build.rs322
-rw-r--r--src/librustc_llvm/lib.rs173
-rw-r--r--src/librustdoc/clean/mod.rs20
-rw-r--r--src/librustdoc/clean/types.rs53
-rw-r--r--src/librustdoc/html/markdown.rs117
-rw-r--r--src/librustdoc/html/render/mod.rs7
-rw-r--r--src/librustdoc/html/static/rustdoc.css4
-rw-r--r--src/librustdoc/html/static/themes/ayu.css8
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs813
m---------src/llvm-project0
-rw-r--r--src/rustllvm/.editorconfig6
-rw-r--r--src/rustllvm/ArchiveWrapper.cpp226
-rw-r--r--src/rustllvm/CoverageMappingWrapper.cpp70
-rw-r--r--src/rustllvm/Linker.cpp48
-rw-r--r--src/rustllvm/PassWrapper.cpp1655
-rw-r--r--src/rustllvm/README16
-rw-r--r--src/rustllvm/RustWrapper.cpp1721
-rw-r--r--src/rustllvm/rustllvm.h115
-rw-r--r--src/test/debuginfo/pretty-std-collections-hash.rs4
-rw-r--r--src/test/mir-opt/equal_true.opt.InstCombine.diff35
-rw-r--r--src/test/mir-opt/equal_true.rs9
-rw-r--r--src/test/mir-opt/graphviz.main.mir_map.0.dot6
-rw-r--r--src/test/mir-opt/inline/inline-compatibility.rs39
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff25
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff25
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff22
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff22
-rw-r--r--src/test/mir-opt/not_equal_false.opt.InstCombine.diff72
-rw-r--r--src/test/mir-opt/not_equal_false.rs9
-rw-r--r--src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff14
-rw-r--r--src/test/mir-opt/spanview_block.main.mir_map.0.html6
-rw-r--r--src/test/mir-opt/spanview_statement.main.mir_map.0.html8
-rw-r--r--src/test/mir-opt/spanview_terminator.main.mir_map.0.html6
-rw-r--r--src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile4
-rw-r--r--src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile6
-rw-r--r--src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html449
-rw-r--r--src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html449
-rw-r--r--src/test/run-make-fulldeps/pgo-branch-weights/Makefile4
-rw-r--r--src/test/run-make-fulldeps/pgo-gen-lto/Makefile4
-rw-r--r--src/test/run-make-fulldeps/pgo-gen/Makefile4
-rw-r--r--src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile4
-rw-r--r--src/test/run-make-fulldeps/pgo-use/Makefile4
-rw-r--r--src/test/run-make-fulldeps/tools.mk4
-rw-r--r--src/test/rustdoc-ui/assoc-item-not-in-scope.stderr3
-rw-r--r--src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr2
-rw-r--r--src/test/rustdoc-ui/failed-doctest-output.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc-alias-ice.stderr3
-rw-r--r--src/test/rustdoc-ui/intra-link-errors.rs88
-rw-r--r--src/test/rustdoc-ui/intra-link-errors.stderr116
-rw-r--r--src/test/rustdoc-ui/intra-link-prim-conflict.rs4
-rw-r--r--src/test/rustdoc-ui/intra-link-prim-conflict.stderr20
-rw-r--r--src/test/rustdoc-ui/intra-link-span-ice-55723.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-links-ambiguity.stderr12
-rw-r--r--src/test/rustdoc-ui/intra-links-anchors.stderr6
-rw-r--r--src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs18
-rw-r--r--src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr54
-rw-r--r--src/test/rustdoc-ui/intra-links-warning-crlf.stderr8
-rw-r--r--src/test/rustdoc-ui/intra-links-warning.stderr44
-rw-r--r--src/test/rustdoc-ui/lint-group.stderr2
-rw-r--r--src/test/rustdoc/auxiliary/intra-link-pub-use.rs4
-rw-r--r--src/test/rustdoc/const-generics/type-alias.rs6
-rw-r--r--src/test/rustdoc/intra-link-disambiguators-removed.rs51
-rw-r--r--src/test/rustdoc/intra-link-pub-use.rs27
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs3
-rw-r--r--src/test/ui-fulldeps/session-derive-errors.rs260
-rw-r--r--src/test/ui-fulldeps/session-derive-errors.stderr135
-rw-r--r--src/test/ui/array-slice-vec/slice-2.rs62
-rw-r--r--src/test/ui/array-slice-vec/vec-concat.rs14
-rw-r--r--src/test/ui/array-slice-vec/vec-growth.rs16
-rw-r--r--src/test/ui/array-slice-vec/vec-push.rs3
-rw-r--r--src/test/ui/array-slice-vec/vec-slice.rs9
-rw-r--r--src/test/ui/array-slice-vec/vec-to_str.rs12
-rw-r--r--src/test/ui/array-slice-vec/vec.rs15
-rw-r--r--src/test/ui/ast-json/ast-json-noexpand-output.stdout2
-rw-r--r--src/test/ui/ast-json/ast-json-output.stdout2
-rw-r--r--src/test/ui/attributes/register-attr-tool-prelude.rs2
-rw-r--r--src/test/ui/attributes/register-attr-tool-prelude.stderr4
-rw-r--r--src/test/ui/bad/bad-module.rs4
-rw-r--r--src/test/ui/bad/bad-module.stderr8
-rw-r--r--src/test/ui/coherence/conflicting-impl-with-err.stderr8
-rw-r--r--src/test/ui/const-generics/auxiliary/const_generic_lib.rs4
-rw-r--r--src/test/ui/const-generics/auxiliary/impl-const.rs4
-rw-r--r--src/test/ui/const-generics/const-argument-cross-crate-mismatch.full.stderr (renamed from src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr)4
-rw-r--r--src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr15
-rw-r--r--src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs1
-rw-r--r--src/test/ui/const-generics/const-argument-cross-crate.rs1
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr10
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr10
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs17
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr10
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple.rs18
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr9
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr10
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs16
-rw-r--r--src/test/ui/const-generics/defaults/complex-unord-param.min.stderr8
-rw-r--r--src/test/ui/const-generics/defaults/complex-unord-param.rs10
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr (renamed from src/test/ui/const-generics/defaults/intermixed-lifetime.stderr)4
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr26
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.rs12
-rw-r--r--src/test/ui/const-generics/defaults/simple-defaults.min.stderr8
-rw-r--r--src/test/ui/const-generics/defaults/simple-defaults.rs9
-rw-r--r--src/test/ui/const-generics/invalid-enum.rs39
-rw-r--r--src/test/ui/const-generics/invalid-enum.stderr99
-rw-r--r--src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs4
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.full.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.stderr19
-rw-r--r--src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs8
-rw-r--r--src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.stderr19
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.full.stderr (renamed from src/test/ui/const-generics/issues/issue-62220.stderr)2
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.full.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.stderr19
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.full.stderr (renamed from src/test/ui/const-generics/issues/issue-62504.stderr)2
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.rs10
-rw-r--r--src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-62579-no-match.rs10
-rw-r--r--src/test/ui/const-generics/issues/issue-62579-no-match.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.full.stderr (renamed from src/test/ui/const-generics/issues/issue-62878.stderr)19
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.min.stderr18
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.rs12
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-2.full.stderr (renamed from src/test/ui/const-generics/issues/issue-67185-2.stderr)23
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-2.min.stderr103
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-2.rs6
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.full.stderr (renamed from src/test/ui/const-generics/issues/issue-67739.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.rs11
-rw-r--r--src/test/ui/const-generics/issues/issue-68366.full.stderr21
-rw-r--r--src/test/ui/const-generics/issues/issue-68366.min.stderr29
-rw-r--r--src/test/ui/const-generics/issues/issue-68366.rs21
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.full.stderr (renamed from src/test/ui/const-generics/issues/issue-72787.stderr)10
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.min.stderr57
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.rs22
-rw-r--r--src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr (renamed from src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr)2
-rw-r--r--src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-73120.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/type-dependent/auxiliary/type_dependent_lib.rs5
-rw-r--r--src/test/ui/const_evaluatable/associated-const.rs11
-rw-r--r--src/test/ui/const_evaluatable/function-call.rs19
-rw-r--r--src/test/ui/const_evaluatable/function-call.stderr12
-rw-r--r--src/test/ui/consts/const-nonzero.rs16
-rw-r--r--src/test/ui/consts/cow-is-borrowed.rs15
-rw-r--r--src/test/ui/consts/duration-consts-2.rs42
-rw-r--r--src/test/ui/consts/is_ascii.rs15
-rw-r--r--src/test/ui/consts/promote-no-mut.rs10
-rw-r--r--src/test/ui/consts/promote-no-mut.stderr23
-rw-r--r--src/test/ui/consts/promotion-mutable-ref.rs17
-rw-r--r--src/test/ui/consts/std/net/ipv4.rs58
-rw-r--r--src/test/ui/consts/std/net/ipv6.rs53
-rw-r--r--src/test/ui/derived-errors/issue-31997-1.stderr2
-rw-r--r--src/test/ui/derives/derive-on-trait-item-or-impl-item.stderr5
-rw-r--r--src/test/ui/derives/deriving-non-type.stderr19
-rw-r--r--src/test/ui/dyn-trait-compatibility.rs4
-rw-r--r--src/test/ui/dyn-trait-compatibility.stderr8
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs3
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr12
-rw-r--r--src/test/ui/error-codes/E0017.rs2
-rw-r--r--src/test/ui/error-codes/E0017.stderr41
-rw-r--r--src/test/ui/error-codes/E0388.rs2
-rw-r--r--src/test/ui/error-codes/E0388.stderr39
-rw-r--r--src/test/ui/error-codes/E0433.stderr4
-rw-r--r--src/test/ui/export-fully-qualified.rs4
-rw-r--r--src/test/ui/export-fully-qualified.stderr6
-rw-r--r--src/test/ui/export2.rs2
-rw-r--r--src/test/ui/export2.stderr4
-rw-r--r--src/test/ui/extern-flag/multiple-opts.stderr4
-rw-r--r--src/test/ui/extern-flag/noprelude.stderr4
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr11
-rw-r--r--src/test/ui/generator/static-generators.rs2
-rw-r--r--src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs4
-rw-r--r--src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr8
-rw-r--r--src/test/ui/hygiene/no_implicit_prelude.stderr2
-rw-r--r--src/test/ui/impl-trait/issue-56445.rs3
-rw-r--r--src/test/ui/impl-trait/issue-72911.stderr8
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-fail.rs4
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-fail.stderr8
-rw-r--r--src/test/ui/issues/auxiliary/issue-75907.rs5
-rw-r--r--src/test/ui/issues/issue-33293.rs2
-rw-r--r--src/test/ui/issues/issue-33293.stderr4
-rw-r--r--src/test/ui/issues/issue-36617.stderr3
-rw-r--r--src/test/ui/issues/issue-43023.stderr7
-rw-r--r--src/test/ui/issues/issue-49934-errors.stderr5
-rw-r--r--src/test/ui/issues/issue-75907.rs18
-rw-r--r--src/test/ui/issues/issue-75907.stderr29
-rw-r--r--src/test/ui/issues/issue-75907_b.rs11
-rw-r--r--src/test/ui/issues/issue-75907_b.stderr9
-rw-r--r--src/test/ui/issues/issue-76077-1.fixed18
-rw-r--r--src/test/ui/issues/issue-76077-1.rs18
-rw-r--r--src/test/ui/issues/issue-76077-1.stderr24
-rw-r--r--src/test/ui/issues/issue-76077.rs10
-rw-r--r--src/test/ui/issues/issue-76077.stderr8
-rw-r--r--src/test/ui/lazy_normalization_consts/issue-73980.rs2
-rw-r--r--src/test/ui/lazy_normalization_consts/issue-73980.stderr12
-rw-r--r--src/test/ui/lint/lint-const-item-mutation.rs21
-rw-r--r--src/test/ui/lint/lint-const-item-mutation.stderr89
-rw-r--r--src/test/ui/macros/builtin-prelude-no-accidents.rs6
-rw-r--r--src/test/ui/macros/builtin-prelude-no-accidents.stderr12
-rw-r--r--src/test/ui/macros/macro-inner-attributes.rs2
-rw-r--r--src/test/ui/macros/macro-inner-attributes.stderr4
-rw-r--r--src/test/ui/macros/macro_path_as_generic_bound.stderr4
-rw-r--r--src/test/ui/macros/trace_faulty_macros.stderr3
-rw-r--r--src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr3
-rw-r--r--src/test/ui/mir/issue-76248.rs29
-rw-r--r--src/test/ui/mod/mod_file_disambig.rs2
-rw-r--r--src/test/ui/mod/mod_file_disambig.stderr4
-rw-r--r--src/test/ui/parser/mod_file_not_exist.rs2
-rw-r--r--src/test/ui/parser/mod_file_not_exist.stderr4
-rw-r--r--src/test/ui/parser/mod_file_not_exist_windows.rs2
-rw-r--r--src/test/ui/parser/mod_file_not_exist_windows.stderr4
-rw-r--r--src/test/ui/parser/unsafe-foreign-mod.rs9
-rw-r--r--src/test/ui/parser/unsafe-foreign-mod.stderr14
-rw-r--r--src/test/ui/parser/unsafe-mod.rs9
-rw-r--r--src/test/ui/parser/unsafe-mod.stderr23
-rw-r--r--src/test/ui/pattern/pattern-error-continue.rs2
-rw-r--r--src/test/ui/pattern/pattern-error-continue.stderr4
-rw-r--r--src/test/ui/proc-macro/attributes-on-modules-fail.stderr4
-rw-r--r--src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs89
-rw-r--r--src/test/ui/proc-macro/capture-macro-rules-invoke.rs29
-rw-r--r--src/test/ui/proc-macro/capture-macro-rules-invoke.stdout303
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs31
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout5
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs7
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs7
-rw-r--r--src/test/ui/proc-macro/macros-in-extern-derive.stderr3
-rw-r--r--src/test/ui/proc-macro/unsafe-foreign-mod.rs14
-rw-r--r--src/test/ui/proc-macro/unsafe-mod.rs13
-rw-r--r--src/test/ui/resolve/use_suggestion.stderr6
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr2
-rw-r--r--src/test/ui/span/issue-43927-non-ADT-derive.stderr3
-rw-r--r--src/test/ui/str-concat.rs9
-rw-r--r--src/test/ui/str/str-idx.stderr6
-rw-r--r--src/test/ui/str/str-mut-idx.stderr4
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path.rs2
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path.stderr4
-rw-r--r--src/test/ui/try-block/try-block-in-return.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-72793.rs27
-rw-r--r--src/test/ui/type-alias/issue-62263-self-in-atb.rs2
-rw-r--r--src/test/ui/type-alias/issue-62263-self-in-atb.stderr4
-rw-r--r--src/test/ui/type-alias/issue-62305-self-assoc-ty.rs2
-rw-r--r--src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr4
-rw-r--r--src/test/ui/type/type-path-err-node-types.rs2
-rw-r--r--src/test/ui/type/type-path-err-node-types.stderr4
-rw-r--r--src/test/ui/union/union-deref.rs28
-rw-r--r--src/test/ui/union/union-deref.stderr56
-rw-r--r--src/test/ui/unknown-tool-name.rs2
-rw-r--r--src/test/ui/unknown-tool-name.stderr4
-rw-r--r--src/test/ui/use/use-self-type.rs2
-rw-r--r--src/test/ui/use/use-self-type.stderr6
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/CHANGELOG.md110
-rw-r--r--src/tools/clippy/clippy_lints/src/async_yields_async.rs86
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/create_dir.rs51
-rw-r--r--src/tools/clippy/clippy_lints/src/default_trait_access.rs46
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_variants.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops.rs100
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/single_component_path_imports.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/temporary_assignment.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/types.rs124
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/ast_utils.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/mod.rs100
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/paths.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/sugg.rs6
-rw-r--r--src/tools/clippy/src/lintlist/mod.rs14
-rw-r--r--src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr4
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.fixed68
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.rs68
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.stderr96
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs1
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr32
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.fixed3
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.rs5
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.stderr10
-rw-r--r--src/tools/clippy/tests/ui/create_dir.fixed17
-rw-r--r--src/tools/clippy/tests/ui/create_dir.rs17
-rw-r--r--src/tools/clippy/tests/ui/create_dir.stderr16
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.fixed106
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.rs5
-rw-r--r--src/tools/clippy/tests/ui/default_trait_access.stderr26
-rw-r--r--src/tools/clippy/tests/ui/doc.rs13
-rw-r--r--src/tools/clippy/tests/ui/doc.stderr50
-rw-r--r--src/tools/clippy/tests/ui/functions_maxlines.stderr2
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr36
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed17
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.rs17
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr20
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr34
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr12
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.rs112
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.stderr42
-rw-r--r--src/tools/clippy/tests/ui/temporary_assignment.rs6
-rw-r--r--src/tools/clippy/tests/ui/temporary_assignment.stderr34
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs8
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.rs13
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.stderr96
-rw-r--r--src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr14
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.fixed42
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.rs42
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed8
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs8
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.stderr2
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs25
-rw-r--r--src/tools/compiletest/src/main.rs29
m---------src/tools/miri16
m---------src/tools/rls0
m---------src/tools/rust-analyzer32
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml2
m---------src/tools/rustfmt10
355 files changed, 6552 insertions, 6304 deletions
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 4dd71ebade1..3694bdbf670 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -112,6 +112,9 @@ fn main() {
         if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
             cmd.arg(format!("-Clinker={}", host_linker));
         }
+        if env::var_os("RUSTC_HOST_FUSE_LD_LLD").is_some() {
+            cmd.arg("-Clink-args=-fuse-ld=lld");
+        }
 
         if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
             if s == "true" {
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index ab846adf942..cb58eb89ad8 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -42,11 +42,14 @@ fn main() {
     if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
         cmd.arg("-Z").arg("force-unstable-if-unmarked");
     }
-    if let Some(linker) = env::var_os("RUSTC_TARGET_LINKER") {
+    if let Some(linker) = env::var_os("RUSTDOC_LINKER") {
         let mut arg = OsString::from("-Clinker=");
         arg.push(&linker);
         cmd.arg(arg);
     }
+    if env::var_os("RUSTDOC_FUSE_LD_LLD").is_some() {
+        cmd.arg("-Clink-args=-fuse-ld=lld");
+    }
 
     // Needed to be able to run all rustdoc tests.
     if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") {
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index c3f1bac177d..955c72856dc 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -398,14 +398,6 @@ class RustBuild(object):
             with output(self.rustc_stamp()) as rust_stamp:
                 rust_stamp.write(self.date)
 
-            # This is required so that we don't mix incompatible MinGW
-            # libraries/binaries that are included in rust-std with
-            # the system MinGW ones.
-            if "pc-windows-gnu" in self.build:
-                filename = "rust-mingw-{}-{}{}".format(
-                    rustc_channel, self.build, tarball_suffix)
-                self._download_stage0_helper(filename, "rust-mingw", tarball_suffix)
-
         if self.cargo().startswith(self.bin_root()) and \
                 (not os.path.exists(self.cargo()) or
                  self.program_out_of_date(self.cargo_stamp())):
@@ -714,7 +706,6 @@ class RustBuild(object):
         # See also: <https://github.com/rust-lang/rust/issues/70208>.
         if "CARGO_BUILD_TARGET" in env:
             del env["CARGO_BUILD_TARGET"]
-        env["RUSTC_BOOTSTRAP"] = '1'
         env["CARGO_TARGET_DIR"] = build_dir
         env["RUSTC"] = self.rustc()
         env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index cecc9ef75ea..31d4f1f28a8 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -87,11 +87,16 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
 
 pub struct RunConfig<'a> {
     pub builder: &'a Builder<'a>,
-    pub host: TargetSelection,
     pub target: TargetSelection,
     pub path: PathBuf,
 }
 
+impl RunConfig<'_> {
+    pub fn build_triple(&self) -> TargetSelection {
+        self.builder.build.build
+    }
+}
+
 struct StepDescription {
     default: bool,
     only_hosts: bool,
@@ -165,7 +170,6 @@ impl StepDescription {
                 pathset, self.name, builder.config.exclude
             );
         }
-        let hosts = &builder.hosts;
 
         // Determine the targets participating in this rule.
         let targets = if self.only_hosts {
@@ -178,16 +182,9 @@ impl StepDescription {
             &builder.targets
         };
 
-        for host in hosts {
-            for target in targets {
-                let run = RunConfig {
-                    builder,
-                    path: pathset.path(builder),
-                    host: *host,
-                    target: *target,
-                };
-                (self.make_run)(run);
-            }
+        for target in targets {
+            let run = RunConfig { builder, path: pathset.path(builder), target: *target };
+            (self.make_run)(run);
         }
     }
 
@@ -382,7 +379,7 @@ impl<'a> Builder<'a> {
                 native::Lld
             ),
             Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => {
-                describe!(check::Std, check::Rustc, check::Rustdoc, check::Clippy)
+                describe!(check::Std, check::Rustc, check::Rustdoc, check::Clippy, check::Bootstrap)
             }
             Kind::Test => describe!(
                 crate::toolstate::ToolStateCheck,
@@ -471,6 +468,7 @@ impl<'a> Builder<'a> {
                 dist::Clippy,
                 dist::Miri,
                 dist::LlvmTools,
+                dist::RustDev,
                 dist::Extended,
                 dist::HashSign
             ),
@@ -755,8 +753,11 @@ impl<'a> Builder<'a> {
         cmd.env_remove("MAKEFLAGS");
         cmd.env_remove("MFLAGS");
 
-        if let Some(linker) = self.linker(compiler.host, true) {
-            cmd.env("RUSTC_TARGET_LINKER", linker);
+        if let Some(linker) = self.linker(compiler.host) {
+            cmd.env("RUSTDOC_LINKER", linker);
+        }
+        if self.is_fuse_ld_lld(compiler.host) {
+            cmd.env("RUSTDOC_FUSE_LD_LLD", "1");
         }
         cmd
     }
@@ -796,7 +797,7 @@ impl<'a> Builder<'a> {
         if cmd == "doc" || cmd == "rustdoc" {
             let my_out = match mode {
                 // This is the intended out directory for compiler documentation.
-                Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target),
+                Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
                 Mode::Std => out_dir.join(target.triple).join("doc"),
                 _ => panic!("doc mode {:?} not expected", mode),
             };
@@ -811,7 +812,7 @@ impl<'a> Builder<'a> {
             format!("CARGO_PROFILE_{}_{}", profile, name)
         };
 
-        // See comment in librustc_llvm/build.rs for why this is necessary, largely llvm-config
+        // See comment in rustc_llvm/build.rs for why this is necessary, largely llvm-config
         // needs to not accidentally link to libLLVM in stage0/lib.
         cargo.env("REAL_LIBRARY_PATH_VAR", &util::dylib_path_var());
         if let Some(e) = env::var_os(util::dylib_path_var()) {
@@ -828,9 +829,9 @@ impl<'a> Builder<'a> {
         // scripts can do less work (i.e. not building/requiring LLVM).
         if cmd == "check" || cmd == "clippy" || cmd == "fix" {
             // If we've not yet built LLVM, or it's stale, then bust
-            // the librustc_llvm cache. That will always work, even though it
+            // the rustc_llvm cache. That will always work, even though it
             // may mean that on the next non-check build we'll need to rebuild
-            // librustc_llvm. But if LLVM is stale, that'll be a tiny amount
+            // rustc_llvm. But if LLVM is stale, that'll be a tiny amount
             // of work comparitively, and we'd likely need to rebuild it anyway,
             // so that's okay.
             if crate::native::prebuilt_llvm_config(self, target).is_err() {
@@ -874,7 +875,7 @@ impl<'a> Builder<'a> {
 
         match mode {
             Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
-            Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
+            Mode::Rustc | Mode::ToolRustc => {
                 // Build proc macros both for the host and the target
                 if target != compiler.host && cmd != "check" {
                     cargo.arg("-Zdual-proc-macros");
@@ -1041,16 +1042,18 @@ impl<'a> Builder<'a> {
             }
         }
 
-        if let Some(host_linker) = self.linker(compiler.host, true) {
+        if let Some(host_linker) = self.linker(compiler.host) {
             cargo.env("RUSTC_HOST_LINKER", host_linker);
         }
+        if self.is_fuse_ld_lld(compiler.host) {
+            cargo.env("RUSTC_HOST_FUSE_LD_LLD", "1");
+        }
 
-        if let Some(target_linker) = self.linker(target, true) {
+        if let Some(target_linker) = self.linker(target) {
             let target = crate::envify(&target.triple);
             cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
         }
-
-        if self.config.use_lld && !target.contains("msvc") {
+        if self.is_fuse_ld_lld(target) {
             rustflags.arg("-Clink-args=-fuse-ld=lld");
         }
 
@@ -1059,7 +1062,7 @@ impl<'a> Builder<'a> {
         }
 
         let debuginfo_level = match mode {
-            Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
+            Mode::Rustc => self.config.rust_debuginfo_level_rustc,
             Mode::Std => self.config.rust_debuginfo_level_std,
             Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {
                 self.config.rust_debuginfo_level_tools
@@ -1196,7 +1199,7 @@ impl<'a> Builder<'a> {
             rustdocflags.arg("-Winvalid_codeblock_attributes");
         }
 
-        if let Mode::Rustc | Mode::Codegen = mode {
+        if mode == Mode::Rustc {
             rustflags.arg("-Zunstable-options");
             rustflags.arg("-Wrustc::internal");
         }
@@ -1359,7 +1362,7 @@ impl<'a> Builder<'a> {
         // When we build Rust dylibs they're all intended for intermediate
         // usage, so make sure we pass the -Cprefer-dynamic flag instead of
         // linking all deps statically into the dylib.
-        if let Mode::Std | Mode::Rustc | Mode::Codegen = mode {
+        if matches!(mode, Mode::Std | Mode::Rustc) {
             rustflags.arg("-Cprefer-dynamic");
         }
 
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index aeb0d713ef0..c6eac95c345 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -217,6 +217,16 @@ mod dist {
                 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
             ]
         );
+        assert_eq!(
+            first(builder.cache.all::<compile::Std>()),
+            &[
+                compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
+                compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
+                compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
+                compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+                compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
+            ],
+        );
         assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
     }
 
@@ -384,12 +394,9 @@ mod dist {
                 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
                 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
                 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
-                compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a },
                 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
                 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
-                compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b },
                 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
-                compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c },
             ]
         );
         assert!(!builder.cache.all::<compile::Assemble>().is_empty());
@@ -399,10 +406,8 @@ mod dist {
                 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
                 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
                 compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a },
-                compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a },
                 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
                 compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b },
-                compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b },
             ]
         );
     }
@@ -425,12 +430,9 @@ mod dist {
                 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
                 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
                 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
-                compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a },
                 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
                 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
-                compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b },
                 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
-                compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c },
             ]
         );
         assert_eq!(
@@ -439,7 +441,6 @@ mod dist {
                 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
                 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
                 compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
-                compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
             ]
         );
         assert_eq!(
@@ -447,7 +448,6 @@ mod dist {
             &[
                 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
                 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
-                compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
             ]
         );
     }
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 9f34bb4e6cc..ead0bd0413b 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -66,6 +66,43 @@ impl Step for Std {
         let libdir = builder.sysroot_libdir(compiler, target);
         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
         add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
+
+        // Then run cargo again, once we've put the rmeta files for the library
+        // crates into the sysroot. This is needed because e.g., core's tests
+        // depend on `libtest` -- Cargo presumes it will exist, but it doesn't
+        // since we initialize with an empty sysroot.
+        //
+        // Currently only the "libtest" tree of crates does this.
+
+        let mut cargo = builder.cargo(
+            compiler,
+            Mode::Std,
+            SourceType::InTree,
+            target,
+            cargo_subcommand(builder.kind),
+        );
+        std_cargo(builder, target, compiler.stage, &mut cargo);
+        cargo.arg("--all-targets");
+
+        // Explicitly pass -p for all dependencies krates -- this will force cargo
+        // to also check the tests/benches/examples for these crates, rather
+        // than just the leaf crate.
+        for krate in builder.in_tree_crates("test") {
+            cargo.arg("-p").arg(krate.name);
+        }
+
+        builder.info(&format!(
+            "Checking std test/bench/example targets ({} -> {})",
+            &compiler.host, target
+        ));
+        run_cargo(
+            builder,
+            cargo,
+            args(builder.kind),
+            &libstd_test_stamp(builder, compiler, target),
+            vec![],
+            true,
+        );
     }
 }
 
@@ -106,6 +143,14 @@ impl Step for Rustc {
             cargo_subcommand(builder.kind),
         );
         rustc_cargo(builder, &mut cargo, target);
+        cargo.arg("--all-targets");
+
+        // Explicitly pass -p for all compiler krates -- this will force cargo
+        // to also check the tests/benches/examples for these crates, rather
+        // than just the leaf crate.
+        for krate in builder.in_tree_crates("rustc-main") {
+            cargo.arg("-p").arg(krate.name);
+        }
 
         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
         run_cargo(
@@ -149,7 +194,7 @@ macro_rules! tool_check_step {
 
                 builder.ensure(Rustc { target });
 
-                let cargo = prepare_tool_cargo(
+                let mut cargo = prepare_tool_cargo(
                     builder,
                     compiler,
                     Mode::ToolRustc,
@@ -160,12 +205,14 @@ macro_rules! tool_check_step {
                     &[],
                 );
 
-                println!(
+                cargo.arg("--all-targets");
+
+                builder.info(&format!(
                     "Checking {} artifacts ({} -> {})",
                     stringify!($name).to_lowercase(),
                     &compiler.host.triple,
                     target.triple
-                );
+                ));
                 run_cargo(
                     builder,
                     cargo,
@@ -202,12 +249,24 @@ tool_check_step!(Rustdoc, "src/tools/rustdoc", SourceType::InTree);
 // rejected.
 tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
 
+tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree);
+
 /// Cargo's output path for the standard library in a given stage, compiled
 /// by a particular compiler for the specified target.
 fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
 }
 
+/// Cargo's output path for the standard library in a given stage, compiled
+/// by a particular compiler for the specified target.
+fn libstd_test_stamp(
+    builder: &Builder<'_>,
+    compiler: Compiler,
+    target: TargetSelection,
+) -> PathBuf {
+    builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check-test.stamp")
+}
+
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 7814ca8e5bb..e0dddda83b9 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -45,7 +45,7 @@ impl Step for Std {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Std {
-            compiler: run.builder.compiler(run.builder.top_stage, run.host),
+            compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
             target: run.target,
         });
     }
@@ -385,7 +385,7 @@ impl Step for StartupObjects {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(StartupObjects {
-            compiler: run.builder.compiler(run.builder.top_stage, run.host),
+            compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
             target: run.target,
         });
     }
@@ -454,7 +454,7 @@ impl Step for Rustc {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Rustc {
-            compiler: run.builder.compiler(run.builder.top_stage, run.host),
+            compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
             target: run.target,
         });
     }
@@ -560,7 +560,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
     }
 
     // Pass down configuration from the LLVM build into the build of
-    // librustc_llvm and librustc_codegen_llvm.
+    // rustc_llvm and rustc_codegen_llvm.
     //
     // Note that this is disabled if LLVM itself is disabled or we're in a check
     // build. If we are in a check build we still go ahead here presuming we've
@@ -579,7 +579,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
         if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
             cargo.env("CFG_LLVM_ROOT", s);
         }
-        // Some LLVM linker flags (-L and -l) may be needed to link librustc_llvm.
+        // Some LLVM linker flags (-L and -l) may be needed to link rustc_llvm.
         if let Some(ref s) = builder.config.llvm_ldflags {
             cargo.env("LLVM_LINKER_FLAGS", s);
         }
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index ad2f4877867..5a79d3db5c9 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -273,10 +273,8 @@ struct TomlConfig {
 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
 struct Build {
     build: Option<String>,
-    #[serde(default)]
-    host: Vec<String>,
-    #[serde(default)]
-    target: Vec<String>,
+    host: Option<Vec<String>>,
+    target: Option<Vec<String>>,
     // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable
     build_dir: Option<String>,
     cargo: Option<String>,
@@ -505,11 +503,6 @@ impl Config {
             config.out = dir;
         }
 
-        // If --target was specified but --host wasn't specified, don't run any host-only tests.
-        let has_hosts = !flags.host.is_empty();
-        let has_targets = !flags.target.is_empty();
-        config.skip_only_host_steps = !has_hosts && has_targets;
-
         let toml = file
             .map(|file| {
                 let contents = t!(fs::read_to_string(&file));
@@ -528,25 +521,28 @@ impl Config {
             .unwrap_or_else(TomlConfig::default);
 
         let build = toml.build.clone().unwrap_or_default();
-        // set by bootstrap.py
-        config.hosts.push(config.build);
-        for host in build.host.iter().map(|h| TargetSelection::from_user(h)) {
-            if !config.hosts.contains(&host) {
-                config.hosts.push(host);
-            }
-        }
-        for target in config
-            .hosts
-            .iter()
-            .copied()
-            .chain(build.target.iter().map(|h| TargetSelection::from_user(h)))
-        {
-            if !config.targets.contains(&target) {
-                config.targets.push(target);
-            }
-        }
-        config.hosts = if !flags.host.is_empty() { flags.host } else { config.hosts };
-        config.targets = if !flags.target.is_empty() { flags.target } else { config.targets };
+
+        // If --target was specified but --host wasn't specified, don't run any host-only tests.
+        let has_hosts = build.host.is_some() || flags.host.is_some();
+        let has_targets = build.target.is_some() || flags.target.is_some();
+        config.skip_only_host_steps = !has_hosts && has_targets;
+
+        config.hosts = if let Some(arg_host) = flags.host.clone() {
+            arg_host
+        } else if let Some(file_host) = build.host {
+            file_host.iter().map(|h| TargetSelection::from_user(h)).collect()
+        } else {
+            vec![config.build]
+        };
+        config.targets = if let Some(arg_target) = flags.target.clone() {
+            arg_target
+        } else if let Some(file_target) = build.target {
+            file_target.iter().map(|h| TargetSelection::from_user(h)).collect()
+        } else {
+            // If target is *not* configured, then default to the host
+            // toolchains.
+            config.hosts.clone()
+        };
 
         config.nodejs = build.nodejs.map(PathBuf::from);
         config.gdb = build.gdb.map(PathBuf::from);
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index c1022099a02..e22cdb13928 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -323,8 +323,8 @@ fn make_win_dist(
     // Warn windows-gnu users that the bundled GCC cannot compile C files
     builder.create(
         &target_bin_dir.join("GCC-WARNING.txt"),
-        "gcc.exe contained in this folder cannot be used for compiling C files - it is only\
-         used as a linker. In order to be able to compile projects containing C code use\
+        "gcc.exe contained in this folder cannot be used for compiling C files - it is only \
+         used as a linker. In order to be able to compile projects containing C code use \
          the GCC provided by MinGW or Cygwin.",
     );
 
@@ -605,7 +605,9 @@ impl Step for DebuggerScripts {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(DebuggerScripts {
-            sysroot: run.builder.sysroot(run.builder.compiler(run.builder.top_stage, run.host)),
+            sysroot: run
+                .builder
+                .sysroot(run.builder.compiler(run.builder.top_stage, run.build_triple())),
             host: run.target,
         });
     }
@@ -2499,3 +2501,94 @@ impl Step for LlvmTools {
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
     }
 }
+
+// Tarball intended for internal consumption to ease rustc/std development.
+//
+// Should not be considered stable by end users.
+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+pub struct RustDev {
+    pub target: TargetSelection,
+}
+
+impl Step for RustDev {
+    type Output = Option<PathBuf>;
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("rust-dev")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(RustDev { target: run.target });
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+        let target = self.target;
+
+        /* run only if llvm-config isn't used */
+        if let Some(config) = builder.config.target_config.get(&target) {
+            if let Some(ref _s) = config.llvm_config {
+                builder.info(&format!("Skipping RustDev ({}): external LLVM", target));
+                return None;
+            }
+        }
+
+        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 exe = builder.llvm_out(target).join("bin").join(exe("llvm-config", target));
+        builder.install(&exe, &dst_bindir, 0o755);
+        builder.install(&builder.llvm_filecheck(target), &dst_bindir, 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"));
+
+        // 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)))
+    }
+}
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 2db4bb07a9f..ff846857446 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -20,8 +20,8 @@ pub struct Flags {
     pub stage: Option<u32>,
     pub keep_stage: Vec<u32>,
 
-    pub host: Vec<TargetSelection>,
-    pub target: Vec<TargetSelection>,
+    pub host: Option<Vec<TargetSelection>>,
+    pub target: Option<Vec<TargetSelection>>,
     pub config: Option<PathBuf>,
     pub jobs: Option<u32>,
     pub cmd: Subcommand,
@@ -526,14 +526,26 @@ Arguments:
                 .into_iter()
                 .map(|j| j.parse().expect("`keep-stage` should be a number"))
                 .collect(),
-            host: split(&matches.opt_strs("host"))
-                .into_iter()
-                .map(|x| TargetSelection::from_user(&x))
-                .collect::<Vec<_>>(),
-            target: split(&matches.opt_strs("target"))
-                .into_iter()
-                .map(|x| TargetSelection::from_user(&x))
-                .collect::<Vec<_>>(),
+            host: if matches.opt_present("host") {
+                Some(
+                    split(&matches.opt_strs("host"))
+                        .into_iter()
+                        .map(|x| TargetSelection::from_user(&x))
+                        .collect::<Vec<_>>(),
+                )
+            } else {
+                None
+            },
+            target: if matches.opt_present("target") {
+                Some(
+                    split(&matches.opt_strs("target"))
+                        .into_iter()
+                        .map(|x| TargetSelection::from_user(&x))
+                        .collect::<Vec<_>>(),
+                )
+            } else {
+                None
+            },
             config: cfg_file,
             jobs: matches.opt_str("jobs").map(|j| j.parse().expect("`jobs` should be a number")),
             cmd,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 54651214363..f0224d88226 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -103,8 +103,6 @@
 //! More documentation can be found in each respective module below, and you can
 //! also check out the `src/bootstrap/README.md` file for more information.
 
-#![feature(drain_filter)]
-
 use std::cell::{Cell, RefCell};
 use std::collections::{HashMap, HashSet};
 use std::env;
@@ -300,9 +298,6 @@ pub enum Mode {
     /// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
     Rustc,
 
-    /// Build codegen libraries, placing output in the "stageN-codegen" directory
-    Codegen,
-
     /// Build a tool, placing output in the "stage0-bootstrap-tools"
     /// directory. This is for miscellaneous sets of tools that are built
     /// using the bootstrap stage0 compiler in its entirety (target libraries
@@ -572,7 +567,6 @@ impl Build {
         let suffix = match mode {
             Mode::Std => "-std",
             Mode::Rustc => "-rustc",
-            Mode::Codegen => "-codegen",
             Mode::ToolBootstrap => "-bootstrap-tools",
             Mode::ToolStd | Mode::ToolRustc => "-tools",
         };
@@ -850,7 +844,7 @@ impl Build {
     }
 
     /// Returns the path to the linker for the given target if it needs to be overridden.
-    fn linker(&self, target: TargetSelection, can_use_lld: bool) -> Option<&Path> {
+    fn linker(&self, target: TargetSelection) -> Option<&Path> {
         if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
         {
             Some(linker)
@@ -863,13 +857,19 @@ impl Build {
             && !target.contains("msvc")
         {
             Some(self.cc(target))
-        } else if can_use_lld && self.config.use_lld && self.build == target {
+        } else if self.config.use_lld && !self.is_fuse_ld_lld(target) && self.build == target {
             Some(&self.initial_lld)
         } else {
             None
         }
     }
 
+    // LLD is used through `-fuse-ld=lld` rather than directly.
+    // Only MSVC targets use LLD directly at the moment.
+    fn is_fuse_ld_lld(&self, target: TargetSelection) -> bool {
+        self.config.use_lld && !target.contains("msvc")
+    }
+
     /// Returns if this target should statically link the C runtime, if specified
     fn crt_static(&self, target: TargetSelection) -> Option<bool> {
         if target.contains("pc-windows-msvc") {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index a0c79e38f9d..6cd850bc0bf 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -169,7 +169,6 @@ impl Step for Llvm {
             .define("LLVM_INCLUDE_TESTS", "OFF")
             .define("LLVM_INCLUDE_DOCS", "OFF")
             .define("LLVM_INCLUDE_BENCHMARKS", "OFF")
-            .define("WITH_POLLY", "OFF")
             .define("LLVM_ENABLE_TERMINFO", "OFF")
             .define("LLVM_ENABLE_LIBEDIT", "OFF")
             .define("LLVM_ENABLE_BINDINGS", "OFF")
@@ -305,10 +304,6 @@ impl Step for Llvm {
             cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES");
         }
 
-        if let Some(ref python) = builder.config.python {
-            cfg.define("PYTHON_EXECUTABLE", python);
-        }
-
         configure_cmake(builder, target, &mut cfg, true);
 
         // FIXME: we don't actually need to build all LLVM tools and all LLVM
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index a7c9b99f45f..045dda2d4cb 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -584,7 +584,7 @@ impl Step for RustdocTheme {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let compiler = run.builder.compiler(run.builder.top_stage, run.host);
+        let compiler = run.builder.compiler(run.builder.top_stage, run.target);
 
         run.builder.ensure(RustdocTheme { compiler });
     }
@@ -600,8 +600,11 @@ impl Step for RustdocTheme {
             .env("CFG_RELEASE_CHANNEL", &builder.config.channel)
             .env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
             .env("RUSTC_BOOTSTRAP", "1");
-        if let Some(linker) = builder.linker(self.compiler.host, true) {
-            cmd.env("RUSTC_TARGET_LINKER", linker);
+        if let Some(linker) = builder.linker(self.compiler.host) {
+            cmd.env("RUSTDOC_LINKER", linker);
+        }
+        if builder.is_fuse_ld_lld(self.compiler.host) {
+            cmd.env("RUSTDOC_FUSE_LD_LLD", "1");
         }
         try_run(builder, &mut cmd);
     }
@@ -648,7 +651,6 @@ impl Step for RustdocJSStd {
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct RustdocJSNotStd {
-    pub host: TargetSelection,
     pub target: TargetSelection,
     pub compiler: Compiler,
 }
@@ -663,8 +665,8 @@ impl Step for RustdocJSNotStd {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let compiler = run.builder.compiler(run.builder.top_stage, run.host);
-        run.builder.ensure(RustdocJSNotStd { host: run.host, target: run.target, compiler });
+        let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
+        run.builder.ensure(RustdocJSNotStd { target: run.target, compiler });
     }
 
     fn run(self, builder: &Builder<'_>) {
@@ -685,7 +687,6 @@ impl Step for RustdocJSNotStd {
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct RustdocUi {
-    pub host: TargetSelection,
     pub target: TargetSelection,
     pub compiler: Compiler,
 }
@@ -700,8 +701,8 @@ impl Step for RustdocUi {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let compiler = run.builder.compiler(run.builder.top_stage, run.host);
-        run.builder.ensure(RustdocUi { host: run.host, target: run.target, compiler });
+        let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
+        run.builder.ensure(RustdocUi { target: run.target, compiler });
     }
 
     fn run(self, builder: &Builder<'_>) {
@@ -870,7 +871,7 @@ macro_rules! test_definitions {
             }
 
             fn make_run(run: RunConfig<'_>) {
-                let compiler = run.builder.compiler(run.builder.top_stage, run.host);
+                let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
 
                 run.builder.ensure($name { compiler, target: run.target });
             }
@@ -1061,17 +1062,22 @@ impl Step for Compiletest {
         flags.push("-Zunstable-options".to_string());
         flags.push(builder.config.cmd.rustc_args().join(" "));
 
-        // Don't use LLD here since we want to test that rustc finds and uses a linker by itself.
-        if let Some(linker) = builder.linker(target, false) {
+        if let Some(linker) = builder.linker(target) {
             cmd.arg("--linker").arg(linker);
         }
 
         let mut hostflags = flags.clone();
         hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
+        if builder.is_fuse_ld_lld(compiler.host) {
+            hostflags.push("-Clink-args=-fuse-ld=lld".to_string());
+        }
         cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
 
         let mut targetflags = flags;
         targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
+        if builder.is_fuse_ld_lld(target) {
+            targetflags.push("-Clink-args=-fuse-ld=lld".to_string());
+        }
         cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
 
         cmd.arg("--docck-python").arg(builder.python());
@@ -1414,7 +1420,7 @@ macro_rules! test_book {
 
                 fn make_run(run: RunConfig<'_>) {
                     run.builder.ensure($name {
-                        compiler: run.builder.compiler(run.builder.top_stage, run.host),
+                        compiler: run.builder.compiler(run.builder.top_stage, run.target),
                     });
                 }
 
@@ -1461,7 +1467,7 @@ impl Step for ErrorIndex {
         // error_index_generator depends on librustdoc. Use the compiler that
         // is normally used to build rustdoc for other tests (like compiletest
         // tests in src/test/rustdoc) so that it shares the same artifacts.
-        let compiler = run.builder.compiler_for(run.builder.top_stage, run.host, run.host);
+        let compiler = run.builder.compiler_for(run.builder.top_stage, run.target, run.target);
         run.builder.ensure(ErrorIndex { compiler });
     }
 
@@ -1565,7 +1571,7 @@ impl Step for CrateLibrustc {
 
     fn make_run(run: RunConfig<'_>) {
         let builder = run.builder;
-        let compiler = builder.compiler(builder.top_stage, run.host);
+        let compiler = builder.compiler(builder.top_stage, run.build_triple());
 
         for krate in builder.in_tree_crates("rustc-main") {
             if krate.path.ends_with(&run.path) {
@@ -1612,7 +1618,7 @@ impl Step for CrateNotDefault {
 
     fn make_run(run: RunConfig<'_>) {
         let builder = run.builder;
-        let compiler = builder.compiler(builder.top_stage, run.host);
+        let compiler = builder.compiler(builder.top_stage, run.build_triple());
 
         let test_kind = builder.kind.into();
 
@@ -1660,7 +1666,7 @@ impl Step for Crate {
 
     fn make_run(run: RunConfig<'_>) {
         let builder = run.builder;
-        let compiler = builder.compiler(builder.top_stage, run.host);
+        let compiler = builder.compiler(builder.top_stage, run.build_triple());
 
         let make = |mode: Mode, krate: &CargoCrate| {
             let test_kind = builder.kind.into();
@@ -1800,7 +1806,7 @@ impl Step for CrateRustdoc {
 
         let test_kind = builder.kind.into();
 
-        builder.ensure(CrateRustdoc { host: run.host, test_kind });
+        builder.ensure(CrateRustdoc { host: run.target, test_kind });
     }
 
     fn run(self, builder: &Builder<'_>) {
@@ -2046,7 +2052,6 @@ impl Step for Bootstrap {
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct TierCheck {
     pub compiler: Compiler,
-    target: TargetSelection,
 }
 
 impl Step for TierCheck {
@@ -2059,18 +2064,19 @@ impl Step for TierCheck {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let compiler = run.builder.compiler_for(run.builder.top_stage, run.host, run.host);
-        run.builder.ensure(TierCheck { compiler, target: run.host });
+        let compiler =
+            run.builder.compiler_for(run.builder.top_stage, run.builder.build.build, run.target);
+        run.builder.ensure(TierCheck { compiler });
     }
 
     /// Tests the Platform Support page in the rustc book.
     fn run(self, builder: &Builder<'_>) {
-        builder.ensure(compile::Std { compiler: self.compiler, target: self.target });
+        builder.ensure(compile::Std { compiler: self.compiler, target: self.compiler.host });
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             self.compiler,
-            Mode::ToolRustc,
-            self.target,
+            Mode::ToolStd,
+            self.compiler.host,
             "run",
             "src/tools/tier-check",
             SourceType::InTree,
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index fe3f1e78029..a607f0fe258 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -162,13 +162,15 @@ impl Step for ToolBuild {
                 "the following dependencies are duplicated although they \
                       have the same features enabled:"
             );
-            for (id, cur, prev) in duplicates.drain_filter(|(_, cur, prev)| cur.2 == prev.2) {
+            let (same, different): (Vec<_>, Vec<_>) =
+                duplicates.into_iter().partition(|(_, cur, prev)| cur.2 == prev.2);
+            for (id, cur, prev) in same {
                 println!("  {}", id);
                 // same features
                 println!("    `{}` ({:?})\n    `{}` ({:?})", cur.0, cur.1, prev.0, prev.1);
             }
             println!("the following dependencies have different features:");
-            for (id, cur, prev) in duplicates {
+            for (id, cur, prev) in different {
                 println!("  {}", id);
                 let cur_features: HashSet<_> = cur.2.into_iter().collect();
                 let prev_features: HashSet<_> = prev.2.into_iter().collect();
@@ -467,8 +469,9 @@ impl Step for Rustdoc {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder
-            .ensure(Rustdoc { compiler: run.builder.compiler(run.builder.top_stage, run.host) });
+        run.builder.ensure(Rustdoc {
+            compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
+        });
     }
 
     fn run(self, builder: &Builder<'_>) -> PathBuf {
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 522d5bd3d9c..aef4374c542 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -523,7 +523,7 @@ jobs:
           - name: x86_64-mingw-1
             env:
               SCRIPT: make ci-mingw-subset-1
-              RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
+              RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-profiler
               CUSTOM_MINGW: 1
               # FIXME(#59637)
               NO_DEBUG_ASSERTIONS: 1
@@ -533,7 +533,7 @@ jobs:
           - name: x86_64-mingw-2
             env:
               SCRIPT: make ci-mingw-subset-2
-              RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
+              RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-profiler
               CUSTOM_MINGW: 1
             <<: *job-windows-xl
 
diff --git a/src/ci/scripts/symlink-build-dir.sh b/src/ci/scripts/symlink-build-dir.sh
index 28d8aa3b6e7..23849f7047c 100755
--- a/src/ci/scripts/symlink-build-dir.sh
+++ b/src/ci/scripts/symlink-build-dir.sh
@@ -12,22 +12,4 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 if isWindows && isAzurePipelines; then
     cmd //c "mkdir c:\\MORE_SPACE"
     cmd //c "mklink /J build c:\\MORE_SPACE"
-elif isLinux && isGitHubActions && ! isSelfHostedGitHubActions; then
-    sudo mkdir -p /mnt/more-space
-    sudo chown -R "$(whoami):" /mnt/more-space
-
-    # Switch the whole workspace to the /mnt partition, which has more space.
-    # We don't just symlink the `obj` directory as doing that creates problems
-    # with the docker container.
-    current_dir="$(readlink -f "$(pwd)")"
-    cd /tmp
-    mv "${current_dir}" /mnt/more-space/workspace
-    ln -s /mnt/more-space/workspace "${current_dir}"
-    cd "${current_dir}"
-
-    # Move the Docker data directory to /mnt
-    sudo systemctl stop docker.service
-    sudo mv /var/lib/docker /mnt/docker
-    sudo ln -s /mnt/docker /var/lib/docker
-    sudo systemctl start docker.service
 fi
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
index c0b14352b7d..18f1be6a1fa 100644
--- a/src/doc/rustc/src/linker-plugin-lto.md
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -89,6 +89,28 @@ rustc -Clinker-plugin-lto="/path/to/LLVMgold.so" -L. -Copt-level=2 ./main.rs
 
 ## Toolchain Compatibility
 
+<!-- NOTE: to update the below table, you can use this shell script:
+
+```sh
+rustup toolchain install --profile minimal nightly
+MINOR_VERSION=$(rustc +nightly --version | cut -d . -f 2)
+LOWER_BOUND=44
+
+llvm_version() {
+    toolchain="$1"
+    printf "Rust $toolchain    |    Clang "
+    rustc +"$toolchain" -Vv | grep LLVM | cut -d ':' -f 2 | tr -d ' '
+}
+
+for version in `seq $LOWER_BOUND $((MINOR_VERSION - 2))`; do
+    toolchain=1.$version.0
+    rustup toolchain install --no-self-update --profile  minimal $toolchain >/dev/null 2>&1
+    llvm_version $toolchain
+done
+```
+
+-->
+
 In order for this kind of LTO to work, the LLVM linker plugin must be able to
 handle the LLVM bitcode produced by both `rustc` and `clang`.
 
@@ -100,17 +122,20 @@ LLVM. However, the approximation is usually reliable.
 
 The following table shows known good combinations of toolchain versions.
 
-|           |  Clang 7  |  Clang 8  |  Clang 9  |
-|-----------|-----------|-----------|-----------|
-| Rust 1.34 |     ✗     |     ✓     |     ✗     |
-| Rust 1.35 |     ✗     |     ✓     |     ✗     |
-| Rust 1.36 |     ✗     |     ✓     |     ✗     |
-| Rust 1.37 |     ✗     |     ✓     |     ✗     |
-| Rust 1.38 |     ✗     |     ✗     |     ✓     |
-| Rust 1.39 |     ✗     |     ✗     |     ✓     |
-| Rust 1.40 |     ✗     |     ✗     |     ✓     |
-| Rust 1.41 |     ✗     |     ✗     |     ✓     |
-| Rust 1.42 |     ✗     |     ✗     |     ✓     |
-| Rust 1.43 |     ✗     |     ✗     |     ✓     |
+| Rust Version | Clang Version |
+|--------------|---------------|
+| Rust 1.34    |    Clang 8    |
+| Rust 1.35    |    Clang 8    |
+| Rust 1.36    |    Clang 8    |
+| Rust 1.37    |    Clang 8    |
+| Rust 1.38    |    Clang 9    |
+| Rust 1.39    |    Clang 9    |
+| Rust 1.40    |    Clang 9    |
+| Rust 1.41    |    Clang 9    |
+| Rust 1.42    |    Clang 9    |
+| Rust 1.43    |    Clang 9    |
+| Rust 1.44    |    Clang 9    |
+| Rust 1.45    |    Clang 10   |
+| Rust 1.46    |    Clang 10   |
 
 Note that the compatibility policy for this feature might change in the future.
diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md
index d3dfc3197e2..d2d8c471efc 100644
--- a/src/doc/rustc/src/lints/listing/allowed-by-default.md
+++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md
@@ -232,7 +232,8 @@ error: lifetime name `'x` only used once
 
 ## trivial-casts
 
-This lint detects trivial casts which could be removed. Some example code
+This lint detects trivial casts which could be replaced with coercion, which may require
+type ascription or a temporary variable. Some example code
 that triggers this lint:
 
 ```rust
diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md
index adcebc832bc..7a38c96d714 100644
--- a/src/doc/rustdoc/src/what-is-rustdoc.md
+++ b/src/doc/rustdoc/src/what-is-rustdoc.md
@@ -93,6 +93,29 @@ passes `-L`, a flag that helps rustdoc find the dependencies
 your code relies on. If our project used dependencies, we'd get
 documentation for them as well!
 
+## Outer and inner documentation
+
+The `///` syntax is used to document the item present after it.
+That's why it is called an outer documentation.
+There is another syntax: `//!`, which is used to document the 
+item it is present inside. It is called an inner documentation.
+It is often used when documenting the entire crate,
+because nothing comes before it: it is the root of the crate.
+So in order to document an entire crate, you need to use `//!` syntax.
+For example:
+
+``` rust
+//! This is my first rust crate
+```
+
+When used in the crate root, it documents the item it is inside,
+which is the crate itself.
+
+For more information about the `//!` syntax, see [the Book].
+
+[the Book]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#commenting-contained-items
+
+
 ## Using standalone Markdown files
 
 `rustdoc` can also generate HTML from standalone Markdown files. Let's
diff --git a/src/doc/unstable-book/src/language-features/ffi-const.md b/src/doc/unstable-book/src/language-features/ffi-const.md
index 9a1ced4033b..24a30443754 100644
--- a/src/doc/unstable-book/src/language-features/ffi-const.md
+++ b/src/doc/unstable-book/src/language-features/ffi-const.md
@@ -1,5 +1,9 @@
 # `ffi_const`
 
+The tracking issue for this feature is: [#58328]
+
+------
+
 The `#[ffi_const]` attribute applies clang's `const` attribute to foreign
 functions declarations.
 
@@ -42,6 +46,7 @@ implemented in this way on all of them. It is therefore also worth verifying
 that the semantics of the C toolchain used to compile the binary being linked
 against are compatible with those of the `#[ffi_const]`.
 
+[#58328]: https://github.com/rust-lang/rust/issues/58328
 [ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html
 [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
 [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm
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 7bfd7a378f0..4aef4eeab55 100644
--- a/src/doc/unstable-book/src/language-features/ffi-pure.md
+++ b/src/doc/unstable-book/src/language-features/ffi-pure.md
@@ -1,5 +1,9 @@
 # `ffi_pure`
 
+The tracking issue for this feature is: [#58329]
+
+------
+
 The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign
 functions declarations.
 
@@ -46,6 +50,7 @@ that the semantics of the C toolchain used to compile the binary being linked
 against are compatible with those of the `#[ffi_pure]`.
 
 
+[#58329]: https://github.com/rust-lang/rust/issues/58329
 [ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html
 [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
 [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm
diff --git a/src/doc/unstable-book/src/language-features/rustc-attrs.md b/src/doc/unstable-book/src/language-features/rustc-attrs.md
index 2967200faf8..1d9409ee9e4 100644
--- a/src/doc/unstable-book/src/language-features/rustc-attrs.md
+++ b/src/doc/unstable-book/src/language-features/rustc-attrs.md
@@ -13,8 +13,8 @@ The `rustc_attrs` feature allows debugging rustc type layouts by using
 with `cargo check`) as an alternative to `rustc -Z print-type-sizes`
 that is way more verbose.
 
-Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `abi`.
-Note that it only work best with sized type without generics.
+Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`,
+`abi`. Note that it only works on sized types without generics.
 
 ## Examples
 
diff --git a/src/doc/unstable-book/src/library-features/slice-check-range.md b/src/doc/unstable-book/src/library-features/slice-check-range.md
new file mode 100644
index 00000000000..83e5738cf54
--- /dev/null
+++ b/src/doc/unstable-book/src/library-features/slice-check-range.md
@@ -0,0 +1,10 @@
+# `slice_check_range`
+
+The tracking issue for this feature is: [#76393]
+
+------------------------
+
+This adds [`slice::check_range`].
+
+[#76393]: https://github.com/rust-lang/rust/issues/76393
+[`slice::check_range`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.check_range
diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py
index 2a46eaadad6..a5a1824c84e 100644
--- a/src/etc/gdb_lookup.py
+++ b/src/etc/gdb_lookup.py
@@ -69,9 +69,9 @@ def lookup(valobj):
         else:
             return StdOldHashMapProvider(valobj)
     if rust_type == RustType.STD_HASH_SET:
-        hash_map = valobj["map"]
+        hash_map = valobj[valobj.type.fields()[0]]
         if is_hashbrown_hashmap(hash_map):
-            return StdHashMapProvider(hash_map, show_values=False)
+            return StdHashMapProvider(valobj, show_values=False)
         else:
             return StdOldHashMapProvider(hash_map, show_values=False)
 
diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py
index 67f99ec4e40..bae51e6f9ee 100644
--- a/src/etc/gdb_providers.py
+++ b/src/etc/gdb_providers.py
@@ -347,7 +347,7 @@ class StdHashMapProvider:
         self.valobj = valobj
         self.show_values = show_values
 
-        table = self.valobj["base"]["table"]
+        table = self.table()
         capacity = int(table["bucket_mask"]) + 1
         ctrl = table["ctrl"]["pointer"]
 
@@ -368,6 +368,18 @@ class StdHashMapProvider:
             if is_presented:
                 self.valid_indices.append(idx)
 
+    def table(self):
+        if self.show_values:
+            hashbrown_hashmap = self.valobj["base"]
+        elif self.valobj.type.fields()[0].name == "map":
+            # BACKCOMPAT: rust 1.47
+            # HashSet wraps std::collections::HashMap, which wraps hashbrown::HashMap
+            hashbrown_hashmap = self.valobj["map"]["base"]
+        else:
+            # HashSet wraps hashbrown::HashSet, which wraps hashbrown::HashMap
+            hashbrown_hashmap = self.valobj["base"]["map"]
+        return hashbrown_hashmap["table"]
+
     def to_string(self):
         if self.show_values:
             return "HashMap(size={})".format(self.size)
diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py
index 13420fbaf0a..3cee51982ba 100644
--- a/src/etc/lldb_lookup.py
+++ b/src/etc/lldb_lookup.py
@@ -94,7 +94,7 @@ def synthetic_lookup(valobj, dict):
     if rust_type == RustType.STD_HASH_SET:
         hash_map = valobj.GetChildAtIndex(0)
         if is_hashbrown_hashmap(hash_map):
-            return StdHashMapSyntheticProvider(hash_map, dict, show_values=False)
+            return StdHashMapSyntheticProvider(valobj, dict, show_values=False)
         else:
             return StdOldHashMapSyntheticProvider(hash_map, dict, show_values=False)
 
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index 19da75c35b4..64cb9837943 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -526,7 +526,7 @@ class StdHashMapSyntheticProvider:
 
     def update(self):
         # type: () -> None
-        table = self.valobj.GetChildMemberWithName("base").GetChildMemberWithName("table")
+        table = self.table()
         capacity = table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1
         ctrl = table.GetChildMemberWithName("ctrl").GetChildAtIndex(0)
 
@@ -552,6 +552,17 @@ class StdHashMapSyntheticProvider:
             if is_present:
                 self.valid_indices.append(idx)
 
+    def table(self):
+        # type: () -> SBValue
+        if self.show_values:
+            hashbrown_hashmap = self.valobj.GetChildMemberWithName("base")
+        else:
+            # BACKCOMPAT: rust 1.47
+            # HashSet wraps either std HashMap or hashbrown::HashSet, which both
+            # wrap hashbrown::HashMap, so either way we "unwrap" twice.
+            hashbrown_hashmap = self.valobj.GetChildAtIndex(0).GetChildAtIndex(0)
+        return hashbrown_hashmap.GetChildMemberWithName("table")
+
     def has_children(self):
         # type: () -> bool
         return True
diff --git a/src/etc/natvis/libstd.natvis b/src/etc/natvis/libstd.natvis
index 4e81173d3d0..9550c25f2fc 100644
--- a/src/etc/natvis/libstd.natvis
+++ b/src/etc/natvis/libstd.natvis
@@ -5,7 +5,7 @@
 
     Current std impls:
       std::collections::hash::set::HashSet<K, S>      is implemented in terms of...
-      std::collections::hash::map::HashMap<K, V, S>   is implemented in terms of...
+      hashbrown::set::HashSet<K, S>                   is implemented in terms of...
       hashbrown::map::HashMap<K, V, S>                is implemented in terms of...
       hashbrown::raw::RawTable<(K, V)>
 
@@ -41,7 +41,7 @@
           <If Condition="(base.table.ctrl.pointer[i] &amp; 0x80) == 0">
             <!-- Bucket is populated -->
             <Exec>n--</Exec>
-            <Item Name="{static_cast&lt;tuple&lt;$T1, $T2&gt;*&gt;(base.table.ctrl.pointer)[-(i + 1)].__0}">static_cast&lt;tuple&lt;$T1, $T2&gt;*&gt;(base.table.ctrl.pointer)[-(i + 1)].__1</Item>
+            <Item Name="{((tuple&lt;$T1, $T2&gt;*)base.table.ctrl.pointer)[-(i + 1)].__0}">((tuple&lt;$T1, $T2&gt;*)base.table.ctrl.pointer)[-(i + 1)].__1</Item>
           </If>
           <Exec>i++</Exec>
         </Loop>
@@ -50,22 +50,22 @@
   </Type>
 
   <Type Name="std::collections::hash::set::HashSet&lt;*,*&gt;">
-    <DisplayString>{{ size={map.base.table.items} }}</DisplayString>
+    <DisplayString>{{ size={base.map.table.items} }}</DisplayString>
     <Expand>
-      <Item Name="[size]">map.base.table.items</Item>
-      <Item Name="[capacity]">map.base.table.items + map.base.table.growth_left</Item>
-      <Item Name="[state]">map.base.hash_builder</Item>
+      <Item Name="[size]">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>
 
       <CustomListItems>
         <Variable Name="i" InitialValue="0" />
-        <Variable Name="n" InitialValue="map.base.table.items" />
-        <Size>map.base.table.items</Size>
+        <Variable Name="n" InitialValue="base.map.table.items" />
+        <Size>base.map.table.items</Size>
         <Loop>
           <Break Condition="n == 0" />
-          <If Condition="(map.base.table.ctrl.pointer[i] &amp; 0x80) == 0">
+          <If Condition="(base.map.table.ctrl.pointer[i] &amp; 0x80) == 0">
             <!-- Bucket is populated -->
             <Exec>n--</Exec>
-            <Item>static_cast&lt;$T1*&gt;(map.base.table.ctrl.pointer)[-(i + 1)]</Item>
+            <Item>(($T1*)base.map.table.ctrl.pointer)[-(i + 1)]</Item>
           </If>
           <Exec>i++</Exec>
         </Loop>
diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml
deleted file mode 100644
index 7120f2e991a..00000000000
--- a/src/librustc_llvm/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_llvm"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-path = "lib.rs"
-
-[features]
-static-libstdcpp = []
-emscripten = []
-
-[dependencies]
-libc = "0.2.73"
-
-[build-dependencies]
-build_helper = { path = "../build_helper" }
-cc = "1.0.58"
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
deleted file mode 100644
index 306ffbf5daa..00000000000
--- a/src/librustc_llvm/build.rs
+++ /dev/null
@@ -1,322 +0,0 @@
-use std::env;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-
-use build_helper::{output, tracked_env_var_os};
-
-fn detect_llvm_link() -> (&'static str, &'static str) {
-    // Force the link mode we want, preferring static by default, but
-    // possibly overridden by `configure --enable-llvm-link-shared`.
-    if tracked_env_var_os("LLVM_LINK_SHARED").is_some() {
-        ("dylib", "--link-shared")
-    } else {
-        ("static", "--link-static")
-    }
-}
-
-fn main() {
-    if tracked_env_var_os("RUST_CHECK").is_some() {
-        // If we're just running `check`, there's no need for LLVM to be built.
-        return;
-    }
-
-    build_helper::restore_library_path();
-
-    let target = env::var("TARGET").expect("TARGET was not set");
-    let llvm_config =
-        tracked_env_var_os("LLVM_CONFIG").map(|x| Some(PathBuf::from(x))).unwrap_or_else(|| {
-            if let Some(dir) = tracked_env_var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
-                let to_test = dir
-                    .parent()
-                    .unwrap()
-                    .parent()
-                    .unwrap()
-                    .join(&target)
-                    .join("llvm/bin/llvm-config");
-                if Command::new(&to_test).output().is_ok() {
-                    return Some(to_test);
-                }
-            }
-            None
-        });
-
-    if let Some(llvm_config) = &llvm_config {
-        println!("cargo:rerun-if-changed={}", llvm_config.display());
-    }
-    let llvm_config = llvm_config.unwrap_or_else(|| PathBuf::from("llvm-config"));
-
-    // Test whether we're cross-compiling LLVM. This is a pretty rare case
-    // currently where we're producing an LLVM for a different platform than
-    // what this build script is currently running on.
-    //
-    // In that case, there's no guarantee that we can actually run the target,
-    // so the build system works around this by giving us the LLVM_CONFIG for
-    // the host platform. This only really works if the host LLVM and target
-    // LLVM are compiled the same way, but for us that's typically the case.
-    //
-    // We *want* detect this cross compiling situation by asking llvm-config
-    // what its host-target is. If that's not the TARGET, then we're cross
-    // compiling. Unfortunately `llvm-config` seems either be buggy, or we're
-    // misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will
-    // report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This
-    // tricks us into thinking we're doing a cross build when we aren't, so
-    // havoc ensues.
-    //
-    // In any case, if we're cross compiling, this generally just means that we
-    // can't trust all the output of llvm-config because it might be targeted
-    // for the host rather than the target. As a result a bunch of blocks below
-    // are gated on `if !is_crossed`
-    let target = env::var("TARGET").expect("TARGET was not set");
-    let host = env::var("HOST").expect("HOST was not set");
-    let is_crossed = target != host;
-
-    let mut optional_components = vec![
-        "x86",
-        "arm",
-        "aarch64",
-        "amdgpu",
-        "avr",
-        "mips",
-        "powerpc",
-        "systemz",
-        "jsbackend",
-        "webassembly",
-        "msp430",
-        "sparc",
-        "nvptx",
-        "hexagon",
-    ];
-
-    let mut version_cmd = Command::new(&llvm_config);
-    version_cmd.arg("--version");
-    let version_output = output(&mut version_cmd);
-    let mut parts = version_output.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
-    let (major, _minor) = if let (Some(major), Some(minor)) = (parts.next(), parts.next()) {
-        (major, minor)
-    } else {
-        (6, 0)
-    };
-
-    if major > 6 {
-        optional_components.push("riscv");
-    }
-
-    let required_components = &[
-        "ipo",
-        "bitreader",
-        "bitwriter",
-        "linker",
-        "asmparser",
-        "lto",
-        "coverage",
-        "instrumentation",
-    ];
-
-    let components = output(Command::new(&llvm_config).arg("--components"));
-    let mut components = components.split_whitespace().collect::<Vec<_>>();
-    components.retain(|c| optional_components.contains(c) || required_components.contains(c));
-
-    for component in required_components {
-        if !components.contains(component) {
-            panic!("require llvm component {} but wasn't found", component);
-        }
-    }
-
-    for component in components.iter() {
-        println!("cargo:rustc-cfg=llvm_component=\"{}\"", component);
-    }
-
-    if major >= 9 {
-        println!("cargo:rustc-cfg=llvm_has_msp430_asm_parser");
-    }
-
-    // Link in our own LLVM shims, compiled with the same flags as LLVM
-    let mut cmd = Command::new(&llvm_config);
-    cmd.arg("--cxxflags");
-    let cxxflags = output(&mut cmd);
-    let mut cfg = cc::Build::new();
-    cfg.warnings(false);
-    for flag in cxxflags.split_whitespace() {
-        // Ignore flags like `-m64` when we're doing a cross build
-        if is_crossed && flag.starts_with("-m") {
-            continue;
-        }
-
-        if flag.starts_with("-flto") {
-            continue;
-        }
-
-        // -Wdate-time is not supported by the netbsd cross compiler
-        if is_crossed && target.contains("netbsd") && flag.contains("date-time") {
-            continue;
-        }
-
-        // Include path contains host directory, replace it with target
-        if is_crossed && flag.starts_with("-I") {
-            cfg.flag(&flag.replace(&host, &target));
-            continue;
-        }
-
-        cfg.flag(flag);
-    }
-
-    for component in &components {
-        let mut flag = String::from("LLVM_COMPONENT_");
-        flag.push_str(&component.to_uppercase());
-        cfg.define(&flag, None);
-    }
-
-    if tracked_env_var_os("LLVM_RUSTLLVM").is_some() {
-        cfg.define("LLVM_RUSTLLVM", None);
-    }
-
-    if tracked_env_var_os("LLVM_NDEBUG").is_some() {
-        cfg.define("NDEBUG", None);
-        cfg.debug(false);
-    }
-
-    build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm"));
-    cfg.file("../rustllvm/PassWrapper.cpp")
-        .file("../rustllvm/RustWrapper.cpp")
-        .file("../rustllvm/ArchiveWrapper.cpp")
-        .file("../rustllvm/CoverageMappingWrapper.cpp")
-        .file("../rustllvm/Linker.cpp")
-        .cpp(true)
-        .cpp_link_stdlib(None) // we handle this below
-        .compile("rustllvm");
-
-    let (llvm_kind, llvm_link_arg) = detect_llvm_link();
-
-    // Link in all LLVM libraries, if we're using the "wrong" llvm-config then
-    // we don't pick up system libs because unfortunately they're for the host
-    // of llvm-config, not the target that we're attempting to link.
-    let mut cmd = Command::new(&llvm_config);
-    cmd.arg(llvm_link_arg).arg("--libs");
-
-    if !is_crossed {
-        cmd.arg("--system-libs");
-    } else if target.contains("windows-gnu") {
-        println!("cargo:rustc-link-lib=shell32");
-        println!("cargo:rustc-link-lib=uuid");
-    } else if target.contains("netbsd") || target.contains("haiku") {
-        println!("cargo:rustc-link-lib=z");
-    }
-    cmd.args(&components);
-
-    for lib in output(&mut cmd).split_whitespace() {
-        let name = if lib.starts_with("-l") {
-            &lib[2..]
-        } else if lib.starts_with('-') {
-            &lib[1..]
-        } else if Path::new(lib).exists() {
-            // On MSVC llvm-config will print the full name to libraries, but
-            // we're only interested in the name part
-            let name = Path::new(lib).file_name().unwrap().to_str().unwrap();
-            name.trim_end_matches(".lib")
-        } else if lib.ends_with(".lib") {
-            // Some MSVC libraries just come up with `.lib` tacked on, so chop
-            // that off
-            lib.trim_end_matches(".lib")
-        } else {
-            continue;
-        };
-
-        // Don't need or want this library, but LLVM's CMake build system
-        // doesn't provide a way to disable it, so filter it here even though we
-        // may or may not have built it. We don't reference anything from this
-        // library and it otherwise may just pull in extra dependencies on
-        // libedit which we don't want
-        if name == "LLVMLineEditor" {
-            continue;
-        }
-
-        let kind = if name.starts_with("LLVM") { llvm_kind } else { "dylib" };
-        println!("cargo:rustc-link-lib={}={}", kind, name);
-    }
-
-    // LLVM ldflags
-    //
-    // If we're a cross-compile of LLVM then unfortunately we can't trust these
-    // ldflags (largely where all the LLVM libs are located). Currently just
-    // hack around this by replacing the host triple with the target and pray
-    // that those -L directories are the same!
-    let mut cmd = Command::new(&llvm_config);
-    cmd.arg(llvm_link_arg).arg("--ldflags");
-    for lib in output(&mut cmd).split_whitespace() {
-        if is_crossed {
-            if lib.starts_with("-LIBPATH:") {
-                println!("cargo:rustc-link-search=native={}", lib[9..].replace(&host, &target));
-            } else if lib.starts_with("-L") {
-                println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target));
-            }
-        } else if lib.starts_with("-LIBPATH:") {
-            println!("cargo:rustc-link-search=native={}", &lib[9..]);
-        } else if lib.starts_with("-l") {
-            println!("cargo:rustc-link-lib={}", &lib[2..]);
-        } else if lib.starts_with("-L") {
-            println!("cargo:rustc-link-search=native={}", &lib[2..]);
-        }
-    }
-
-    // Some LLVM linker flags (-L and -l) may be needed even when linking
-    // librustc_llvm, for example when using static libc++, we may need to
-    // manually specify the library search path and -ldl -lpthread as link
-    // dependencies.
-    let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS");
-    if let Some(s) = llvm_linker_flags {
-        for lib in s.into_string().unwrap().split_whitespace() {
-            if lib.starts_with("-l") {
-                println!("cargo:rustc-link-lib={}", &lib[2..]);
-            } else if lib.starts_with("-L") {
-                println!("cargo:rustc-link-search=native={}", &lib[2..]);
-            }
-        }
-    }
-
-    let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP");
-    let llvm_use_libcxx = tracked_env_var_os("LLVM_USE_LIBCXX");
-
-    let stdcppname = if target.contains("openbsd") {
-        if target.contains("sparc64") { "estdc++" } else { "c++" }
-    } else if target.contains("freebsd") {
-        "c++"
-    } else if target.contains("darwin") {
-        "c++"
-    } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() {
-        // NetBSD uses a separate library when relocation is required
-        "stdc++_pic"
-    } else if llvm_use_libcxx.is_some() {
-        "c++"
-    } else {
-        "stdc++"
-    };
-
-    // RISC-V requires libatomic for sub-word atomic operations
-    if target.starts_with("riscv") {
-        println!("cargo:rustc-link-lib=atomic");
-    }
-
-    // C++ runtime library
-    if !target.contains("msvc") {
-        if let Some(s) = llvm_static_stdcpp {
-            assert!(!cxxflags.contains("stdlib=libc++"));
-            let path = PathBuf::from(s);
-            println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display());
-            if target.contains("windows") {
-                println!("cargo:rustc-link-lib=static-nobundle={}", stdcppname);
-            } else {
-                println!("cargo:rustc-link-lib=static={}", stdcppname);
-            }
-        } else if cxxflags.contains("stdlib=libc++") {
-            println!("cargo:rustc-link-lib=c++");
-        } else {
-            println!("cargo:rustc-link-lib={}", stdcppname);
-        }
-    }
-
-    // Libstdc++ depends on pthread which Rust doesn't link on MinGW
-    // since nothing else requires it.
-    if target.contains("windows-gnu") {
-        println!("cargo:rustc-link-lib=static-nobundle=pthread");
-    }
-}
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
deleted file mode 100644
index 9d23397ade0..00000000000
--- a/src/librustc_llvm/lib.rs
+++ /dev/null
@@ -1,173 +0,0 @@
-#![feature(nll)]
-#![feature(static_nobundle)]
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
-
-// NOTE: This crate only exists to allow linking on mingw targets.
-
-use libc::{c_char, size_t};
-use std::cell::RefCell;
-use std::slice;
-
-#[repr(C)]
-pub struct RustString {
-    pub bytes: RefCell<Vec<u8>>,
-}
-
-impl RustString {
-    pub fn len(&self) -> usize {
-        self.bytes.borrow().len()
-    }
-}
-
-/// Appending to a Rust string -- used by RawRustStringOstream.
-#[no_mangle]
-#[allow(improper_ctypes_definitions)]
-pub unsafe extern "C" fn LLVMRustStringWriteImpl(
-    sr: &RustString,
-    ptr: *const c_char,
-    size: size_t,
-) {
-    let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
-
-    sr.bytes.borrow_mut().extend_from_slice(slice);
-}
-
-/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`.
-/// N.B., this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
-pub fn initialize_available_targets() {
-    macro_rules! init_target(
-        ($cfg:meta, $($method:ident),*) => { {
-            #[cfg($cfg)]
-            fn init() {
-                extern {
-                    $(fn $method();)*
-                }
-                unsafe {
-                    $($method();)*
-                }
-            }
-            #[cfg(not($cfg))]
-            fn init() { }
-            init();
-        } }
-    );
-    init_target!(
-        llvm_component = "x86",
-        LLVMInitializeX86TargetInfo,
-        LLVMInitializeX86Target,
-        LLVMInitializeX86TargetMC,
-        LLVMInitializeX86AsmPrinter,
-        LLVMInitializeX86AsmParser
-    );
-    init_target!(
-        llvm_component = "arm",
-        LLVMInitializeARMTargetInfo,
-        LLVMInitializeARMTarget,
-        LLVMInitializeARMTargetMC,
-        LLVMInitializeARMAsmPrinter,
-        LLVMInitializeARMAsmParser
-    );
-    init_target!(
-        llvm_component = "aarch64",
-        LLVMInitializeAArch64TargetInfo,
-        LLVMInitializeAArch64Target,
-        LLVMInitializeAArch64TargetMC,
-        LLVMInitializeAArch64AsmPrinter,
-        LLVMInitializeAArch64AsmParser
-    );
-    init_target!(
-        llvm_component = "amdgpu",
-        LLVMInitializeAMDGPUTargetInfo,
-        LLVMInitializeAMDGPUTarget,
-        LLVMInitializeAMDGPUTargetMC,
-        LLVMInitializeAMDGPUAsmPrinter,
-        LLVMInitializeAMDGPUAsmParser
-    );
-    init_target!(
-        llvm_component = "avr",
-        LLVMInitializeAVRTargetInfo,
-        LLVMInitializeAVRTarget,
-        LLVMInitializeAVRTargetMC,
-        LLVMInitializeAVRAsmPrinter,
-        LLVMInitializeAVRAsmParser
-    );
-    init_target!(
-        llvm_component = "mips",
-        LLVMInitializeMipsTargetInfo,
-        LLVMInitializeMipsTarget,
-        LLVMInitializeMipsTargetMC,
-        LLVMInitializeMipsAsmPrinter,
-        LLVMInitializeMipsAsmParser
-    );
-    init_target!(
-        llvm_component = "powerpc",
-        LLVMInitializePowerPCTargetInfo,
-        LLVMInitializePowerPCTarget,
-        LLVMInitializePowerPCTargetMC,
-        LLVMInitializePowerPCAsmPrinter,
-        LLVMInitializePowerPCAsmParser
-    );
-    init_target!(
-        llvm_component = "systemz",
-        LLVMInitializeSystemZTargetInfo,
-        LLVMInitializeSystemZTarget,
-        LLVMInitializeSystemZTargetMC,
-        LLVMInitializeSystemZAsmPrinter,
-        LLVMInitializeSystemZAsmParser
-    );
-    init_target!(
-        llvm_component = "jsbackend",
-        LLVMInitializeJSBackendTargetInfo,
-        LLVMInitializeJSBackendTarget,
-        LLVMInitializeJSBackendTargetMC
-    );
-    init_target!(
-        llvm_component = "msp430",
-        LLVMInitializeMSP430TargetInfo,
-        LLVMInitializeMSP430Target,
-        LLVMInitializeMSP430TargetMC,
-        LLVMInitializeMSP430AsmPrinter
-    );
-    init_target!(
-        all(llvm_component = "msp430", llvm_has_msp430_asm_parser),
-        LLVMInitializeMSP430AsmParser
-    );
-    init_target!(
-        llvm_component = "riscv",
-        LLVMInitializeRISCVTargetInfo,
-        LLVMInitializeRISCVTarget,
-        LLVMInitializeRISCVTargetMC,
-        LLVMInitializeRISCVAsmPrinter,
-        LLVMInitializeRISCVAsmParser
-    );
-    init_target!(
-        llvm_component = "sparc",
-        LLVMInitializeSparcTargetInfo,
-        LLVMInitializeSparcTarget,
-        LLVMInitializeSparcTargetMC,
-        LLVMInitializeSparcAsmPrinter,
-        LLVMInitializeSparcAsmParser
-    );
-    init_target!(
-        llvm_component = "nvptx",
-        LLVMInitializeNVPTXTargetInfo,
-        LLVMInitializeNVPTXTarget,
-        LLVMInitializeNVPTXTargetMC,
-        LLVMInitializeNVPTXAsmPrinter
-    );
-    init_target!(
-        llvm_component = "hexagon",
-        LLVMInitializeHexagonTargetInfo,
-        LLVMInitializeHexagonTarget,
-        LLVMInitializeHexagonTargetMC,
-        LLVMInitializeHexagonAsmPrinter,
-        LLVMInitializeHexagonAsmParser
-    );
-    init_target!(
-        llvm_component = "webassembly",
-        LLVMInitializeWebAssemblyTargetInfo,
-        LLVMInitializeWebAssemblyTarget,
-        LLVMInitializeWebAssemblyTargetMC,
-        LLVMInitializeWebAssemblyAsmPrinter
-    );
-}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1bdbad46755..9d784d24609 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1364,16 +1364,16 @@ impl Clean<Type> for hir::Ty<'_> {
             TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
             TyKind::Array(ref ty, ref length) => {
                 let def_id = cx.tcx.hir().local_def_id(length.hir_id);
-                let length = match cx.tcx.const_eval_poly(def_id.to_def_id()) {
-                    Ok(length) => {
-                        print_const(cx, ty::Const::from_value(cx.tcx, length, cx.tcx.types.usize))
-                    }
-                    Err(_) => cx
-                        .sess()
-                        .source_map()
-                        .span_to_snippet(cx.tcx.def_span(def_id))
-                        .unwrap_or_else(|_| "_".to_string()),
-                };
+                // NOTE(min_const_generics): We can't use `const_eval_poly` for constants
+                // as we currently do not supply the parent generics to anonymous constants
+                // but do allow `ConstKind::Param`.
+                //
+                // `const_eval_poly` tries to to first substitute generic parameters which
+                // results in an ICE while manually constructing the constant and using `eval`
+                // does nothing for `ConstKind::Param`.
+                let ct = ty::Const::from_anon_const(cx.tcx, def_id);
+                let param_env = cx.tcx.param_env(def_id);
+                let length = print_const(cx, ct.eval(cx.tcx, param_env));
                 Array(box ty.clean(cx), length)
             }
             TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index a458cdab303..223fda84871 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -118,7 +118,7 @@ impl Item {
         self.attrs.collapsed_doc_value()
     }
 
-    pub fn links(&self) -> Vec<(String, String)> {
+    pub fn links(&self) -> Vec<RenderedLink> {
         self.attrs.links(&self.def_id.krate)
     }
 
@@ -425,10 +425,38 @@ pub struct Attributes {
     pub cfg: Option<Arc<Cfg>>,
     pub span: Option<rustc_span::Span>,
     /// map from Rust paths to resolved defs and potential URL fragments
-    pub links: Vec<(String, Option<DefId>, Option<String>)>,
+    pub links: Vec<ItemLink>,
     pub inner_docs: bool,
 }
 
+#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
+/// A link that has not yet been rendered.
+///
+/// This link will be turned into a rendered link by [`Attributes::links`]
+pub struct ItemLink {
+    /// The original link written in the markdown
+    pub(crate) link: String,
+    /// The link text displayed in the HTML.
+    ///
+    /// This may not be the same as `link` if there was a disambiguator
+    /// in an intra-doc link (e.g. \[`fn@f`\])
+    pub(crate) link_text: String,
+    pub(crate) did: Option<DefId>,
+    /// The url fragment to append to the link
+    pub(crate) fragment: Option<String>,
+}
+
+pub struct RenderedLink {
+    /// The text the link was original written as.
+    ///
+    /// This could potentially include disambiguators and backticks.
+    pub(crate) original_text: String,
+    /// The text to display in the HTML
+    pub(crate) new_text: String,
+    /// The URL to put in the `href`
+    pub(crate) href: String,
+}
+
 impl Attributes {
     /// Extracts the content from an attribute `#[doc(cfg(content))]`.
     pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
@@ -605,21 +633,25 @@ impl Attributes {
     /// Gets links as a vector
     ///
     /// Cache must be populated before call
-    pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> {
+    pub fn links(&self, krate: &CrateNum) -> Vec<RenderedLink> {
         use crate::html::format::href;
         use crate::html::render::CURRENT_DEPTH;
 
         self.links
             .iter()
-            .filter_map(|&(ref s, did, ref fragment)| {
-                match did {
+            .filter_map(|ItemLink { link: s, link_text, did, fragment }| {
+                match *did {
                     Some(did) => {
                         if let Some((mut href, ..)) = href(did) {
                             if let Some(ref fragment) = *fragment {
                                 href.push_str("#");
                                 href.push_str(fragment);
                             }
-                            Some((s.clone(), href))
+                            Some(RenderedLink {
+                                original_text: s.clone(),
+                                new_text: link_text.clone(),
+                                href,
+                            })
                         } else {
                             None
                         }
@@ -639,16 +671,17 @@ impl Attributes {
                             };
                             // This is a primitive so the url is done "by hand".
                             let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
-                            Some((
-                                s.clone(),
-                                format!(
+                            Some(RenderedLink {
+                                original_text: s.clone(),
+                                new_text: link_text.clone(),
+                                href: format!(
                                     "{}{}std/primitive.{}.html{}",
                                     url,
                                     if !url.ends_with('/') { "/" } else { "" },
                                     &fragment[..tail],
                                     &fragment[tail..]
                                 ),
-                            ))
+                            })
                         } else {
                             panic!("This isn't a primitive?!");
                         }
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 098ece9a1d5..a8c60e4a76d 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -34,6 +34,7 @@ use std::fmt::Write;
 use std::ops::Range;
 use std::str;
 
+use crate::clean::RenderedLink;
 use crate::doctest;
 use crate::html::highlight;
 use crate::html::toc::TocBuilder;
@@ -52,7 +53,7 @@ fn opts() -> Options {
 pub struct Markdown<'a>(
     pub &'a str,
     /// A list of link replacements.
-    pub &'a [(String, String)],
+    pub &'a [RenderedLink],
     /// The current list of used header IDs.
     pub &'a mut IdMap,
     /// Whether to allow the use of explicit error codes in doctest lang strings.
@@ -78,7 +79,7 @@ pub struct MarkdownHtml<'a>(
     pub &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders only the first paragraph.
-pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
+pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]);
 
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum ErrorCodes {
@@ -337,31 +338,107 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
 }
 
 /// Make headings links with anchor IDs and build up TOC.
-struct LinkReplacer<'a, 'b, I: Iterator<Item = Event<'a>>> {
+struct LinkReplacer<'a, I: Iterator<Item = Event<'a>>> {
     inner: I,
-    links: &'b [(String, String)],
+    links: &'a [RenderedLink],
+    shortcut_link: Option<&'a RenderedLink>,
 }
 
-impl<'a, 'b, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, 'b, I> {
-    fn new(iter: I, links: &'b [(String, String)]) -> Self {
-        LinkReplacer { inner: iter, links }
+impl<'a, I: Iterator<Item = Event<'a>>> LinkReplacer<'a, I> {
+    fn new(iter: I, links: &'a [RenderedLink]) -> Self {
+        LinkReplacer { inner: iter, links, shortcut_link: None }
     }
 }
 
-impl<'a, 'b, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, 'b, I> {
+impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
     type Item = Event<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        let event = self.inner.next();
-        if let Some(Event::Start(Tag::Link(kind, dest, text))) = event {
-            if let Some(&(_, ref replace)) = self.links.iter().find(|link| link.0 == *dest) {
-                Some(Event::Start(Tag::Link(kind, replace.to_owned().into(), text)))
-            } else {
-                Some(Event::Start(Tag::Link(kind, dest, text)))
+        use pulldown_cmark::LinkType;
+
+        let mut event = self.inner.next();
+
+        // Replace intra-doc links and remove disambiguators from shortcut links (`[fn@f]`).
+        match &mut event {
+            // This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
+            // Remove any disambiguator.
+            Some(Event::Start(Tag::Link(
+                // [fn@f] or [fn@f][]
+                LinkType::ShortcutUnknown | LinkType::CollapsedUnknown,
+                dest,
+                title,
+            ))) => {
+                debug!("saw start of shortcut link to {} with title {}", dest, title);
+                // If this is a shortcut link, it was resolved by the broken_link_callback.
+                // So the URL will already be updated properly.
+                let link = self.links.iter().find(|&link| *link.href == **dest);
+                // Since this is an external iterator, we can't replace the inner text just yet.
+                // Store that we saw a link so we know to replace it later.
+                if let Some(link) = link {
+                    trace!("it matched");
+                    assert!(self.shortcut_link.is_none(), "shortcut links cannot be nested");
+                    self.shortcut_link = Some(link);
+                }
             }
-        } else {
-            event
+            // Now that we're done with the shortcut link, don't replace any more text.
+            Some(Event::End(Tag::Link(
+                LinkType::ShortcutUnknown | LinkType::CollapsedUnknown,
+                dest,
+                _,
+            ))) => {
+                debug!("saw end of shortcut link to {}", dest);
+                if self.links.iter().find(|&link| *link.href == **dest).is_some() {
+                    assert!(self.shortcut_link.is_some(), "saw closing link without opening tag");
+                    self.shortcut_link = None;
+                }
+            }
+            // Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
+            // [`fn@f`]
+            Some(Event::Code(text)) => {
+                trace!("saw code {}", text);
+                if let Some(link) = self.shortcut_link {
+                    trace!("original text was {}", link.original_text);
+                    // NOTE: this only replaces if the code block is the *entire* text.
+                    // If only part of the link has code highlighting, the disambiguator will not be removed.
+                    // e.g. [fn@`f`]
+                    // This is a limitation from `collect_intra_doc_links`: it passes a full link,
+                    // and does not distinguish at all between code blocks.
+                    // So we could never be sure we weren't replacing too much:
+                    // [fn@my_`f`unc] is treated the same as [my_func()] in that pass.
+                    //
+                    // NOTE: &[1..len() - 1] is to strip the backticks
+                    if **text == link.original_text[1..link.original_text.len() - 1] {
+                        debug!("replacing {} with {}", text, link.new_text);
+                        *text = CowStr::Borrowed(&link.new_text);
+                    }
+                }
+            }
+            // Replace plain text in links, but only in the middle of a shortcut link.
+            // [fn@f]
+            Some(Event::Text(text)) => {
+                trace!("saw text {}", text);
+                if let Some(link) = self.shortcut_link {
+                    trace!("original text was {}", link.original_text);
+                    // NOTE: same limitations as `Event::Code`
+                    if **text == *link.original_text {
+                        debug!("replacing {} with {}", text, link.new_text);
+                        *text = CowStr::Borrowed(&link.new_text);
+                    }
+                }
+            }
+            // If this is a link, but not a shortcut link,
+            // replace the URL, since the broken_link_callback was not called.
+            Some(Event::Start(Tag::Link(_, dest, _))) => {
+                if let Some(link) = self.links.iter().find(|&link| *link.original_text == **dest) {
+                    *dest = CowStr::Borrowed(link.href.as_ref());
+                }
+            }
+            // Anything else couldn't have been a valid Rust path, so no need to replace the text.
+            _ => {}
         }
+
+        // Yield the modified event
+        event
     }
 }
 
@@ -855,8 +932,8 @@ impl Markdown<'_> {
             return String::new();
         }
         let replacer = |_: &str, s: &str| {
-            if let Some(&(_, ref replace)) = links.iter().find(|link| &*link.0 == s) {
-                Some((replace.clone(), s.to_owned()))
+            if let Some(link) = links.iter().find(|link| &*link.original_text == s) {
+                Some((link.href.clone(), link.new_text.clone()))
             } else {
                 None
             }
@@ -933,8 +1010,8 @@ impl MarkdownSummaryLine<'_> {
         }
 
         let replacer = |_: &str, s: &str| {
-            if let Some(&(_, ref replace)) = links.iter().find(|link| &*link.0 == s) {
-                Some((replace.clone(), s.to_owned()))
+            if let Some(link) = links.iter().find(|link| &*link.original_text == s) {
+                Some((link.href.clone(), link.new_text.clone()))
             } else {
                 None
             }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 57b3b9502a3..f095f67b54c 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -63,9 +63,8 @@ use rustc_span::symbol::{sym, Symbol};
 use serde::ser::SerializeSeq;
 use serde::{Serialize, Serializer};
 
-use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, TypeKind};
-use crate::config::RenderInfo;
-use crate::config::RenderOptions;
+use crate::clean::{self, AttributesExt, Deprecation, GetDefId, RenderedLink, SelfTy, TypeKind};
+use crate::config::{RenderInfo, RenderOptions};
 use crate::docfs::{DocFS, PathError};
 use crate::doctree;
 use crate::error::Error;
@@ -1774,7 +1773,7 @@ fn render_markdown(
     w: &mut Buffer,
     cx: &Context,
     md_text: &str,
-    links: Vec<(String, String)>,
+    links: Vec<RenderedLink>,
     prefix: &str,
     is_hidden: bool,
 ) {
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 55dcaec8ae1..935b96e51fc 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -126,6 +126,10 @@ h1, h2, h3, h4,
 	font-family: "Fira Sans", sans-serif;
 }
 
+.content ul.crate a.crate {
+	font: 16px/1.6 "Fira Sans";
+}
+
 ol, ul {
 	padding-left: 25px;
 }
diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css
index b4571018270..3b15b21889d 100644
--- a/src/librustdoc/html/static/themes/ayu.css
+++ b/src/librustdoc/html/static/themes/ayu.css
@@ -129,9 +129,10 @@ pre {
 	color: #ffb44c;
 }
 
-.line-numbers span { color: #5c6773ab; }
+.line-numbers span { color: #5c6773; }
 .line-numbers .line-highlighted {
-	background-color: rgba(255, 236, 164, 0.06) !important;
+	color: #708090;
+	background-color: rgba(255, 236, 164, 0.06);
 	padding-right: 4px;
 	border-right: 1px solid #ffb44c;
 }
@@ -178,9 +179,6 @@ pre {
 .content span.externcrate, .content span.mod, .content a.mod {
 	color: #acccf9;
 }
-.content ul.crate a.crate {
-	font: 16px/1.6 "Fira Sans";
-}
 .content span.struct, .content a.struct {
 	color: #ffa0a5;
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a4f5530815c..5780610c862 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -17,8 +17,9 @@ use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::Symbol;
 use rustc_span::DUMMY_SP;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 
+use std::borrow::Cow;
 use std::cell::Cell;
 use std::ops::Range;
 
@@ -46,19 +47,73 @@ pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
     }
 }
 
-enum ErrorKind {
-    ResolutionFailure,
+enum ErrorKind<'a> {
+    Resolve(Box<ResolutionFailure<'a>>),
     AnchorFailure(AnchorFailure),
 }
 
+impl<'a> From<ResolutionFailure<'a>> for ErrorKind<'a> {
+    fn from(err: ResolutionFailure<'a>) -> Self {
+        ErrorKind::Resolve(box err)
+    }
+}
+
+#[derive(Debug)]
+enum ResolutionFailure<'a> {
+    /// This resolved, but with the wrong namespace.
+    /// `Namespace` is the expected namespace (as opposed to the actual).
+    WrongNamespace(Res, Namespace),
+    /// This has a partial resolution, but is not in the TypeNS and so cannot
+    /// have associated items or fields.
+    CannotHaveAssociatedItems(Res, Namespace),
+    /// `name` is the base name of the path (not necessarily the whole link)
+    NotInScope { module_id: DefId, name: Cow<'a, str> },
+    /// this is a primitive type without an impls (no associated methods)
+    /// when will this actually happen?
+    /// the `Res` is the primitive it resolved to
+    NoPrimitiveImpl(Res, String),
+    /// `[u8::not_found]`
+    /// the `Res` is the primitive it resolved to
+    NoPrimitiveAssocItem { res: Res, prim_name: &'a str, assoc_item: Symbol },
+    /// `[S::not_found]`
+    /// the `String` is the associated item that wasn't found
+    NoAssocItem(Res, Symbol),
+    /// should not ever happen
+    NoParentItem,
+    /// this could be an enum variant, but the last path fragment wasn't resolved.
+    /// the `String` is the variant that didn't exist
+    NotAVariant(Res, Symbol),
+    /// used to communicate that this should be ignored, but shouldn't be reported to the user
+    Dummy,
+}
+
+impl ResolutionFailure<'a> {
+    // A partial or full resolution
+    fn res(&self) -> Option<Res> {
+        use ResolutionFailure::*;
+        match self {
+            NoPrimitiveAssocItem { res, .. }
+            | NoAssocItem(res, _)
+            | NoPrimitiveImpl(res, _)
+            | NotAVariant(res, _)
+            | WrongNamespace(res, _)
+            | CannotHaveAssociatedItems(res, _) => Some(*res),
+            NotInScope { .. } | NoParentItem | Dummy => None,
+        }
+    }
+
+    // This resolved fully (not just partially) but is erroneous for some other reason
+    fn full_res(&self) -> Option<Res> {
+        match self {
+            Self::WrongNamespace(res, _) => Some(*res),
+            _ => None,
+        }
+    }
+}
+
 enum AnchorFailure {
     MultipleAnchors,
-    Primitive,
-    Variant,
-    AssocConstant,
-    AssocType,
-    Field,
-    Method,
+    RustdocAnchorConflict(Res),
 }
 
 struct LinkCollector<'a, 'tcx> {
@@ -68,7 +123,7 @@ struct LinkCollector<'a, 'tcx> {
     /// This is used to store the kind of associated items,
     /// 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>>,
+    kind_side_channel: Cell<Option<(DefKind, DefId)>>,
 }
 
 impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
@@ -78,17 +133,25 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
 
     fn variant_field(
         &self,
-        path_str: &str,
+        path_str: &'path str,
         current_item: &Option<String>,
         module_id: DefId,
-    ) -> Result<(Res, Option<String>), ErrorKind> {
+        extra_fragment: &Option<String>,
+    ) -> Result<(Res, Option<String>), ErrorKind<'path>> {
         let cx = self.cx;
 
+        debug!("looking for enum variant {}", path_str);
         let mut split = path_str.rsplitn(3, "::");
-        let variant_field_name =
-            split.next().map(|f| Symbol::intern(f)).ok_or(ErrorKind::ResolutionFailure)?;
+        let variant_field_name = split
+            .next()
+            .map(|f| Symbol::intern(f))
+            .expect("fold_item should ensure link is non-empty");
         let variant_name =
-            split.next().map(|f| Symbol::intern(f)).ok_or(ErrorKind::ResolutionFailure)?;
+            // we're not sure this is a variant at all, so use the full string
+            split.next().map(|f| Symbol::intern(f)).ok_or_else(|| ResolutionFailure::NotInScope {
+                module_id,
+                name: path_str.into(),
+            })?;
         let path = split
             .next()
             .map(|f| {
@@ -99,14 +162,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 }
                 f.to_owned()
             })
-            .ok_or(ErrorKind::ResolutionFailure)?;
-        let (_, ty_res) = cx
+            .ok_or_else(|| ResolutionFailure::NotInScope {
+                module_id,
+                name: variant_name.to_string().into(),
+            })?;
+        let ty_res = cx
             .enter_resolver(|resolver| {
                 resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
             })
-            .map_err(|_| ErrorKind::ResolutionFailure)?;
+            .map(|(_, res)| res)
+            .unwrap_or(Res::Err);
         if let Res::Err = ty_res {
-            return Err(ErrorKind::ResolutionFailure);
+            return Err(ResolutionFailure::NotInScope { module_id, name: path.into() }.into());
         }
         let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
         match ty_res {
@@ -118,7 +185,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     .flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
                     .any(|item| item.ident.name == variant_name)
                 {
-                    return Err(ErrorKind::ResolutionFailure);
+                    // This is just to let `fold_item` know that this shouldn't be considered;
+                    // it's a bug for the error to make it to the user
+                    return Err(ResolutionFailure::Dummy.into());
                 }
                 match cx.tcx.type_of(did).kind() {
                     ty::Adt(def, _) if def.is_enum() => {
@@ -131,18 +200,43 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                                 )),
                             ))
                         } else {
-                            Err(ErrorKind::ResolutionFailure)
+                            Err(ResolutionFailure::NotAVariant(ty_res, variant_field_name).into())
                         }
                     }
-                    _ => Err(ErrorKind::ResolutionFailure),
+                    _ => unreachable!(),
                 }
             }
-            _ => Err(ErrorKind::ResolutionFailure),
+            // `variant_field` looks at 3 different path segments in a row.
+            // But `NoAssocItem` assumes there are only 2. Check to see if there's
+            // an intermediate segment that resolves.
+            _ => {
+                let intermediate_path = format!("{}::{}", path, variant_name);
+                // NOTE: we have to be careful here, because we're already in `resolve`.
+                // We know this doesn't recurse forever because we use a shorter path each time.
+                // NOTE: this uses `TypeNS` because nothing else has a valid path segment after
+                let kind = if let Some(intermediate) = self.check_full_res(
+                    TypeNS,
+                    &intermediate_path,
+                    Some(module_id),
+                    current_item,
+                    extra_fragment,
+                ) {
+                    ResolutionFailure::NoAssocItem(intermediate, variant_field_name)
+                } else {
+                    // Even with the shorter path, it didn't resolve, so say that.
+                    ResolutionFailure::NoAssocItem(ty_res, variant_name)
+                };
+                Err(kind.into())
+            }
         }
     }
 
     /// Resolves a string as a macro.
-    fn macro_resolve(&self, path_str: &str, parent_id: Option<DefId>) -> Option<Res> {
+    fn macro_resolve(
+        &self,
+        path_str: &'a str,
+        parent_id: Option<DefId>,
+    ) -> Result<Res, ResolutionFailure<'a>> {
         let cx = self.cx;
         let path = ast::Path::from_ident(Ident::from_str(path_str));
         cx.enter_resolver(|resolver| {
@@ -154,11 +248,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 false,
             ) {
                 if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
-                    return Some(res.map_id(|_| panic!("unexpected id")));
+                    return Some(Ok(res.map_id(|_| panic!("unexpected id"))));
                 }
             }
             if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
-                return Some(res.map_id(|_| panic!("unexpected id")));
+                return Some(Ok(res.map_id(|_| panic!("unexpected id"))));
             }
             if let Some(module_id) = parent_id {
                 debug!("resolving {} as a macro in the module {:?}", path_str, module_id);
@@ -168,25 +262,47 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     // don't resolve builtins like `#[derive]`
                     if let Res::Def(..) = res {
                         let res = res.map_id(|_| panic!("unexpected node_id"));
-                        return Some(res);
+                        return Some(Ok(res));
                     }
                 }
             } else {
                 debug!("attempting to resolve item without parent module: {}", path_str);
+                return Some(Err(ResolutionFailure::NoParentItem));
             }
             None
         })
+        // This weird control flow is so we don't borrow the resolver more than once at a time
+        .unwrap_or_else(|| {
+            let mut split = path_str.rsplitn(2, "::");
+            if let Some((parent, base)) = split.next().and_then(|x| Some((split.next()?, x))) {
+                if let Some(res) = self.check_full_res(TypeNS, parent, parent_id, &None, &None) {
+                    return Err(if matches!(res, Res::PrimTy(_)) {
+                        ResolutionFailure::NoPrimitiveAssocItem {
+                            res,
+                            prim_name: parent,
+                            assoc_item: Symbol::intern(base),
+                        }
+                    } else {
+                        ResolutionFailure::NoAssocItem(res, Symbol::intern(base))
+                    });
+                }
+            }
+            Err(ResolutionFailure::NotInScope {
+                module_id: parent_id.expect("already saw `Some` when resolving as a macro"),
+                name: path_str.into(),
+            })
+        })
     }
     /// Resolves a string as a path within a particular namespace. Also returns an optional
     /// URL fragment in the case of variants and methods.
-    fn resolve(
+    fn resolve<'path>(
         &self,
-        path_str: &str,
+        path_str: &'path str,
         ns: Namespace,
         current_item: &Option<String>,
         parent_id: Option<DefId>,
         extra_fragment: &Option<String>,
-    ) -> Result<(Res, Option<String>), ErrorKind> {
+    ) -> Result<(Res, Option<String>), ErrorKind<'path>> {
         let cx = self.cx;
 
         // In case we're in a module, try to resolve the relative path.
@@ -196,8 +312,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             });
             debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
             let result = match result {
-                Ok((_, Res::Err)) => Err(ErrorKind::ResolutionFailure),
-                _ => result.map_err(|_| ErrorKind::ResolutionFailure),
+                Ok((_, Res::Err)) => Err(()),
+                x => x,
             };
 
             if let Ok((_, res)) = result {
@@ -213,7 +329,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     // Not a trait item; just return what we found.
                     Res::PrimTy(..) => {
                         if extra_fragment.is_some() {
-                            return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
+                            return Err(ErrorKind::AnchorFailure(
+                                AnchorFailure::RustdocAnchorConflict(res),
+                            ));
                         }
                         return Ok((res, Some(path_str.to_owned())));
                     }
@@ -226,20 +344,22 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 };
 
                 if value != (ns == ValueNS) {
-                    return Err(ErrorKind::ResolutionFailure);
+                    return Err(ResolutionFailure::WrongNamespace(res, ns).into());
                 }
             } else if let Some((path, prim)) = is_primitive(path_str, ns) {
                 if extra_fragment.is_some() {
-                    return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
+                    return Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(
+                        prim,
+                    )));
                 }
                 return Ok((prim, Some(path.to_owned())));
             }
 
             // Try looking for methods and associated items.
             let mut split = path_str.rsplitn(2, "::");
-            let item_name =
-                split.next().map(|f| Symbol::intern(f)).ok_or(ErrorKind::ResolutionFailure)?;
-            let path = split
+            // this can be an `unwrap()` because we ensure the link is never empty
+            let item_name = Symbol::intern(split.next().unwrap());
+            let path_root = split
                 .next()
                 .map(|f| {
                     if f == "self" || f == "Self" {
@@ -249,10 +369,17 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     }
                     f.to_owned()
                 })
-                .ok_or(ErrorKind::ResolutionFailure)?;
-
-            if let Some((path, prim)) = is_primitive(&path, TypeNS) {
-                for &impl_ in primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)? {
+                // If there's no `::`, it's not an associated item.
+                // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
+                .ok_or_else(|| {
+                    debug!("found no `::`, assumming {} was correctly not in scope", item_name);
+                    ResolutionFailure::NotInScope { module_id, name: item_name.to_string().into() }
+                })?;
+
+            if let Some((path, prim)) = is_primitive(&path_root, TypeNS) {
+                let impls = primitive_impl(cx, &path)
+                    .ok_or_else(|| ResolutionFailure::NoPrimitiveImpl(prim, path_root.into()))?;
+                for &impl_ in impls {
                     let link = cx
                         .tcx
                         .associated_items(impl_)
@@ -272,21 +399,54 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         return Ok(link);
                     }
                 }
-                return Err(ErrorKind::ResolutionFailure);
+                debug!(
+                    "returning primitive error for {}::{} in {} namespace",
+                    path,
+                    item_name,
+                    ns.descr()
+                );
+                return Err(ResolutionFailure::NoPrimitiveAssocItem {
+                    res: prim,
+                    prim_name: path,
+                    assoc_item: item_name,
+                }
+                .into());
             }
 
-            let (_, ty_res) = cx
+            let ty_res = cx
                 .enter_resolver(|resolver| {
-                    resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
+                    // only types can have associated items
+                    resolver.resolve_str_path_error(DUMMY_SP, &path_root, TypeNS, module_id)
                 })
-                .map_err(|_| ErrorKind::ResolutionFailure)?;
-            if let Res::Err = ty_res {
-                return if ns == Namespace::ValueNS {
-                    self.variant_field(path_str, current_item, module_id)
-                } else {
-                    Err(ErrorKind::ResolutionFailure)
-                };
-            }
+                .map(|(_, res)| res);
+            let ty_res = match ty_res {
+                Err(()) | Ok(Res::Err) => {
+                    return if ns == Namespace::ValueNS {
+                        self.variant_field(path_str, current_item, module_id, extra_fragment)
+                    } else {
+                        // See if it only broke because of the namespace.
+                        let kind = cx.enter_resolver(|resolver| {
+                            // NOTE: this doesn't use `check_full_res` because we explicitly want to ignore `TypeNS` (we already checked it)
+                            for &ns in &[MacroNS, ValueNS] {
+                                match resolver
+                                    .resolve_str_path_error(DUMMY_SP, &path_root, ns, module_id)
+                                {
+                                    Ok((_, Res::Err)) | Err(()) => {}
+                                    Ok((_, res)) => {
+                                        let res = res.map_id(|_| panic!("unexpected node_id"));
+                                        return ResolutionFailure::CannotHaveAssociatedItems(
+                                            res, ns,
+                                        );
+                                    }
+                                }
+                            }
+                            ResolutionFailure::NotInScope { module_id, name: path_root.into() }
+                        });
+                        Err(kind.into())
+                    };
+                }
+                Ok(res) => res,
+            };
             let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
             let res = match ty_res {
                 Res::Def(
@@ -295,7 +455,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 ) => {
                     debug!("looking for associated item named {} for item {:?}", item_name, did);
                     // Checks if item_name belongs to `impl SomeItem`
-                    let kind = cx
+                    let assoc_item = cx
                         .tcx
                         .inherent_impls(did)
                         .iter()
@@ -307,7 +467,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                                 imp,
                             )
                         })
-                        .map(|item| item.kind)
+                        .map(|item| (item.kind, item.def_id))
                         // There should only ever be one associated item that matches from any inherent impl
                         .next()
                         // Check if item_name belongs to `impl SomeTrait for SomeItem`
@@ -323,26 +483,25 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                             kind
                         });
 
-                    if let Some(kind) = kind {
+                    if let Some((kind, id)) = assoc_item {
                         let out = match kind {
                             ty::AssocKind::Fn => "method",
                             ty::AssocKind::Const => "associatedconstant",
                             ty::AssocKind::Type => "associatedtype",
                         };
                         Some(if extra_fragment.is_some() {
-                            Err(ErrorKind::AnchorFailure(if kind == ty::AssocKind::Fn {
-                                AnchorFailure::Method
-                            } else {
-                                AnchorFailure::AssocConstant
-                            }))
+                            Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(
+                                ty_res,
+                            )))
                         } else {
                             // HACK(jynelson): `clean` expects the type, not the associated item.
                             // but the disambiguator logic expects the associated item.
                             // Store the kind in a side channel so that only the disambiguator logic looks at it.
-                            self.kind_side_channel.set(Some(kind.as_def_kind()));
+                            self.kind_side_channel.set(Some((kind.as_def_kind(), id)));
                             Ok((ty_res, Some(format!("{}.{}", out, item_name))))
                         })
                     } else if ns == Namespace::ValueNS {
+                        debug!("looking for variants or fields named {} for {:?}", item_name, did);
                         match cx.tcx.type_of(did).kind() {
                             ty::Adt(def, _) => {
                                 let field = if def.is_enum() {
@@ -355,11 +514,17 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                                 };
                                 field.map(|item| {
                                     if extra_fragment.is_some() {
-                                        Err(ErrorKind::AnchorFailure(if def.is_enum() {
-                                            AnchorFailure::Variant
-                                        } else {
-                                            AnchorFailure::Field
-                                        }))
+                                        let res = Res::Def(
+                                            if def.is_enum() {
+                                                DefKind::Variant
+                                            } else {
+                                                DefKind::Field
+                                            },
+                                            item.did,
+                                        );
+                                        Err(ErrorKind::AnchorFailure(
+                                            AnchorFailure::RustdocAnchorConflict(res),
+                                        ))
                                     } else {
                                         Ok((
                                             ty_res,
@@ -380,7 +545,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         }
                     } else {
                         // We already know this isn't in ValueNS, so no need to check variant_field
-                        return Err(ErrorKind::ResolutionFailure);
+                        return Err(ResolutionFailure::NoAssocItem(ty_res, item_name).into());
                     }
                 }
                 Res::Def(DefKind::Trait, did) => cx
@@ -401,13 +566,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         };
 
                         if extra_fragment.is_some() {
-                            Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Const {
-                                AnchorFailure::AssocConstant
-                            } else if item.kind == ty::AssocKind::Type {
-                                AnchorFailure::AssocType
-                            } else {
-                                AnchorFailure::Method
-                            }))
+                            Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(
+                                ty_res,
+                            )))
                         } else {
                             let res = Res::Def(item.kind.as_def_kind(), item.def_id);
                             Ok((res, Some(format!("{}.{}", kind, item_name))))
@@ -417,14 +578,54 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             };
             res.unwrap_or_else(|| {
                 if ns == Namespace::ValueNS {
-                    self.variant_field(path_str, current_item, module_id)
+                    self.variant_field(path_str, current_item, module_id, extra_fragment)
                 } else {
-                    Err(ErrorKind::ResolutionFailure)
+                    Err(ResolutionFailure::NoAssocItem(ty_res, item_name).into())
                 }
             })
         } else {
             debug!("attempting to resolve item without parent module: {}", path_str);
-            Err(ErrorKind::ResolutionFailure)
+            Err(ResolutionFailure::NoParentItem.into())
+        }
+    }
+
+    /// Used for reporting better errors.
+    ///
+    /// Returns whether the link resolved 'fully' in another namespace.
+    /// 'fully' here means that all parts of the link resolved, not just some path segments.
+    /// This returns the `Res` even if it was erroneous for some reason
+    /// (such as having invalid URL fragments or being in the wrong namespace).
+    fn check_full_res(
+        &self,
+        ns: Namespace,
+        path_str: &str,
+        base_node: Option<DefId>,
+        current_item: &Option<String>,
+        extra_fragment: &Option<String>,
+    ) -> Option<Res> {
+        let check_full_res_inner = |this: &Self, result: Result<Res, ErrorKind<'_>>| {
+            let res = match result {
+                Ok(res) => Some(res),
+                Err(ErrorKind::Resolve(box kind)) => kind.full_res(),
+                Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(res))) => {
+                    Some(res)
+                }
+                Err(ErrorKind::AnchorFailure(AnchorFailure::MultipleAnchors)) => None,
+            };
+            this.kind_side_channel.take().map(|(kind, id)| Res::Def(kind, id)).or(res)
+        };
+        // cannot be used for macro namespace
+        let check_full_res = |this: &Self, ns| {
+            let result = this.resolve(path_str, ns, current_item, base_node, extra_fragment);
+            check_full_res_inner(this, result.map(|(res, _)| res))
+        };
+        let check_full_res_macro = |this: &Self| {
+            let result = this.macro_resolve(path_str, base_node);
+            check_full_res_inner(this, result.map_err(ErrorKind::from))
+        };
+        match ns {
+            Namespace::MacroNS => check_full_res_macro(self),
+            Namespace::TypeNS | Namespace::ValueNS => check_full_res(self, ns),
         }
     }
 }
@@ -435,7 +636,7 @@ fn resolve_associated_trait_item(
     item_name: Symbol,
     ns: Namespace,
     cx: &DocContext<'_>,
-) -> Option<ty::AssocKind> {
+) -> Option<(ty::AssocKind, DefId)> {
     let ty = cx.tcx.type_of(did);
     // First consider automatic impls: `impl From<T> for T`
     let implicit_impls = crate::clean::get_auto_trait_and_blanket_impls(cx, ty, did);
@@ -463,7 +664,7 @@ fn resolve_associated_trait_item(
                             // 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((assoc.def_id, kind))
+                            Some((kind, assoc.def_id))
                         });
                         let assoc = items.next();
                         debug_assert_eq!(items.count(), 0);
@@ -485,7 +686,7 @@ fn resolve_associated_trait_item(
                                 ns,
                                 trait_,
                             )
-                            .map(|assoc| (assoc.def_id, assoc.kind))
+                            .map(|assoc| (assoc.kind, assoc.def_id))
                     }
                 }
                 _ => panic!("get_impls returned something that wasn't an impl"),
@@ -502,12 +703,12 @@ fn resolve_associated_trait_item(
             cx.tcx
                 .associated_items(trait_)
                 .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_)
-                .map(|assoc| (assoc.def_id, assoc.kind))
+                .map(|assoc| (assoc.kind, assoc.def_id))
         }));
     }
     // FIXME: warn about ambiguity
     debug!("the candidates were {:?}", candidates);
-    candidates.pop().map(|(_, kind)| kind)
+    candidates.pop()
 }
 
 /// Given a type, return all traits in scope in `module` implemented by that type.
@@ -536,7 +737,7 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx
             let trait_ref = cx.tcx.impl_trait_ref(impl_).expect("this is not an inherent impl");
             // Check if these are the same type.
             let impl_type = trait_ref.self_ty();
-            debug!(
+            trace!(
                 "comparing type {} with kind {:?} against type {:?}",
                 impl_type,
                 impl_type.kind(),
@@ -562,10 +763,10 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx
 /// Check for resolve collisions between a trait and its derive
 ///
 /// These are common and we should just resolve to the trait in that case
-fn is_derive_trait_collision<T>(ns: &PerNS<Option<(Res, T)>>) -> bool {
+fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_>>>) -> bool {
     if let PerNS {
-        type_ns: Some((Res::Def(DefKind::Trait, _), _)),
-        macro_ns: Some((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
+        type_ns: Ok((Res::Def(DefKind::Trait, _), _)),
+        macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
         ..
     } = *ns
     {
@@ -582,6 +783,9 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
         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.
@@ -593,6 +797,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                     }
                     current = parent;
                 } else {
+                    debug!(
+                        "{:?} has no parent (kind={:?}, original was {:?})",
+                        current,
+                        self.cx.tcx.def_kind(current),
+                        item.def_id
+                    );
                     break None;
                 }
             }
@@ -697,11 +907,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                     // This is an anchor to an element of the current page, nothing to do in here!
                     continue;
                 }
-                (parts[0].to_owned(), Some(parts[1].to_owned()))
+                (parts[0], Some(parts[1].to_owned()))
             } else {
-                (parts[0].to_owned(), None)
+                (parts[0], None)
             };
             let resolved_self;
+            let link_text;
             let mut path_str;
             let disambiguator;
             let (mut res, mut fragment) = {
@@ -718,6 +929,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                     continue;
                 }
 
+                // We stripped `()` and `!` when parsing the disambiguator.
+                // Add them back to be displayed, but not prefix disambiguators.
+                link_text = disambiguator
+                    .map(|d| d.display_for(path_str))
+                    .unwrap_or_else(|| path_str.to_owned());
+
                 // In order to correctly resolve intra-doc-links we need to
                 // pick a base AST node to work from.  If the documentation for
                 // this module came from an inner comment (//!) then we anchor
@@ -748,8 +965,32 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment)
                         {
                             Ok(res) => res,
-                            Err(ErrorKind::ResolutionFailure) => {
-                                resolution_failure(cx, &item, path_str, &dox, link_range);
+                            Err(ErrorKind::Resolve(box mut kind)) => {
+                                // We only looked in one namespace. Try to give a better error if possible.
+                                if kind.full_res().is_none() {
+                                    let other_ns = if ns == ValueNS { TypeNS } else { ValueNS };
+                                    for &new_ns in &[other_ns, MacroNS] {
+                                        if let Some(res) = self.check_full_res(
+                                            new_ns,
+                                            path_str,
+                                            base_node,
+                                            &current_item,
+                                            &extra_fragment,
+                                        ) {
+                                            kind = ResolutionFailure::WrongNamespace(res, ns);
+                                            break;
+                                        }
+                                    }
+                                }
+                                resolution_failure(
+                                    self,
+                                    &item,
+                                    path_str,
+                                    disambiguator,
+                                    &dox,
+                                    link_range,
+                                    smallvec![kind],
+                                );
                                 // This could just be a normal link or a broken link
                                 // we could potentially check if something is
                                 // "intra-doc-link-like" and warn in that case.
@@ -776,13 +1017,13 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                             ) {
                                 Ok(res) => {
                                     debug!("got res in TypeNS: {:?}", res);
-                                    Some(res)
+                                    Ok(res)
                                 }
                                 Err(ErrorKind::AnchorFailure(msg)) => {
                                     anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
                                     continue;
                                 }
-                                Err(ErrorKind::ResolutionFailure) => None,
+                                Err(ErrorKind::Resolve(box kind)) => Err(kind),
                             },
                             value_ns: match self.resolve(
                                 path_str,
@@ -791,48 +1032,57 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                                 base_node,
                                 &extra_fragment,
                             ) {
-                                Ok(res) => Some(res),
+                                Ok(res) => Ok(res),
                                 Err(ErrorKind::AnchorFailure(msg)) => {
                                     anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
                                     continue;
                                 }
-                                Err(ErrorKind::ResolutionFailure) => None,
+                                Err(ErrorKind::Resolve(box kind)) => Err(kind),
                             }
                             .and_then(|(res, fragment)| {
                                 // Constructors are picked up in the type namespace.
                                 match res {
-                                    Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => None,
+                                    Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => {
+                                        Err(ResolutionFailure::WrongNamespace(res, TypeNS))
+                                    }
                                     _ => match (fragment, extra_fragment) {
                                         (Some(fragment), Some(_)) => {
                                             // Shouldn't happen but who knows?
-                                            Some((res, Some(fragment)))
-                                        }
-                                        (fragment, None) | (None, fragment) => {
-                                            Some((res, fragment))
+                                            Ok((res, Some(fragment)))
                                         }
+                                        (fragment, None) | (None, fragment) => Ok((res, fragment)),
                                     },
                                 }
                             }),
                         };
 
-                        if candidates.is_empty() {
-                            resolution_failure(cx, &item, path_str, &dox, link_range);
+                        let len = candidates.iter().filter(|res| res.is_ok()).count();
+
+                        if len == 0 {
+                            resolution_failure(
+                                self,
+                                &item,
+                                path_str,
+                                disambiguator,
+                                &dox,
+                                link_range,
+                                candidates.into_iter().filter_map(|res| res.err()).collect(),
+                            );
                             // this could just be a normal link
                             continue;
                         }
 
-                        let len = candidates.clone().present_items().count();
-
                         if len == 1 {
-                            candidates.present_items().next().unwrap()
+                            candidates.into_iter().filter_map(|res| res.ok()).next().unwrap()
                         } else if len == 2 && is_derive_trait_collision(&candidates) {
                             candidates.type_ns.unwrap()
                         } else {
                             if is_derive_trait_collision(&candidates) {
-                                candidates.macro_ns = None;
+                                candidates.macro_ns = Err(ResolutionFailure::Dummy);
                             }
+                            // If we're reporting an ambiguity, don't mention the namespaces that failed
                             let candidates =
-                                candidates.map(|candidate| candidate.map(|(res, _)| res));
+                                candidates.map(|candidate| candidate.ok().map(|(res, _)| res));
                             ambiguity_error(
                                 cx,
                                 &item,
@@ -845,11 +1095,33 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         }
                     }
                     Some(MacroNS) => {
-                        if let Some(res) = self.macro_resolve(path_str, base_node) {
-                            (res, extra_fragment)
-                        } else {
-                            resolution_failure(cx, &item, path_str, &dox, link_range);
-                            continue;
+                        match self.macro_resolve(path_str, base_node) {
+                            Ok(res) => (res, extra_fragment),
+                            Err(mut kind) => {
+                                // `macro_resolve` 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,
+                                        &current_item,
+                                        &extra_fragment,
+                                    ) {
+                                        kind = ResolutionFailure::WrongNamespace(res, MacroNS);
+                                        break;
+                                    }
+                                }
+                                resolution_failure(
+                                    self,
+                                    &item,
+                                    path_str,
+                                    disambiguator,
+                                    &dox,
+                                    link_range,
+                                    smallvec![kind],
+                                );
+                                continue;
+                            }
                         }
                     }
                 }
@@ -873,7 +1145,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                                 path_str,
                                 &dox,
                                 link_range,
-                                AnchorFailure::Primitive,
+                                AnchorFailure::RustdocAnchorConflict(prim),
                             );
                             continue;
                         }
@@ -891,7 +1163,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
             let report_mismatch = |specified: Disambiguator, resolved: Disambiguator| {
                 // The resolved item did not match the disambiguator; give a better error than 'not found'
                 let msg = format!("incompatible link kind for `{}`", path_str);
-                report_diagnostic(cx, &msg, &item, &dox, link_range.clone(), |diag, sp| {
+                report_diagnostic(cx, &msg, &item, &dox, &link_range, |diag, sp| {
                     let note = format!(
                         "this link resolved to {} {}, which is not {} {}",
                         resolved.article(),
@@ -906,7 +1178,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
             if let Res::PrimTy(_) = res {
                 match disambiguator {
                     Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {
-                        item.attrs.links.push((ori_link, None, fragment))
+                        item.attrs.links.push(ItemLink {
+                            link: ori_link,
+                            link_text: path_str.to_owned(),
+                            did: None,
+                            fragment,
+                        });
                     }
                     Some(other) => {
                         report_mismatch(other, Disambiguator::Primitive);
@@ -919,7 +1196,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                 // Disallow e.g. linking to enums with `struct@`
                 if let Res::Def(kind, _) = res {
                     debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator);
-                    match (self.kind_side_channel.take().unwrap_or(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)))
                         // NOTE: this allows 'method' to mean both normal functions and associated functions
                         // This can't cause ambiguity because both are in the same namespace.
@@ -957,7 +1234,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                     }
                 }
                 let id = register_res(cx, res);
-                item.attrs.links.push((ori_link, Some(id), fragment));
+                item.attrs.links.push(ItemLink {
+                    link: ori_link,
+                    link_text,
+                    did: Some(id),
+                    fragment,
+                });
             }
         }
 
@@ -985,6 +1267,18 @@ enum Disambiguator {
 }
 
 impl Disambiguator {
+    /// The text that should be displayed when the path is rendered as HTML.
+    ///
+    /// NOTE: `path` is not the original link given by the user, but a name suitable for passing to `resolve`.
+    fn display_for(&self, path: &str) -> String {
+        match self {
+            // FIXME: this will have different output if the user had `m!()` originally.
+            Self::Kind(DefKind::Macro(MacroKind::Bang)) => format!("{}!", path),
+            Self::Kind(DefKind::Fn) => format!("{}()", path),
+            _ => path.to_owned(),
+        }
+    }
+
     /// (disambiguator, path_str)
     fn from_str(link: &str) -> Result<(Self, &str), ()> {
         use Disambiguator::{Kind, Namespace as NS, Primitive};
@@ -1036,21 +1330,16 @@ impl Disambiguator {
         }
     }
 
-    /// Return (description of the change, suggestion)
-    fn display_for(self, path_str: &str) -> (&'static str, String) {
-        const PREFIX: &str = "prefix with the item kind";
-        const FUNCTION: &str = "add parentheses";
-        const MACRO: &str = "add an exclamation mark";
-
+    fn suggestion(self) -> Suggestion {
         let kind = match self {
-            Disambiguator::Primitive => return (PREFIX, format!("prim@{}", path_str)),
+            Disambiguator::Primitive => return Suggestion::Prefix("prim"),
             Disambiguator::Kind(kind) => kind,
             Disambiguator::Namespace(_) => panic!("display_for cannot be used on namespaces"),
         };
         if kind == DefKind::Macro(MacroKind::Bang) {
-            return (MACRO, format!("{}!", path_str));
+            return Suggestion::Macro;
         } else if kind == DefKind::Fn || kind == DefKind::AssocFn {
-            return (FUNCTION, format!("{}()", path_str));
+            return Suggestion::Function;
         }
 
         let prefix = match kind {
@@ -1075,8 +1364,7 @@ impl Disambiguator {
             },
         };
 
-        // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
-        (PREFIX, format!("{}@{}", prefix, path_str))
+        Suggestion::Prefix(prefix)
     }
 
     fn ns(self) -> Namespace {
@@ -1108,6 +1396,31 @@ impl Disambiguator {
     }
 }
 
+enum Suggestion {
+    Prefix(&'static str),
+    Function,
+    Macro,
+}
+
+impl Suggestion {
+    fn descr(&self) -> Cow<'static, str> {
+        match self {
+            Self::Prefix(x) => format!("prefix with `{}@`", x).into(),
+            Self::Function => "add parentheses".into(),
+            Self::Macro => "add an exclamation mark".into(),
+        }
+    }
+
+    fn as_help(&self, path_str: &str) -> String {
+        // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
+        match self {
+            Self::Prefix(prefix) => format!("{}@{}", prefix, path_str),
+            Self::Function => format!("{}()", path_str),
+            Self::Macro => format!("{}!", path_str),
+        }
+    }
+}
+
 /// Reports a diagnostic for an intra-doc link.
 ///
 /// If no link range is provided, or the source span of the link cannot be determined, the span of
@@ -1123,7 +1436,7 @@ fn report_diagnostic(
     msg: &str,
     item: &Item,
     dox: &str,
-    link_range: Option<Range<usize>>,
+    link_range: &Option<Range<usize>>,
     decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
 ) {
     let hir_id = match cx.as_local_hir_id(item.def_id) {
@@ -1175,24 +1488,197 @@ fn report_diagnostic(
 }
 
 fn resolution_failure(
-    cx: &DocContext<'_>,
+    collector: &LinkCollector<'_, '_>,
     item: &Item,
     path_str: &str,
+    disambiguator: Option<Disambiguator>,
     dox: &str,
     link_range: Option<Range<usize>>,
+    kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
 ) {
     report_diagnostic(
-        cx,
+        collector.cx,
         &format!("unresolved link to `{}`", path_str),
         item,
         dox,
-        link_range,
+        &link_range,
         |diag, sp| {
-            if let Some(sp) = sp {
-                diag.span_label(sp, "unresolved link");
-            }
+            let in_scope = kinds.iter().any(|kind| kind.res().is_some());
+            let item = |res: Res| {
+                format!(
+                    "the {} `{}`",
+                    res.descr(),
+                    collector.cx.tcx.item_name(res.def_id()).to_string()
+                )
+            };
+            let assoc_item_not_allowed = |res: Res| {
+                let def_id = res.def_id();
+                let name = collector.cx.tcx.item_name(def_id);
+                format!(
+                    "`{}` is {} {}, not a module or type, and cannot have associated items",
+                    name,
+                    res.article(),
+                    res.descr()
+                )
+            };
+            // ignore duplicates
+            let mut variants_seen = SmallVec::<[_; 3]>::new();
+            for mut failure in kinds {
+                // Check if _any_ parent of the path gets resolved.
+                // If so, report it and say the first which failed; if not, say the first path segment didn't resolve.
+                if let ResolutionFailure::NotInScope { module_id, name } = &mut failure {
+                    let mut current = name.as_ref();
+                    loop {
+                        current = match current.rsplitn(2, "::").nth(1) {
+                            Some(p) => p,
+                            None => {
+                                *name = current.to_owned().into();
+                                break;
+                            }
+                        };
+                        if let Some(res) = collector.check_full_res(
+                            TypeNS,
+                            &current,
+                            Some(*module_id),
+                            &None,
+                            &None,
+                        ) {
+                            failure = ResolutionFailure::NoAssocItem(res, Symbol::intern(current));
+                            break;
+                        }
+                    }
+                }
+                let variant = std::mem::discriminant(&failure);
+                if variants_seen.contains(&variant) {
+                    continue;
+                }
+                variants_seen.push(variant);
+                let note = match failure {
+                    ResolutionFailure::NotInScope { module_id, name, .. } => {
+                        if in_scope {
+                            continue;
+                        }
+                        // NOTE: uses an explicit `continue` so the `note:` will come before the `help:`
+                        let module_name = collector.cx.tcx.item_name(module_id);
+                        let note = format!("no item named `{}` in `{}`", name, module_name);
+                        if let Some(span) = sp {
+                            diag.span_label(span, &note);
+                        } else {
+                            diag.note(&note);
+                        }
+                        // If the link has `::` in the path, assume it's meant to be an intra-doc link
+                        if !path_str.contains("::") {
+                            // Otherwise, the `[]` might be unrelated.
+                            // FIXME(https://github.com/raphlinus/pulldown-cmark/issues/373):
+                            // don't show this for autolinks (`<>`), `()` style links, or reference links
+                            diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#);
+                        }
+                        continue;
+                    }
+                    ResolutionFailure::Dummy => continue,
+                    ResolutionFailure::WrongNamespace(res, expected_ns) => {
+                        if let Res::Def(kind, _) = res {
+                            let disambiguator = Disambiguator::Kind(kind);
+                            suggest_disambiguator(
+                                disambiguator,
+                                diag,
+                                path_str,
+                                dox,
+                                sp,
+                                &link_range,
+                            )
+                        }
 
-            diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#);
+                        format!(
+                            "this link resolves to {}, which is not in the {} namespace",
+                            item(res),
+                            expected_ns.descr()
+                        )
+                    }
+                    ResolutionFailure::NoParentItem => {
+                        diag.level = rustc_errors::Level::Bug;
+                        "all intra doc links should have a parent item".to_owned()
+                    }
+                    ResolutionFailure::NoPrimitiveImpl(res, _) => format!(
+                        "this link partially resolves to {}, which does not have any associated items",
+                        item(res),
+                    ),
+                    ResolutionFailure::NoPrimitiveAssocItem { prim_name, assoc_item, .. } => {
+                        format!(
+                            "the builtin type `{}` does not have an associated item named `{}`",
+                            prim_name, assoc_item
+                        )
+                    }
+                    ResolutionFailure::NoAssocItem(res, assoc_item) => {
+                        use DefKind::*;
+
+                        let (kind, def_id) = match res {
+                            Res::Def(kind, def_id) => (kind, def_id),
+                            x => unreachable!(
+                                "primitives are covered above and other `Res` variants aren't possible at module scope: {:?}",
+                                x,
+                            ),
+                        };
+                        let name = collector.cx.tcx.item_name(def_id);
+                        let path_description = if let Some(disambiguator) = disambiguator {
+                            disambiguator.descr()
+                        } else {
+                            match kind {
+                                Mod | ForeignMod => "inner item",
+                                Struct => "field or associated item",
+                                Enum | Union => "variant or associated item",
+                                Variant
+                                | Field
+                                | Closure
+                                | Generator
+                                | AssocTy
+                                | AssocConst
+                                | AssocFn
+                                | Fn
+                                | Macro(_)
+                                | Const
+                                | ConstParam
+                                | ExternCrate
+                                | Use
+                                | LifetimeParam
+                                | Ctor(_, _)
+                                | AnonConst => {
+                                    let note = assoc_item_not_allowed(res);
+                                    if let Some(span) = sp {
+                                        diag.span_label(span, &note);
+                                    } else {
+                                        diag.note(&note);
+                                    }
+                                    return;
+                                }
+                                Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
+                                | Static => "associated item",
+                                Impl | GlobalAsm => unreachable!("not a path"),
+                            }
+                        };
+                        format!(
+                            "the {} `{}` has no {} named `{}`",
+                            res.descr(),
+                            name,
+                            path_description,
+                            assoc_item
+                        )
+                    }
+                    ResolutionFailure::CannotHaveAssociatedItems(res, _) => {
+                        assoc_item_not_allowed(res)
+                    }
+                    ResolutionFailure::NotAVariant(res, variant) => format!(
+                        "this link partially resolves to {}, but there is no variant named {}",
+                        item(res),
+                        variant
+                    ),
+                };
+                if let Some(span) = sp {
+                    diag.span_label(span, &note);
+                } else {
+                    diag.note(&note);
+                }
+            }
         },
     );
 }
@@ -1207,31 +1693,14 @@ fn anchor_failure(
 ) {
     let msg = match failure {
         AnchorFailure::MultipleAnchors => format!("`{}` contains multiple anchors", path_str),
-        AnchorFailure::Primitive
-        | AnchorFailure::Variant
-        | AnchorFailure::AssocConstant
-        | AnchorFailure::AssocType
-        | AnchorFailure::Field
-        | AnchorFailure::Method => {
-            let kind = match failure {
-                AnchorFailure::Primitive => "primitive type",
-                AnchorFailure::Variant => "enum variant",
-                AnchorFailure::AssocConstant => "associated constant",
-                AnchorFailure::AssocType => "associated type",
-                AnchorFailure::Field => "struct field",
-                AnchorFailure::Method => "method",
-                AnchorFailure::MultipleAnchors => unreachable!("should be handled already"),
-            };
-
-            format!(
-                "`{}` contains an anchor, but links to {kind}s are already anchored",
-                path_str,
-                kind = kind
-            )
-        }
+        AnchorFailure::RustdocAnchorConflict(res) => format!(
+            "`{}` contains an anchor, but links to {kind}s are already anchored",
+            path_str,
+            kind = res.descr(),
+        ),
     };
 
-    report_diagnostic(cx, &msg, item, dox, link_range, |diag, sp| {
+    report_diagnostic(cx, &msg, item, dox, &link_range, |diag, sp| {
         if let Some(sp) = sp {
             diag.span_label(sp, "contains invalid anchor");
         }
@@ -1270,7 +1739,7 @@ fn ambiguity_error(
         }
     }
 
-    report_diagnostic(cx, &msg, item, dox, link_range.clone(), |diag, sp| {
+    report_diagnostic(cx, &msg, item, dox, &link_range, |diag, sp| {
         if let Some(sp) = sp {
             diag.span_label(sp, "ambiguous link");
         } else {
@@ -1292,18 +1761,20 @@ fn suggest_disambiguator(
     sp: Option<rustc_span::Span>,
     link_range: &Option<Range<usize>>,
 ) {
-    let (action, mut suggestion) = disambiguator.display_for(path_str);
-    let help = format!("to link to the {}, {}", disambiguator.descr(), action);
+    let suggestion = disambiguator.suggestion();
+    let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
 
     if let Some(sp) = sp {
         let link_range = link_range.as_ref().expect("must have a link range if we have a span");
-        if dox.bytes().nth(link_range.start) == Some(b'`') {
-            suggestion = format!("`{}`", suggestion);
-        }
+        let msg = if dox.bytes().nth(link_range.start) == Some(b'`') {
+            format!("`{}`", suggestion.as_help(path_str))
+        } else {
+            suggestion.as_help(path_str)
+        };
 
-        diag.span_suggestion(sp, &help, suggestion, Applicability::MaybeIncorrect);
+        diag.span_suggestion(sp, &help, msg, Applicability::MaybeIncorrect);
     } else {
-        diag.help(&format!("{}: {}", help, suggestion));
+        diag.help(&format!("{}: {}", help, suggestion.as_help(path_str)));
     }
 }
 
@@ -1318,7 +1789,7 @@ fn privacy_error(
     let msg =
         format!("public documentation for `{}` links to private item `{}`", item_name, path_str);
 
-    report_diagnostic(cx, &msg, item, dox, link_range, |diag, sp| {
+    report_diagnostic(cx, &msg, item, dox, &link_range, |diag, sp| {
         if let Some(sp) = sp {
             diag.span_label(sp, "this item is private");
         }
@@ -1337,16 +1808,16 @@ fn handle_variant(
     cx: &DocContext<'_>,
     res: Res,
     extra_fragment: &Option<String>,
-) -> Result<(Res, Option<String>), ErrorKind> {
+) -> Result<(Res, Option<String>), ErrorKind<'static>> {
     use rustc_middle::ty::DefIdTree;
 
     if extra_fragment.is_some() {
-        return Err(ErrorKind::AnchorFailure(AnchorFailure::Variant));
+        return Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(res)));
     }
     let parent = if let Some(parent) = cx.tcx.parent(res.def_id()) {
         parent
     } else {
-        return Err(ErrorKind::ResolutionFailure);
+        return Err(ResolutionFailure::NoParentItem.into());
     };
     let parent_def = Res::Def(DefKind::Enum, parent);
     let variant = cx.tcx.expect_variant_res(res);
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 45790d79496be37fbce6ec57abad5af8fa7a34d
+Subproject 833dd1e3d4fd350c7c9f6fb2ce0c5f16af7a1e2
diff --git a/src/rustllvm/.editorconfig b/src/rustllvm/.editorconfig
deleted file mode 100644
index 865cd45f708..00000000000
--- a/src/rustllvm/.editorconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-[*.{h,cpp}]
-end_of_line = lf
-insert_final_newline = true
-charset = utf-8
-indent_style = space
-indent_size = 2
diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp
deleted file mode 100644
index 9ce614fda57..00000000000
--- a/src/rustllvm/ArchiveWrapper.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-#include "rustllvm.h"
-
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/ArchiveWriter.h"
-#include "llvm/Support/Path.h"
-
-using namespace llvm;
-using namespace llvm::object;
-
-struct RustArchiveMember {
-  const char *Filename;
-  const char *Name;
-  Archive::Child Child;
-
-  RustArchiveMember()
-      : Filename(nullptr), Name(nullptr),
-        Child(nullptr, nullptr, nullptr)
-  {
-  }
-  ~RustArchiveMember() {}
-};
-
-struct RustArchiveIterator {
-  bool First;
-  Archive::child_iterator Cur;
-  Archive::child_iterator End;
-  std::unique_ptr<Error> Err;
-
-  RustArchiveIterator(Archive::child_iterator Cur, Archive::child_iterator End,
-      std::unique_ptr<Error> Err)
-    : First(true),
-      Cur(Cur),
-      End(End),
-      Err(std::move(Err)) {}
-};
-
-enum class LLVMRustArchiveKind {
-  GNU,
-  BSD,
-  DARWIN,
-  COFF,
-};
-
-static Archive::Kind fromRust(LLVMRustArchiveKind Kind) {
-  switch (Kind) {
-  case LLVMRustArchiveKind::GNU:
-    return Archive::K_GNU;
-  case LLVMRustArchiveKind::BSD:
-    return Archive::K_BSD;
-  case LLVMRustArchiveKind::DARWIN:
-    return Archive::K_DARWIN;
-  case LLVMRustArchiveKind::COFF:
-    return Archive::K_COFF;
-  default:
-    report_fatal_error("Bad ArchiveKind.");
-  }
-}
-
-typedef OwningBinary<Archive> *LLVMRustArchiveRef;
-typedef RustArchiveMember *LLVMRustArchiveMemberRef;
-typedef Archive::Child *LLVMRustArchiveChildRef;
-typedef Archive::Child const *LLVMRustArchiveChildConstRef;
-typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
-
-extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
-      MemoryBuffer::getFile(Path, -1, false);
-  if (!BufOr) {
-    LLVMRustSetLastError(BufOr.getError().message().c_str());
-    return nullptr;
-  }
-
-  Expected<std::unique_ptr<Archive>> ArchiveOr =
-      Archive::create(BufOr.get()->getMemBufferRef());
-
-  if (!ArchiveOr) {
-    LLVMRustSetLastError(toString(ArchiveOr.takeError()).c_str());
-    return nullptr;
-  }
-
-  OwningBinary<Archive> *Ret = new OwningBinary<Archive>(
-      std::move(ArchiveOr.get()), std::move(BufOr.get()));
-
-  return Ret;
-}
-
-extern "C" void LLVMRustDestroyArchive(LLVMRustArchiveRef RustArchive) {
-  delete RustArchive;
-}
-
-extern "C" LLVMRustArchiveIteratorRef
-LLVMRustArchiveIteratorNew(LLVMRustArchiveRef RustArchive) {
-  Archive *Archive = RustArchive->getBinary();
-#if LLVM_VERSION_GE(10, 0)
-  std::unique_ptr<Error> Err = std::make_unique<Error>(Error::success());
-#else
-  std::unique_ptr<Error> Err = llvm::make_unique<Error>(Error::success());
-#endif
-  auto Cur = Archive->child_begin(*Err);
-  if (*Err) {
-    LLVMRustSetLastError(toString(std::move(*Err)).c_str());
-    return nullptr;
-  }
-  auto End = Archive->child_end();
-  return new RustArchiveIterator(Cur, End, std::move(Err));
-}
-
-extern "C" LLVMRustArchiveChildConstRef
-LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef RAI) {
-  if (RAI->Cur == RAI->End)
-    return nullptr;
-
-  // Advancing the iterator validates the next child, and this can
-  // uncover an error. LLVM requires that we check all Errors,
-  // so we only advance the iterator if we actually need to fetch
-  // the next child.
-  // This means we must not advance the iterator in the *first* call,
-  // but instead advance it *before* fetching the child in all later calls.
-  if (!RAI->First) {
-    ++RAI->Cur;
-    if (*RAI->Err) {
-      LLVMRustSetLastError(toString(std::move(*RAI->Err)).c_str());
-      return nullptr;
-    }
-  } else {
-    RAI->First = false;
-  }
-
-  if (RAI->Cur == RAI->End)
-    return nullptr;
-
-  const Archive::Child &Child = *RAI->Cur.operator->();
-  Archive::Child *Ret = new Archive::Child(Child);
-
-  return Ret;
-}
-
-extern "C" void LLVMRustArchiveChildFree(LLVMRustArchiveChildRef Child) {
-  delete Child;
-}
-
-extern "C" void LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef RAI) {
-  delete RAI;
-}
-
-extern "C" const char *
-LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
-  Expected<StringRef> NameOrErr = Child->getName();
-  if (!NameOrErr) {
-    // rustc_codegen_llvm currently doesn't use this error string, but it might be
-    // useful in the future, and in the mean time this tells LLVM that the
-    // error was not ignored and that it shouldn't abort the process.
-    LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str());
-    return nullptr;
-  }
-  StringRef Name = NameOrErr.get();
-  *Size = Name.size();
-  return Name.data();
-}
-
-extern "C" const char *LLVMRustArchiveChildData(LLVMRustArchiveChildRef Child,
-                                                size_t *Size) {
-  StringRef Buf;
-  Expected<StringRef> BufOrErr = Child->getBuffer();
-  if (!BufOrErr) {
-    LLVMRustSetLastError(toString(BufOrErr.takeError()).c_str());
-    return nullptr;
-  }
-  Buf = BufOrErr.get();
-  *Size = Buf.size();
-  return Buf.data();
-}
-
-extern "C" LLVMRustArchiveMemberRef
-LLVMRustArchiveMemberNew(char *Filename, char *Name,
-                         LLVMRustArchiveChildRef Child) {
-  RustArchiveMember *Member = new RustArchiveMember;
-  Member->Filename = Filename;
-  Member->Name = Name;
-  if (Child)
-    Member->Child = *Child;
-  return Member;
-}
-
-extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
-  delete Member;
-}
-
-extern "C" LLVMRustResult
-LLVMRustWriteArchive(char *Dst, size_t NumMembers,
-                     const LLVMRustArchiveMemberRef *NewMembers,
-                     bool WriteSymbtab, LLVMRustArchiveKind RustKind) {
-
-  std::vector<NewArchiveMember> Members;
-  auto Kind = fromRust(RustKind);
-
-  for (size_t I = 0; I < NumMembers; I++) {
-    auto Member = NewMembers[I];
-    assert(Member->Name);
-    if (Member->Filename) {
-      Expected<NewArchiveMember> MOrErr =
-          NewArchiveMember::getFile(Member->Filename, true);
-      if (!MOrErr) {
-        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
-        return LLVMRustResult::Failure;
-      }
-      MOrErr->MemberName = sys::path::filename(MOrErr->MemberName);
-      Members.push_back(std::move(*MOrErr));
-    } else {
-      Expected<NewArchiveMember> MOrErr =
-          NewArchiveMember::getOldMember(Member->Child, true);
-      if (!MOrErr) {
-        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
-        return LLVMRustResult::Failure;
-      }
-      Members.push_back(std::move(*MOrErr));
-    }
-  }
-
-  auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
-  if (!Result)
-    return LLVMRustResult::Success;
-  LLVMRustSetLastError(toString(std::move(Result)).c_str());
-
-  return LLVMRustResult::Failure;
-}
diff --git a/src/rustllvm/CoverageMappingWrapper.cpp b/src/rustllvm/CoverageMappingWrapper.cpp
deleted file mode 100644
index 81aba0cbf7d..00000000000
--- a/src/rustllvm/CoverageMappingWrapper.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "rustllvm.h"
-#include "llvm/ProfileData/Coverage/CoverageMapping.h"
-#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
-#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/LEB128.h"
-
-#include <iostream>
-
-using namespace llvm;
-
-extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
-    const char* const Filenames[],
-    size_t FilenamesLen,
-    RustStringRef BufferOut) {
-  // LLVM 11's CoverageFilenamesSectionWriter uses its new `Version4` format,
-  // so we're manually writing the `Version3` format ourselves.
-  RawRustStringOstream OS(BufferOut);
-  encodeULEB128(FilenamesLen, OS);
-  for (size_t i = 0; i < FilenamesLen; i++) {
-    StringRef Filename(Filenames[i]);
-    encodeULEB128(Filename.size(), OS);
-    OS << Filename;
-  }
-}
-
-extern "C" void LLVMRustCoverageWriteMappingToBuffer(
-    const unsigned *VirtualFileMappingIDs,
-    unsigned NumVirtualFileMappingIDs,
-    const coverage::CounterExpression *Expressions,
-    unsigned NumExpressions,
-    coverage::CounterMappingRegion *MappingRegions,
-    unsigned NumMappingRegions,
-    RustStringRef BufferOut) {
-  auto CoverageMappingWriter = coverage::CoverageMappingWriter(
-      makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
-      makeArrayRef(Expressions, NumExpressions),
-      makeMutableArrayRef(MappingRegions, NumMappingRegions));
-  RawRustStringOstream OS(BufferOut);
-  CoverageMappingWriter.write(OS);
-}
-
-extern "C" LLVMValueRef LLVMRustCoverageCreatePGOFuncNameVar(LLVMValueRef F, const char *FuncName) {
-  StringRef FuncNameRef(FuncName);
-  return wrap(createPGOFuncNameVar(*cast<Function>(unwrap(F)), FuncNameRef));
-}
-
-extern "C" uint64_t LLVMRustCoverageComputeHash(const char *Name) {
-  StringRef NameRef(Name);
-  return IndexedInstrProf::ComputeHash(NameRef);
-}
-
-extern "C" void LLVMRustCoverageWriteSectionNameToString(LLVMModuleRef M,
-                                                         RustStringRef Str) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
-  auto name = getInstrProfSectionName(IPSK_covmap,
-                                      TargetTriple.getObjectFormat());
-  RawRustStringOstream OS(Str);
-  OS << name;
-}
-
-extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
-  auto name = getCoverageMappingVarName();
-  RawRustStringOstream OS(Str);
-  OS << name;
-}
-
-extern "C" uint32_t LLVMRustCoverageMappingVersion() {
-  return coverage::CovMapVersion::Version3;
-}
diff --git a/src/rustllvm/Linker.cpp b/src/rustllvm/Linker.cpp
deleted file mode 100644
index 69176f9cb1f..00000000000
--- a/src/rustllvm/Linker.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "llvm/Linker/Linker.h"
-
-#include "rustllvm.h"
-
-using namespace llvm;
-
-struct RustLinker {
-  Linker L;
-  LLVMContext &Ctx;
-
-  RustLinker(Module &M) :
-    L(M),
-    Ctx(M.getContext())
-  {}
-};
-
-extern "C" RustLinker*
-LLVMRustLinkerNew(LLVMModuleRef DstRef) {
-  Module *Dst = unwrap(DstRef);
-
-  return new RustLinker(*Dst);
-}
-
-extern "C" void
-LLVMRustLinkerFree(RustLinker *L) {
-  delete L;
-}
-
-extern "C" bool
-LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) {
-  std::unique_ptr<MemoryBuffer> Buf =
-      MemoryBuffer::getMemBufferCopy(StringRef(BC, Len));
-
-  Expected<std::unique_ptr<Module>> SrcOrError =
-      llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), L->Ctx);
-  if (!SrcOrError) {
-    LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
-    return false;
-  }
-
-  auto Src = std::move(*SrcOrError);
-
-  if (L->L.linkInModule(std::move(Src))) {
-    LLVMRustSetLastError("");
-    return false;
-  }
-  return true;
-}
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
deleted file mode 100644
index 76fe5e7f769..00000000000
--- a/src/rustllvm/PassWrapper.cpp
+++ /dev/null
@@ -1,1655 +0,0 @@
-#include <stdio.h>
-
-#include <vector>
-#include <set>
-
-#include "rustllvm.h"
-
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/IR/AutoUpgrade.h"
-#include "llvm/IR/AssemblyAnnotationWriter.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/IRObjectFile.h"
-#include "llvm/Passes/PassBuilder.h"
-#if LLVM_VERSION_GE(9, 0)
-#include "llvm/Passes/StandardInstrumentations.h"
-#endif
-#include "llvm/Support/CBindingWrapping.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include "llvm/Transforms/IPO/AlwaysInliner.h"
-#include "llvm/Transforms/IPO/FunctionImport.h"
-#include "llvm/Transforms/Utils/FunctionImportUtils.h"
-#include "llvm/LTO/LTO.h"
-#include "llvm-c/Transforms/PassManagerBuilder.h"
-
-#include "llvm/Transforms/Instrumentation.h"
-#if LLVM_VERSION_GE(9, 0)
-#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
-#include "llvm/Support/TimeProfiler.h"
-#endif
-#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
-#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
-#if LLVM_VERSION_GE(9, 0)
-#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
-#endif
-#include "llvm/Transforms/Utils/NameAnonGlobals.h"
-
-using namespace llvm;
-
-typedef struct LLVMOpaquePass *LLVMPassRef;
-typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
-
-DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
-DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
-#if LLVM_VERSION_LT(11, 0)
-DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
-                                   LLVMPassManagerBuilderRef)
-#endif
-
-extern "C" void LLVMInitializePasses() {
-  PassRegistry &Registry = *PassRegistry::getPassRegistry();
-  initializeCore(Registry);
-  initializeCodeGen(Registry);
-  initializeScalarOpts(Registry);
-  initializeVectorization(Registry);
-  initializeIPO(Registry);
-  initializeAnalysis(Registry);
-  initializeTransformUtils(Registry);
-  initializeInstCombine(Registry);
-  initializeInstrumentation(Registry);
-  initializeTarget(Registry);
-}
-
-extern "C" void LLVMTimeTraceProfilerInitialize() {
-#if LLVM_VERSION_GE(10, 0)
-  timeTraceProfilerInitialize(
-      /* TimeTraceGranularity */ 0,
-      /* ProcName */ "rustc");
-#elif LLVM_VERSION_GE(9, 0)
-  timeTraceProfilerInitialize();
-#endif
-}
-
-extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
-#if LLVM_VERSION_GE(9, 0)
-  StringRef FN(FileName);
-  std::error_code EC;
-  raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
-
-  timeTraceProfilerWrite(OS);
-  timeTraceProfilerCleanup();
-#endif
-}
-
-enum class LLVMRustPassKind {
-  Other,
-  Function,
-  Module,
-};
-
-static LLVMRustPassKind toRust(PassKind Kind) {
-  switch (Kind) {
-  case PT_Function:
-    return LLVMRustPassKind::Function;
-  case PT_Module:
-    return LLVMRustPassKind::Module;
-  default:
-    return LLVMRustPassKind::Other;
-  }
-}
-
-extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
-  StringRef SR(PassName);
-  PassRegistry *PR = PassRegistry::getPassRegistry();
-
-  const PassInfo *PI = PR->getPassInfo(SR);
-  if (PI) {
-    return wrap(PI->createPass());
-  }
-  return nullptr;
-}
-
-extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
-  const bool CompileKernel = false;
-  const bool UseAfterScope = true;
-
-  return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope));
-}
-
-extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
-  const bool CompileKernel = false;
-
-#if LLVM_VERSION_GE(9, 0)
-  return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
-#else
-  return wrap(createAddressSanitizerModulePass(CompileKernel, Recover));
-#endif
-}
-
-extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
-#if LLVM_VERSION_GE(9, 0)
-  const bool CompileKernel = false;
-
-  return wrap(createMemorySanitizerLegacyPassPass(
-      MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
-#else
-  return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover));
-#endif
-}
-
-extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
-  return wrap(createThreadSanitizerLegacyPassPass());
-}
-
-extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
-  assert(RustPass);
-  Pass *Pass = unwrap(RustPass);
-  return toRust(Pass->getPassKind());
-}
-
-extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
-  assert(RustPass);
-  Pass *Pass = unwrap(RustPass);
-  PassManagerBase *PMB = unwrap(PMR);
-  PMB->add(Pass);
-}
-
-extern "C"
-void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
-  LLVMPassManagerBuilderRef PMBR,
-  LLVMPassManagerRef PMR
-) {
-  unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
-}
-
-extern "C"
-void LLVMRustAddLastExtensionPasses(
-    LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) {
-  auto AddExtensionPasses = [Passes, NumPasses](
-      const PassManagerBuilder &Builder, PassManagerBase &PM) {
-    for (size_t I = 0; I < NumPasses; I++) {
-      PM.add(unwrap(Passes[I]));
-    }
-  };
-  // Add the passes to both of the pre-finalization extension points,
-  // so they are run for optimized and non-optimized builds.
-  unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast,
-                             AddExtensionPasses);
-  unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
-                             AddExtensionPasses);
-}
-
-#ifdef LLVM_COMPONENT_X86
-#define SUBTARGET_X86 SUBTARGET(X86)
-#else
-#define SUBTARGET_X86
-#endif
-
-#ifdef LLVM_COMPONENT_ARM
-#define SUBTARGET_ARM SUBTARGET(ARM)
-#else
-#define SUBTARGET_ARM
-#endif
-
-#ifdef LLVM_COMPONENT_AARCH64
-#define SUBTARGET_AARCH64 SUBTARGET(AArch64)
-#else
-#define SUBTARGET_AARCH64
-#endif
-
-#ifdef LLVM_COMPONENT_AVR
-#define SUBTARGET_AVR SUBTARGET(AVR)
-#else
-#define SUBTARGET_AVR
-#endif
-
-#ifdef LLVM_COMPONENT_MIPS
-#define SUBTARGET_MIPS SUBTARGET(Mips)
-#else
-#define SUBTARGET_MIPS
-#endif
-
-#ifdef LLVM_COMPONENT_POWERPC
-#define SUBTARGET_PPC SUBTARGET(PPC)
-#else
-#define SUBTARGET_PPC
-#endif
-
-#ifdef LLVM_COMPONENT_SYSTEMZ
-#define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
-#else
-#define SUBTARGET_SYSTEMZ
-#endif
-
-#ifdef LLVM_COMPONENT_MSP430
-#define SUBTARGET_MSP430 SUBTARGET(MSP430)
-#else
-#define SUBTARGET_MSP430
-#endif
-
-#ifdef LLVM_COMPONENT_RISCV
-#define SUBTARGET_RISCV SUBTARGET(RISCV)
-#else
-#define SUBTARGET_RISCV
-#endif
-
-#ifdef LLVM_COMPONENT_SPARC
-#define SUBTARGET_SPARC SUBTARGET(Sparc)
-#else
-#define SUBTARGET_SPARC
-#endif
-
-#ifdef LLVM_COMPONENT_HEXAGON
-#define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
-#else
-#define SUBTARGET_HEXAGON
-#endif
-
-#define GEN_SUBTARGETS                                                         \
-  SUBTARGET_X86                                                                \
-  SUBTARGET_ARM                                                                \
-  SUBTARGET_AARCH64                                                            \
-  SUBTARGET_AVR                                                                \
-  SUBTARGET_MIPS                                                               \
-  SUBTARGET_PPC                                                                \
-  SUBTARGET_SYSTEMZ                                                            \
-  SUBTARGET_MSP430                                                             \
-  SUBTARGET_SPARC                                                              \
-  SUBTARGET_HEXAGON                                                            \
-  SUBTARGET_RISCV                                                              \
-
-#define SUBTARGET(x)                                                           \
-  namespace llvm {                                                             \
-  extern const SubtargetFeatureKV x##FeatureKV[];                              \
-  extern const SubtargetFeatureKV x##SubTypeKV[];                              \
-  }
-
-GEN_SUBTARGETS
-#undef SUBTARGET
-
-extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
-                                   const char *Feature) {
-  TargetMachine *Target = unwrap(TM);
-  const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
-  return MCInfo->checkFeatures(std::string("+") + Feature);
-}
-
-enum class LLVMRustCodeModel {
-  Tiny,
-  Small,
-  Kernel,
-  Medium,
-  Large,
-  None,
-};
-
-static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
-  switch (Model) {
-  case LLVMRustCodeModel::Tiny:
-    return CodeModel::Tiny;
-  case LLVMRustCodeModel::Small:
-    return CodeModel::Small;
-  case LLVMRustCodeModel::Kernel:
-    return CodeModel::Kernel;
-  case LLVMRustCodeModel::Medium:
-    return CodeModel::Medium;
-  case LLVMRustCodeModel::Large:
-    return CodeModel::Large;
-  case LLVMRustCodeModel::None:
-    return None;
-  default:
-    report_fatal_error("Bad CodeModel.");
-  }
-}
-
-enum class LLVMRustCodeGenOptLevel {
-  None,
-  Less,
-  Default,
-  Aggressive,
-};
-
-static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
-  switch (Level) {
-  case LLVMRustCodeGenOptLevel::None:
-    return CodeGenOpt::None;
-  case LLVMRustCodeGenOptLevel::Less:
-    return CodeGenOpt::Less;
-  case LLVMRustCodeGenOptLevel::Default:
-    return CodeGenOpt::Default;
-  case LLVMRustCodeGenOptLevel::Aggressive:
-    return CodeGenOpt::Aggressive;
-  default:
-    report_fatal_error("Bad CodeGenOptLevel.");
-  }
-}
-
-enum class LLVMRustPassBuilderOptLevel {
-  O0,
-  O1,
-  O2,
-  O3,
-  Os,
-  Oz,
-};
-
-static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
-  switch (Level) {
-  case LLVMRustPassBuilderOptLevel::O0:
-    return PassBuilder::OptimizationLevel::O0;
-  case LLVMRustPassBuilderOptLevel::O1:
-    return PassBuilder::OptimizationLevel::O1;
-  case LLVMRustPassBuilderOptLevel::O2:
-    return PassBuilder::OptimizationLevel::O2;
-  case LLVMRustPassBuilderOptLevel::O3:
-    return PassBuilder::OptimizationLevel::O3;
-  case LLVMRustPassBuilderOptLevel::Os:
-    return PassBuilder::OptimizationLevel::Os;
-  case LLVMRustPassBuilderOptLevel::Oz:
-    return PassBuilder::OptimizationLevel::Oz;
-  default:
-    report_fatal_error("Bad PassBuilderOptLevel.");
-  }
-}
-
-enum class LLVMRustRelocModel {
-  Static,
-  PIC,
-  DynamicNoPic,
-  ROPI,
-  RWPI,
-  ROPIRWPI,
-};
-
-static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
-  switch (RustReloc) {
-  case LLVMRustRelocModel::Static:
-    return Reloc::Static;
-  case LLVMRustRelocModel::PIC:
-    return Reloc::PIC_;
-  case LLVMRustRelocModel::DynamicNoPic:
-    return Reloc::DynamicNoPIC;
-  case LLVMRustRelocModel::ROPI:
-    return Reloc::ROPI;
-  case LLVMRustRelocModel::RWPI:
-    return Reloc::RWPI;
-  case LLVMRustRelocModel::ROPIRWPI:
-    return Reloc::ROPI_RWPI;
-  }
-  report_fatal_error("Bad RelocModel.");
-}
-
-#ifdef LLVM_RUSTLLVM
-/// getLongestEntryLength - Return the length of the longest entry in the table.
-template<typename KV>
-static size_t getLongestEntryLength(ArrayRef<KV> Table) {
-  size_t MaxLen = 0;
-  for (auto &I : Table)
-    MaxLen = std::max(MaxLen, std::strlen(I.Key));
-  return MaxLen;
-}
-
-extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
-  const TargetMachine *Target = unwrap(TM);
-  const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
-  const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
-  const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
-  const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
-  unsigned MaxCPULen = getLongestEntryLength(CPUTable);
-
-  printf("Available CPUs for this target:\n");
-  if (HostArch == TargetArch) {
-    const StringRef HostCPU = sys::getHostCPUName();
-    printf("    %-*s - Select the CPU of the current host (currently %.*s).\n",
-      MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
-  }
-  for (auto &CPU : CPUTable)
-    printf("    %-*s\n", MaxCPULen, CPU.Key);
-  printf("\n");
-}
-
-extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
-  const TargetMachine *Target = unwrap(TM);
-  const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
-  const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
-  unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
-
-  printf("Available features for this target:\n");
-  for (auto &Feature : FeatTable)
-    printf("    %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
-  printf("\nRust-specific features:\n");
-  printf("    %-*s - %s.\n",
-    MaxFeatLen,
-    "crt-static",
-    "Enables libraries with C Run-time Libraries(CRT) to be statically linked"
-  );
-  printf("\n");
-
-  printf("Use +feature to enable a feature, or -feature to disable it.\n"
-         "For example, rustc -C -target-cpu=mycpu -C "
-         "target-feature=+feature1,-feature2\n\n");
-}
-
-#else
-
-extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
-  printf("Target CPU help is not supported by this LLVM version.\n\n");
-}
-
-extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
-  printf("Target features help is not supported by this LLVM version.\n\n");
-}
-#endif
-
-extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
-  StringRef Name = sys::getHostCPUName();
-  *len = Name.size();
-  return Name.data();
-}
-
-extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
-    const char *TripleStr, const char *CPU, const char *Feature,
-    const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
-    LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
-    bool FunctionSections,
-    bool DataSections,
-    bool TrapUnreachable,
-    bool Singlethread,
-    bool AsmComments,
-    bool EmitStackSizeSection,
-    bool RelaxELFRelocations,
-    bool UseInitArray) {
-
-  auto OptLevel = fromRust(RustOptLevel);
-  auto RM = fromRust(RustReloc);
-  auto CM = fromRust(RustCM);
-
-  std::string Error;
-  Triple Trip(Triple::normalize(TripleStr));
-  const llvm::Target *TheTarget =
-      TargetRegistry::lookupTarget(Trip.getTriple(), Error);
-  if (TheTarget == nullptr) {
-    LLVMRustSetLastError(Error.c_str());
-    return nullptr;
-  }
-
-  TargetOptions Options;
-
-  Options.FloatABIType = FloatABI::Default;
-  if (UseSoftFloat) {
-    Options.FloatABIType = FloatABI::Soft;
-  }
-  Options.DataSections = DataSections;
-  Options.FunctionSections = FunctionSections;
-  Options.MCOptions.AsmVerbose = AsmComments;
-  Options.MCOptions.PreserveAsmComments = AsmComments;
-  Options.MCOptions.ABIName = ABIStr;
-  Options.RelaxELFRelocations = RelaxELFRelocations;
-  Options.UseInitArray = UseInitArray;
-
-  if (TrapUnreachable) {
-    // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
-    // This limits the extent of possible undefined behavior in some cases, as
-    // it prevents control flow from "falling through" into whatever code
-    // happens to be laid out next in memory.
-    Options.TrapUnreachable = true;
-  }
-
-  if (Singlethread) {
-    Options.ThreadModel = ThreadModel::Single;
-  }
-
-  Options.EmitStackSizeSection = EmitStackSizeSection;
-
-  TargetMachine *TM = TheTarget->createTargetMachine(
-      Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
-  return wrap(TM);
-}
-
-extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
-  delete unwrap(TM);
-}
-
-extern "C" void LLVMRustConfigurePassManagerBuilder(
-    LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
-    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
-    const char* PGOGenPath, const char* PGOUsePath) {
-  unwrap(PMBR)->MergeFunctions = MergeFunctions;
-  unwrap(PMBR)->SLPVectorize = SLPVectorize;
-  unwrap(PMBR)->OptLevel = fromRust(OptLevel);
-  unwrap(PMBR)->LoopVectorize = LoopVectorize;
-  unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
-
-  if (PGOGenPath) {
-    assert(!PGOUsePath);
-    unwrap(PMBR)->EnablePGOInstrGen = true;
-    unwrap(PMBR)->PGOInstrGen = PGOGenPath;
-  }
-  if (PGOUsePath) {
-    assert(!PGOGenPath);
-    unwrap(PMBR)->PGOInstrUse = PGOUsePath;
-  }
-}
-
-// Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
-// field of a PassManagerBuilder, we expose our own method of doing so.
-extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
-                                              LLVMModuleRef M,
-                                              bool DisableSimplifyLibCalls) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
-  TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
-  if (DisableSimplifyLibCalls)
-    TLI->disableAllFunctions();
-  unwrap(PMBR)->LibraryInfo = TLI;
-}
-
-// Unfortunately, the LLVM C API doesn't provide a way to create the
-// TargetLibraryInfo pass, so we use this method to do so.
-extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
-                                       bool DisableSimplifyLibCalls) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
-  TargetLibraryInfoImpl TLII(TargetTriple);
-  if (DisableSimplifyLibCalls)
-    TLII.disableAllFunctions();
-  unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
-}
-
-// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
-// all the functions in a module, so we do that manually here. You'll find
-// similar code in clang's BackendUtil.cpp file.
-extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
-                                               LLVMModuleRef M) {
-  llvm::legacy::FunctionPassManager *P =
-      unwrap<llvm::legacy::FunctionPassManager>(PMR);
-  P->doInitialization();
-
-  // Upgrade all calls to old intrinsics first.
-  for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
-    UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
-
-  for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
-       ++I)
-    if (!I->isDeclaration())
-      P->run(*I);
-
-  P->doFinalization();
-}
-
-extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
-  // Initializing the command-line options more than once is not allowed. So,
-  // check if they've already been initialized.  (This could happen if we're
-  // being called from rustpkg, for example). If the arguments change, then
-  // that's just kinda unfortunate.
-  static bool Initialized = false;
-  if (Initialized)
-    return;
-  Initialized = true;
-  cl::ParseCommandLineOptions(Argc, Argv);
-}
-
-enum class LLVMRustFileType {
-  AssemblyFile,
-  ObjectFile,
-};
-
-#if LLVM_VERSION_GE(10, 0)
-static CodeGenFileType fromRust(LLVMRustFileType Type) {
-  switch (Type) {
-  case LLVMRustFileType::AssemblyFile:
-    return CGFT_AssemblyFile;
-  case LLVMRustFileType::ObjectFile:
-    return CGFT_ObjectFile;
-  default:
-    report_fatal_error("Bad FileType.");
-  }
-}
-#else
-static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
-  switch (Type) {
-  case LLVMRustFileType::AssemblyFile:
-    return TargetMachine::CGFT_AssemblyFile;
-  case LLVMRustFileType::ObjectFile:
-    return TargetMachine::CGFT_ObjectFile;
-  default:
-    report_fatal_error("Bad FileType.");
-  }
-}
-#endif
-
-extern "C" LLVMRustResult
-LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
-                        LLVMModuleRef M, const char *Path,
-                        LLVMRustFileType RustFileType) {
-  llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
-  auto FileType = fromRust(RustFileType);
-
-  std::string ErrorInfo;
-  std::error_code EC;
-  raw_fd_ostream OS(Path, EC, sys::fs::F_None);
-  if (EC)
-    ErrorInfo = EC.message();
-  if (ErrorInfo != "") {
-    LLVMRustSetLastError(ErrorInfo.c_str());
-    return LLVMRustResult::Failure;
-  }
-
-  buffer_ostream BOS(OS);
-  unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
-  PM->run(*unwrap(M));
-
-  // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
-  // stream (OS), so the only real safe place to delete this is here? Don't we
-  // wish this was written in Rust?
-  LLVMDisposePassManager(PMR);
-  return LLVMRustResult::Success;
-}
-
-extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmSelfProfiler
-                                                      const char*,      // pass name
-                                                      const char*);     // IR name
-extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler
-
-#if LLVM_VERSION_GE(9, 0)
-
-std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
-  if (any_isa<const Module *>(WrappedIr))
-    return any_cast<const Module *>(WrappedIr)->getName().str();
-  if (any_isa<const Function *>(WrappedIr))
-    return any_cast<const Function *>(WrappedIr)->getName().str();
-  if (any_isa<const Loop *>(WrappedIr))
-    return any_cast<const Loop *>(WrappedIr)->getName().str();
-  if (any_isa<const LazyCallGraph::SCC *>(WrappedIr))
-    return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName();
-  return "<UNKNOWN>";
-}
-
-
-void LLVMSelfProfileInitializeCallbacks(
-    PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
-    LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
-    LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
-  PIC.registerBeforePassCallback([LlvmSelfProfiler, BeforePassCallback](
-                                     StringRef Pass, llvm::Any Ir) {
-    std::string PassName = Pass.str();
-    std::string IrName = LLVMRustwrappedIrGetName(Ir);
-    BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
-    return true;
-  });
-
-  PIC.registerAfterPassCallback(
-      [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
-        AfterPassCallback(LlvmSelfProfiler);
-      });
-
-  PIC.registerAfterPassInvalidatedCallback(
-      [LlvmSelfProfiler, AfterPassCallback](StringRef Pass) {
-        AfterPassCallback(LlvmSelfProfiler);
-      });
-
-  PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
-                                         StringRef Pass, llvm::Any Ir) {
-    std::string PassName = Pass.str();
-    std::string IrName = LLVMRustwrappedIrGetName(Ir);
-    BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
-  });
-
-  PIC.registerAfterAnalysisCallback(
-      [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
-        AfterPassCallback(LlvmSelfProfiler);
-      });
-}
-#endif
-
-enum class LLVMRustOptStage {
-  PreLinkNoLTO,
-  PreLinkThinLTO,
-  PreLinkFatLTO,
-  ThinLTO,
-  FatLTO,
-};
-
-struct LLVMRustSanitizerOptions {
-  bool SanitizeAddress;
-  bool SanitizeAddressRecover;
-  bool SanitizeMemory;
-  bool SanitizeMemoryRecover;
-  int  SanitizeMemoryTrackOrigins;
-  bool SanitizeThread;
-};
-
-extern "C" void
-LLVMRustOptimizeWithNewPassManager(
-    LLVMModuleRef ModuleRef,
-    LLVMTargetMachineRef TMRef,
-    LLVMRustPassBuilderOptLevel OptLevelRust,
-    LLVMRustOptStage OptStage,
-    bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
-    bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
-    bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
-    LLVMRustSanitizerOptions *SanitizerOptions,
-    const char *PGOGenPath, const char *PGOUsePath,
-    void* LlvmSelfProfiler,
-    LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
-    LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
-#if LLVM_VERSION_GE(9, 0)
-  Module *TheModule = unwrap(ModuleRef);
-  TargetMachine *TM = unwrap(TMRef);
-  PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
-
-  // FIXME: MergeFunctions is not supported by NewPM yet.
-  (void) MergeFunctions;
-
-  PipelineTuningOptions PTO;
-  PTO.LoopUnrolling = UnrollLoops;
-  PTO.LoopInterleaving = UnrollLoops;
-  PTO.LoopVectorization = LoopVectorize;
-  PTO.SLPVectorization = SLPVectorize;
-
-  PassInstrumentationCallbacks PIC;
-  StandardInstrumentations SI;
-  SI.registerCallbacks(PIC);
-
-  if (LlvmSelfProfiler){
-    LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback);
-  }
-
-  Optional<PGOOptions> PGOOpt;
-  if (PGOGenPath) {
-    assert(!PGOUsePath);
-    PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr);
-  } else if (PGOUsePath) {
-    assert(!PGOGenPath);
-    PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse);
-  }
-
-  PassBuilder PB(TM, PTO, PGOOpt, &PIC);
-
-  // FIXME: We may want to expose this as an option.
-  bool DebugPassManager = false;
-  LoopAnalysisManager LAM(DebugPassManager);
-  FunctionAnalysisManager FAM(DebugPassManager);
-  CGSCCAnalysisManager CGAM(DebugPassManager);
-  ModuleAnalysisManager MAM(DebugPassManager);
-
-  FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
-
-  Triple TargetTriple(TheModule->getTargetTriple());
-  std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
-  if (DisableSimplifyLibCalls)
-    TLII->disableAllFunctions();
-  FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
-
-  PB.registerModuleAnalyses(MAM);
-  PB.registerCGSCCAnalyses(CGAM);
-  PB.registerFunctionAnalyses(FAM);
-  PB.registerLoopAnalyses(LAM);
-  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
-
-  // We manually collect pipeline callbacks so we can apply them at O0, where the
-  // PassBuilder does not create a pipeline.
-  std::vector<std::function<void(ModulePassManager &)>> PipelineStartEPCallbacks;
-#if LLVM_VERSION_GE(11, 0)
-  std::vector<std::function<void(ModulePassManager &, PassBuilder::OptimizationLevel)>>
-      OptimizerLastEPCallbacks;
-#else
-  std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>>
-      OptimizerLastEPCallbacks;
-#endif
-
-  if (VerifyIR) {
-    PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
-        MPM.addPass(VerifierPass());
-    });
-  }
-
-  if (SanitizerOptions) {
-    if (SanitizerOptions->SanitizeMemory) {
-      MemorySanitizerOptions Options(
-          SanitizerOptions->SanitizeMemoryTrackOrigins,
-          SanitizerOptions->SanitizeMemoryRecover,
-          /*CompileKernel=*/false);
-#if LLVM_VERSION_GE(11, 0)
-      OptimizerLastEPCallbacks.push_back(
-        [Options](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
-          MPM.addPass(MemorySanitizerPass(Options));
-          MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
-        }
-      );
-#else
-#if LLVM_VERSION_GE(10, 0)
-      PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
-        MPM.addPass(MemorySanitizerPass(Options));
-      });
-#endif
-      OptimizerLastEPCallbacks.push_back(
-        [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
-          FPM.addPass(MemorySanitizerPass(Options));
-        }
-      );
-#endif
-    }
-
-    if (SanitizerOptions->SanitizeThread) {
-#if LLVM_VERSION_GE(11, 0)
-      OptimizerLastEPCallbacks.push_back(
-        [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
-          MPM.addPass(ThreadSanitizerPass());
-          MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
-        }
-      );
-#else
-#if LLVM_VERSION_GE(10, 0)
-      PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
-        MPM.addPass(ThreadSanitizerPass());
-      });
-#endif
-      OptimizerLastEPCallbacks.push_back(
-        [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
-          FPM.addPass(ThreadSanitizerPass());
-        }
-      );
-#endif
-    }
-
-    if (SanitizerOptions->SanitizeAddress) {
-#if LLVM_VERSION_GE(11, 0)
-      OptimizerLastEPCallbacks.push_back(
-        [SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
-          MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
-          MPM.addPass(ModuleAddressSanitizerPass(
-              /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
-          MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
-              /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
-              /*UseAfterScope=*/true)));
-        }
-      );
-#else
-      PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
-        MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
-      });
-      OptimizerLastEPCallbacks.push_back(
-        [SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
-          FPM.addPass(AddressSanitizerPass(
-              /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
-              /*UseAfterScope=*/true));
-        }
-      );
-      PipelineStartEPCallbacks.push_back(
-        [SanitizerOptions](ModulePassManager &MPM) {
-          MPM.addPass(ModuleAddressSanitizerPass(
-              /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
-        }
-      );
-#endif
-    }
-  }
-
-  ModulePassManager MPM(DebugPassManager);
-  if (!NoPrepopulatePasses) {
-    if (OptLevel == PassBuilder::OptimizationLevel::O0) {
-      for (const auto &C : PipelineStartEPCallbacks)
-        C(MPM);
-
-#if LLVM_VERSION_GE(11, 0)
-      for (const auto &C : OptimizerLastEPCallbacks)
-        C(MPM, OptLevel);
-#else
-      if (!OptimizerLastEPCallbacks.empty()) {
-        FunctionPassManager FPM(DebugPassManager);
-        for (const auto &C : OptimizerLastEPCallbacks)
-          C(FPM, OptLevel);
-        MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-      }
-#endif
-
-      MPM.addPass(AlwaysInlinerPass(EmitLifetimeMarkers));
-
-#if LLVM_VERSION_GE(10, 0)
-      if (PGOOpt) {
-        PB.addPGOInstrPassesForO0(
-            MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
-            /*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
-      }
-#endif
-    } else {
-      for (const auto &C : PipelineStartEPCallbacks)
-        PB.registerPipelineStartEPCallback(C);
-      if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
-        for (const auto &C : OptimizerLastEPCallbacks)
-          PB.registerOptimizerLastEPCallback(C);
-      }
-
-      switch (OptStage) {
-      case LLVMRustOptStage::PreLinkNoLTO:
-        MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
-        break;
-      case LLVMRustOptStage::PreLinkThinLTO:
-        MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
-#if LLVM_VERSION_GE(11, 0)
-        for (const auto &C : OptimizerLastEPCallbacks)
-          C(MPM, OptLevel);
-#else
-        if (!OptimizerLastEPCallbacks.empty()) {
-          FunctionPassManager FPM(DebugPassManager);
-          for (const auto &C : OptimizerLastEPCallbacks)
-            C(FPM, OptLevel);
-          MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-        }
-#endif
-        break;
-      case LLVMRustOptStage::PreLinkFatLTO:
-        MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
-        break;
-      case LLVMRustOptStage::ThinLTO:
-        // FIXME: Does it make sense to pass the ModuleSummaryIndex?
-        // It only seems to be needed for C++ specific optimizations.
-        MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
-        break;
-      case LLVMRustOptStage::FatLTO:
-        MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
-        break;
-      }
-    }
-  }
-
-  if (UseThinLTOBuffers) {
-    MPM.addPass(CanonicalizeAliasesPass());
-    MPM.addPass(NameAnonGlobalPass());
-  }
-
-  // Upgrade all calls to old intrinsics first.
-  for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
-    UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
-
-  MPM.run(*TheModule, MAM);
-#else
-  // The new pass manager has been available for a long time,
-  // but we don't bother supporting it on old LLVM versions.
-  report_fatal_error("New pass manager only supported since LLVM 9");
-#endif
-}
-
-// Callback to demangle function name
-// Parameters:
-// * name to be demangled
-// * name len
-// * output buffer
-// * output buffer len
-// Returns len of demangled string, or 0 if demangle failed.
-typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
-
-
-namespace {
-
-class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
-  DemangleFn Demangle;
-  std::vector<char> Buf;
-
-public:
-  RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
-
-  // Return empty string if demangle failed
-  // or if name does not need to be demangled
-  StringRef CallDemangle(StringRef name) {
-    if (!Demangle) {
-      return StringRef();
-    }
-
-    if (Buf.size() < name.size() * 2) {
-      // Semangled name usually shorter than mangled,
-      // but allocate twice as much memory just in case
-      Buf.resize(name.size() * 2);
-    }
-
-    auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
-    if (!R) {
-      // Demangle failed.
-      return StringRef();
-    }
-
-    auto Demangled = StringRef(Buf.data(), R);
-    if (Demangled == name) {
-      // Do not print anything if demangled name is equal to mangled.
-      return StringRef();
-    }
-
-    return Demangled;
-  }
-
-  void emitFunctionAnnot(const Function *F,
-                         formatted_raw_ostream &OS) override {
-    StringRef Demangled = CallDemangle(F->getName());
-    if (Demangled.empty()) {
-        return;
-    }
-
-    OS << "; " << Demangled << "\n";
-  }
-
-  void emitInstructionAnnot(const Instruction *I,
-                            formatted_raw_ostream &OS) override {
-    const char *Name;
-    const Value *Value;
-    if (const CallInst *CI = dyn_cast<CallInst>(I)) {
-      Name = "call";
-      Value = CI->getCalledOperand();
-    } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
-      Name = "invoke";
-      Value = II->getCalledOperand();
-    } else {
-      // Could demangle more operations, e. g.
-      // `store %place, @function`.
-      return;
-    }
-
-    if (!Value->hasName()) {
-      return;
-    }
-
-    StringRef Demangled = CallDemangle(Value->getName());
-    if (Demangled.empty()) {
-      return;
-    }
-
-    OS << "; " << Name << " " << Demangled << "\n";
-  }
-};
-
-} // namespace
-
-extern "C" LLVMRustResult
-LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
-  std::string ErrorInfo;
-  std::error_code EC;
-  raw_fd_ostream OS(Path, EC, sys::fs::F_None);
-  if (EC)
-    ErrorInfo = EC.message();
-  if (ErrorInfo != "") {
-    LLVMRustSetLastError(ErrorInfo.c_str());
-    return LLVMRustResult::Failure;
-  }
-
-  RustAssemblyAnnotationWriter AAW(Demangle);
-  formatted_raw_ostream FOS(OS);
-  unwrap(M)->print(FOS, &AAW);
-
-  return LLVMRustResult::Success;
-}
-
-extern "C" void LLVMRustPrintPasses() {
-  LLVMInitializePasses();
-  struct MyListener : PassRegistrationListener {
-    void passEnumerate(const PassInfo *Info) {
-      StringRef PassArg = Info->getPassArgument();
-      StringRef PassName = Info->getPassName();
-      if (!PassArg.empty()) {
-        // These unsigned->signed casts could theoretically overflow, but
-        // realistically never will (and even if, the result is implementation
-        // defined rather plain UB).
-        printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
-               (int)PassName.size(), PassName.data());
-      }
-    }
-  } Listener;
-
-  PassRegistry *PR = PassRegistry::getPassRegistry();
-  PR->enumerateWith(&Listener);
-}
-
-extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
-                                            bool AddLifetimes) {
-  unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
-}
-
-extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
-                                           size_t Len) {
-  llvm::legacy::PassManager passes;
-
-  auto PreserveFunctions = [=](const GlobalValue &GV) {
-    for (size_t I = 0; I < Len; I++) {
-      if (GV.getName() == Symbols[I]) {
-        return true;
-      }
-    }
-    return false;
-  };
-
-  passes.add(llvm::createInternalizePass(PreserveFunctions));
-
-  passes.run(*unwrap(M));
-}
-
-extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
-  for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
-       ++GV) {
-    GV->setDoesNotThrow();
-    Function *F = dyn_cast<Function>(GV);
-    if (F == nullptr)
-      continue;
-
-    for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
-      for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
-        if (isa<InvokeInst>(I)) {
-          InvokeInst *CI = cast<InvokeInst>(I);
-          CI->setDoesNotThrow();
-        }
-      }
-    }
-  }
-}
-
-extern "C" void
-LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
-                                       LLVMTargetMachineRef TMR) {
-  TargetMachine *Target = unwrap(TMR);
-  unwrap(Module)->setDataLayout(Target->createDataLayout());
-}
-
-extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
-  unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
-}
-
-extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
-  unwrap(M)->setPIELevel(PIELevel::Level::Large);
-}
-
-// Here you'll find an implementation of ThinLTO as used by the Rust compiler
-// right now. This ThinLTO support is only enabled on "recent ish" versions of
-// LLVM, and otherwise it's just blanket rejected from other compilers.
-//
-// Most of this implementation is straight copied from LLVM. At the time of
-// this writing it wasn't *quite* suitable to reuse more code from upstream
-// for our purposes, but we should strive to upstream this support once it's
-// ready to go! I figure we may want a bit of testing locally first before
-// sending this upstream to LLVM. I hear though they're quite eager to receive
-// feedback like this!
-//
-// If you're reading this code and wondering "what in the world" or you're
-// working "good lord by LLVM upgrade is *still* failing due to these bindings"
-// then fear not! (ok maybe fear a little). All code here is mostly based
-// on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
-//
-// You'll find that the general layout here roughly corresponds to the `run`
-// method in that file as well as `ProcessThinLTOModule`. Functions are
-// specifically commented below as well, but if you're updating this code
-// or otherwise trying to understand it, the LLVM source will be useful in
-// interpreting the mysteries within.
-//
-// Otherwise I'll apologize in advance, it probably requires a relatively
-// significant investment on your part to "truly understand" what's going on
-// here. Not saying I do myself, but it took me awhile staring at LLVM's source
-// and various online resources about ThinLTO to make heads or tails of all
-// this.
-
-// This is a shared data structure which *must* be threadsafe to share
-// read-only amongst threads. This also corresponds basically to the arguments
-// of the `ProcessThinLTOModule` function in the LLVM source.
-struct LLVMRustThinLTOData {
-  // The combined index that is the global analysis over all modules we're
-  // performing ThinLTO for. This is mostly managed by LLVM.
-  ModuleSummaryIndex Index;
-
-  // All modules we may look at, stored as in-memory serialized versions. This
-  // is later used when inlining to ensure we can extract any module to inline
-  // from.
-  StringMap<MemoryBufferRef> ModuleMap;
-
-  // A set that we manage of everything we *don't* want internalized. Note that
-  // this includes all transitive references right now as well, but it may not
-  // always!
-  DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
-
-  // Not 100% sure what these are, but they impact what's internalized and
-  // what's inlined across modules, I believe.
-  StringMap<FunctionImporter::ImportMapTy> ImportLists;
-  StringMap<FunctionImporter::ExportSetTy> ExportLists;
-  StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
-
-  LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
-};
-
-// Just an argument to the `LLVMRustCreateThinLTOData` function below.
-struct LLVMRustThinLTOModule {
-  const char *identifier;
-  const char *data;
-  size_t len;
-};
-
-// This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
-// does.
-static const GlobalValueSummary *
-getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
-  auto StrongDefForLinker = llvm::find_if(
-      GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
-        auto Linkage = Summary->linkage();
-        return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
-               !GlobalValue::isWeakForLinker(Linkage);
-      });
-  if (StrongDefForLinker != GVSummaryList.end())
-    return StrongDefForLinker->get();
-
-  auto FirstDefForLinker = llvm::find_if(
-      GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
-        auto Linkage = Summary->linkage();
-        return !GlobalValue::isAvailableExternallyLinkage(Linkage);
-      });
-  if (FirstDefForLinker == GVSummaryList.end())
-    return nullptr;
-  return FirstDefForLinker->get();
-}
-
-// The main entry point for creating the global ThinLTO analysis. The structure
-// here is basically the same as before threads are spawned in the `run`
-// function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
-extern "C" LLVMRustThinLTOData*
-LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
-                          int num_modules,
-                          const char **preserved_symbols,
-                          int num_symbols) {
-#if LLVM_VERSION_GE(10, 0)
-  auto Ret = std::make_unique<LLVMRustThinLTOData>();
-#else
-  auto Ret = llvm::make_unique<LLVMRustThinLTOData>();
-#endif
-
-  // Load each module's summary and merge it into one combined index
-  for (int i = 0; i < num_modules; i++) {
-    auto module = &modules[i];
-    StringRef buffer(module->data, module->len);
-    MemoryBufferRef mem_buffer(buffer, module->identifier);
-
-    Ret->ModuleMap[module->identifier] = mem_buffer;
-
-    if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
-      LLVMRustSetLastError(toString(std::move(Err)).c_str());
-      return nullptr;
-    }
-  }
-
-  // Collect for each module the list of function it defines (GUID -> Summary)
-  Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
-
-  // Convert the preserved symbols set from string to GUID, this is then needed
-  // for internalization.
-  for (int i = 0; i < num_symbols; i++) {
-    auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
-    Ret->GUIDPreservedSymbols.insert(GUID);
-  }
-
-  // Collect the import/export lists for all modules from the call-graph in the
-  // combined index
-  //
-  // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
-  auto deadIsPrevailing = [&](GlobalValue::GUID G) {
-    return PrevailingType::Unknown;
-  };
-  // We don't have a complete picture in our use of ThinLTO, just our immediate
-  // crate, so we need `ImportEnabled = false` to limit internalization.
-  // Otherwise, we sometimes lose `static` values -- see #60184.
-  computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
-                                  deadIsPrevailing, /* ImportEnabled = */ false);
-  ComputeCrossModuleImport(
-    Ret->Index,
-    Ret->ModuleToDefinedGVSummaries,
-    Ret->ImportLists,
-    Ret->ExportLists
-  );
-
-  // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
-  // impacts the caching.
-  //
-  // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
-  // being lifted from `lib/LTO/LTO.cpp` as well
-  StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
-  DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
-  for (auto &I : Ret->Index) {
-    if (I.second.SummaryList.size() > 1)
-      PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
-  }
-  auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
-    const auto &Prevailing = PrevailingCopy.find(GUID);
-    if (Prevailing == PrevailingCopy.end())
-      return true;
-    return Prevailing->second == S;
-  };
-  auto recordNewLinkage = [&](StringRef ModuleIdentifier,
-                              GlobalValue::GUID GUID,
-                              GlobalValue::LinkageTypes NewLinkage) {
-    ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
-  };
-#if LLVM_VERSION_GE(9, 0)
-  thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
-                                  Ret->GUIDPreservedSymbols);
-#else
-  thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
-#endif
-
-  // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
-  // callback below. This callback below will dictate the linkage for all
-  // summaries in the index, and we basically just only want to ensure that dead
-  // symbols are internalized. Otherwise everything that's already external
-  // linkage will stay as external, and internal will stay as internal.
-  std::set<GlobalValue::GUID> ExportedGUIDs;
-  for (auto &List : Ret->Index) {
-    for (auto &GVS: List.second.SummaryList) {
-      if (GlobalValue::isLocalLinkage(GVS->linkage()))
-        continue;
-      auto GUID = GVS->getOriginalName();
-      if (GVS->flags().Live)
-        ExportedGUIDs.insert(GUID);
-    }
-  }
-#if LLVM_VERSION_GE(10, 0)
-  auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
-    const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
-    return (ExportList != Ret->ExportLists.end() &&
-      ExportList->second.count(VI)) ||
-      ExportedGUIDs.count(VI.getGUID());
-  };
-  thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
-#else
-  auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
-    const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
-    return (ExportList != Ret->ExportLists.end() &&
-      ExportList->second.count(GUID)) ||
-      ExportedGUIDs.count(GUID);
-  };
-  thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported);
-#endif
-
-  return Ret.release();
-}
-
-extern "C" void
-LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
-  delete Data;
-}
-
-// Below are the various passes that happen *per module* when doing ThinLTO.
-//
-// In other words, these are the functions that are all run concurrently
-// with one another, one per module. The passes here correspond to the analysis
-// passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
-// `ProcessThinLTOModule` function. Here they're split up into separate steps
-// so rustc can save off the intermediate bytecode between each step.
-
-#if LLVM_VERSION_GE(11, 0)
-static bool
-clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
-  // When linking an ELF shared object, dso_local should be dropped. We
-  // conservatively do this for -fpic.
-  bool ClearDSOLocalOnDeclarations =
-      TM.getTargetTriple().isOSBinFormatELF() &&
-      TM.getRelocationModel() != Reloc::Static &&
-      Mod.getPIELevel() == PIELevel::Default;
-  return ClearDSOLocalOnDeclarations;
-}
-#endif
-
-extern "C" bool
-LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
-                             LLVMTargetMachineRef TM) {
-  Module &Mod = *unwrap(M);
-  TargetMachine &Target = *unwrap(TM);
-
-#if LLVM_VERSION_GE(11, 0)
-  bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
-  bool error = renameModuleForThinLTO(Mod, Data->Index, ClearDSOLocal);
-#else
-  bool error = renameModuleForThinLTO(Mod, Data->Index);
-#endif
-
-  if (error) {
-    LLVMRustSetLastError("renameModuleForThinLTO failed");
-    return false;
-  }
-  return true;
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
-  Module &Mod = *unwrap(M);
-  const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
-  thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
-  return true;
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
-  Module &Mod = *unwrap(M);
-  const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
-  thinLTOInternalizeModule(Mod, DefinedGlobals);
-  return true;
-}
-
-extern "C" bool
-LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
-                             LLVMTargetMachineRef TM) {
-  Module &Mod = *unwrap(M);
-  TargetMachine &Target = *unwrap(TM);
-
-  const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
-  auto Loader = [&](StringRef Identifier) {
-    const auto &Memory = Data->ModuleMap.lookup(Identifier);
-    auto &Context = Mod.getContext();
-    auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
-
-    if (!MOrErr)
-      return MOrErr;
-
-    // The rest of this closure is a workaround for
-    // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
-    // we accidentally import wasm custom sections into different modules,
-    // duplicating them by in the final output artifact.
-    //
-    // The issue is worked around here by manually removing the
-    // `wasm.custom_sections` named metadata node from any imported module. This
-    // we know isn't used by any optimization pass so there's no need for it to
-    // be imported.
-    //
-    // Note that the metadata is currently lazily loaded, so we materialize it
-    // here before looking up if there's metadata inside. The `FunctionImporter`
-    // will immediately materialize metadata anyway after an import, so this
-    // shouldn't be a perf hit.
-    if (Error Err = (*MOrErr)->materializeMetadata()) {
-      Expected<std::unique_ptr<Module>> Ret(std::move(Err));
-      return Ret;
-    }
-
-    auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
-    if (WasmCustomSections)
-      WasmCustomSections->eraseFromParent();
-
-    return MOrErr;
-  };
-#if LLVM_VERSION_GE(11, 0)
-  bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
-  FunctionImporter Importer(Data->Index, Loader, ClearDSOLocal);
-#else
-  FunctionImporter Importer(Data->Index, Loader);
-#endif
-  Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
-  if (!Result) {
-    LLVMRustSetLastError(toString(Result.takeError()).c_str());
-    return false;
-  }
-  return true;
-}
-
-extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
-                                                      const char*, // importing module name
-                                                      const char*); // imported module name
-
-// Calls `module_name_callback` for each module import done by ThinLTO.
-// The callback is provided with regular null-terminated C strings.
-extern "C" void
-LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
-                                LLVMRustModuleNameCallback module_name_callback,
-                                void* callback_payload) {
-  for (const auto& importing_module : data->ImportLists) {
-    const std::string importing_module_id = importing_module.getKey().str();
-    const auto& imports = importing_module.getValue();
-    for (const auto& imported_module : imports) {
-      const std::string imported_module_id = imported_module.getKey().str();
-      module_name_callback(callback_payload,
-                           importing_module_id.c_str(),
-                           imported_module_id.c_str());
-    }
-  }
-}
-
-// This struct and various functions are sort of a hack right now, but the
-// problem is that we've got in-memory LLVM modules after we generate and
-// optimize all codegen-units for one compilation in rustc. To be compatible
-// with the LTO support above we need to serialize the modules plus their
-// ThinLTO summary into memory.
-//
-// This structure is basically an owned version of a serialize module, with
-// a ThinLTO summary attached.
-struct LLVMRustThinLTOBuffer {
-  std::string data;
-};
-
-extern "C" LLVMRustThinLTOBuffer*
-LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
-#if LLVM_VERSION_GE(10, 0)
-  auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
-#else
-  auto Ret = llvm::make_unique<LLVMRustThinLTOBuffer>();
-#endif
-  {
-    raw_string_ostream OS(Ret->data);
-    {
-      legacy::PassManager PM;
-      PM.add(createWriteThinLTOBitcodePass(OS));
-      PM.run(*unwrap(M));
-    }
-  }
-  return Ret.release();
-}
-
-extern "C" void
-LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
-  delete Buffer;
-}
-
-extern "C" const void*
-LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
-  return Buffer->data.data();
-}
-
-extern "C" size_t
-LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
-  return Buffer->data.length();
-}
-
-// This is what we used to parse upstream bitcode for actual ThinLTO
-// processing.  We'll call this once per module optimized through ThinLTO, and
-// it'll be called concurrently on many threads.
-extern "C" LLVMModuleRef
-LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
-                           const char *data,
-                           size_t len,
-                           const char *identifier) {
-  StringRef Data(data, len);
-  MemoryBufferRef Buffer(Data, identifier);
-  unwrap(Context)->enableDebugTypeODRUniquing();
-  Expected<std::unique_ptr<Module>> SrcOrError =
-      parseBitcodeFile(Buffer, *unwrap(Context));
-  if (!SrcOrError) {
-    LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
-    return nullptr;
-  }
-  return wrap(std::move(*SrcOrError).release());
-}
-
-// Find the bitcode section in the object file data and return it as a slice.
-// Fail if the bitcode section is present but empty.
-//
-// On success, the return value is the pointer to the start of the slice and
-// `out_len` is filled with the (non-zero) length. On failure, the return value
-// is `nullptr` and `out_len` is set to zero.
-extern "C" const char*
-LLVMRustGetBitcodeSliceFromObjectData(const char *data,
-                                      size_t len,
-                                      size_t *out_len) {
-  *out_len = 0;
-
-  StringRef Data(data, len);
-  MemoryBufferRef Buffer(Data, ""); // The id is unused.
-
-  Expected<MemoryBufferRef> BitcodeOrError =
-    object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
-  if (!BitcodeOrError) {
-    LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
-    return nullptr;
-  }
-
-  *out_len = BitcodeOrError->getBufferSize();
-  return BitcodeOrError->getBufferStart();
-}
-
-// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
-// the comment in `back/lto.rs` for why this exists.
-extern "C" void
-LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
-                                DICompileUnit **A,
-                                DICompileUnit **B) {
-  Module *M = unwrap(Mod);
-  DICompileUnit **Cur = A;
-  DICompileUnit **Next = B;
-  for (DICompileUnit *CU : M->debug_compile_units()) {
-    *Cur = CU;
-    Cur = Next;
-    Next = nullptr;
-    if (Cur == nullptr)
-      break;
-  }
-}
-
-// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
-// the comment in `back/lto.rs` for why this exists.
-extern "C" void
-LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
-  Module *M = unwrap(Mod);
-
-  // If the original source module didn't have a `DICompileUnit` then try to
-  // merge all the existing compile units. If there aren't actually any though
-  // then there's not much for us to do so return.
-  if (Unit == nullptr) {
-    for (DICompileUnit *CU : M->debug_compile_units()) {
-      Unit = CU;
-      break;
-    }
-    if (Unit == nullptr)
-      return;
-  }
-
-  // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
-  // process it recursively. Note that we used to specifically iterate over
-  // instructions to ensure we feed everything into it, but `processModule`
-  // started doing this the same way in LLVM 7 (commit d769eb36ab2b8).
-  DebugInfoFinder Finder;
-  Finder.processModule(*M);
-
-  // After we've found all our debuginfo, rewrite all subprograms to point to
-  // the same `DICompileUnit`.
-  for (auto &F : Finder.subprograms()) {
-    F->replaceUnit(Unit);
-  }
-
-  // Erase any other references to other `DICompileUnit` instances, the verifier
-  // will later ensure that we don't actually have any other stale references to
-  // worry about.
-  auto *MD = M->getNamedMetadata("llvm.dbg.cu");
-  MD->clearOperands();
-  MD->addOperand(Unit);
-}
diff --git a/src/rustllvm/README b/src/rustllvm/README
deleted file mode 100644
index e1c6dd07d2b..00000000000
--- a/src/rustllvm/README
+++ /dev/null
@@ -1,16 +0,0 @@
-This directory currently contains some LLVM support code. This will generally
-be sent upstream to LLVM in time; for now it lives here.
-
-NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never*
-be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types
-must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here.
-
-Functions that return a failure status and leave the error in
-the LLVM last error should return an LLVMRustResult rather than an
-int or anything to avoid confusion.
-
-When translating enums, add a single `Other` variant as the first
-one to allow for new variants to be added. It should abort when used
-as an input.
-
-All other types must not be typedef-ed as such.
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
deleted file mode 100644
index 9d90b0dfe07..00000000000
--- a/src/rustllvm/RustWrapper.cpp
+++ /dev/null
@@ -1,1721 +0,0 @@
-#include "rustllvm.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/DiagnosticPrinter.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/ADT/Optional.h"
-
-#include <iostream>
-
-//===----------------------------------------------------------------------===
-//
-// This file defines alternate interfaces to core functions that are more
-// readily callable by Rust's FFI.
-//
-//===----------------------------------------------------------------------===
-
-using namespace llvm;
-using namespace llvm::sys;
-using namespace llvm::object;
-
-// LLVMAtomicOrdering is already an enum - don't create another
-// one.
-static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
-  switch (Ordering) {
-  case LLVMAtomicOrderingNotAtomic:
-    return AtomicOrdering::NotAtomic;
-  case LLVMAtomicOrderingUnordered:
-    return AtomicOrdering::Unordered;
-  case LLVMAtomicOrderingMonotonic:
-    return AtomicOrdering::Monotonic;
-  case LLVMAtomicOrderingAcquire:
-    return AtomicOrdering::Acquire;
-  case LLVMAtomicOrderingRelease:
-    return AtomicOrdering::Release;
-  case LLVMAtomicOrderingAcquireRelease:
-    return AtomicOrdering::AcquireRelease;
-  case LLVMAtomicOrderingSequentiallyConsistent:
-    return AtomicOrdering::SequentiallyConsistent;
-  }
-
-  report_fatal_error("Invalid LLVMAtomicOrdering value!");
-}
-
-static LLVM_THREAD_LOCAL char *LastError;
-
-// Custom error handler for fatal LLVM errors.
-//
-// Notably it exits the process with code 101, unlike LLVM's default of 1.
-static void FatalErrorHandler(void *UserData,
-                              const std::string& Reason,
-                              bool GenCrashDiag) {
-  // Do the same thing that the default error handler does.
-  std::cerr << "LLVM ERROR: " << Reason << std::endl;
-
-  // Since this error handler exits the process, we have to run any cleanup that
-  // LLVM would run after handling the error. This might change with an LLVM
-  // upgrade.
-  sys::RunInterruptHandlers();
-
-  exit(101);
-}
-
-extern "C" void LLVMRustInstallFatalErrorHandler() {
-  install_fatal_error_handler(FatalErrorHandler);
-}
-
-extern "C" LLVMMemoryBufferRef
-LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
-      MemoryBuffer::getFile(Path, -1, false);
-  if (!BufOr) {
-    LLVMRustSetLastError(BufOr.getError().message().c_str());
-    return nullptr;
-  }
-  return wrap(BufOr.get().release());
-}
-
-extern "C" char *LLVMRustGetLastError(void) {
-  char *Ret = LastError;
-  LastError = nullptr;
-  return Ret;
-}
-
-extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
-  return unwrap(M)->getInstructionCount();
-}
-
-extern "C" void LLVMRustSetLastError(const char *Err) {
-  free((void *)LastError);
-  LastError = strdup(Err);
-}
-
-extern "C" LLVMContextRef LLVMRustContextCreate(bool shouldDiscardNames) {
-  auto ctx = new LLVMContext();
-  ctx->setDiscardValueNames(shouldDiscardNames);
-  return wrap(ctx);
-}
-
-extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
-                                            const char *Triple) {
-  unwrap(M)->setTargetTriple(Triple::normalize(Triple));
-}
-
-extern "C" void LLVMRustPrintPassTimings() {
-  raw_fd_ostream OS(2, false); // stderr.
-  TimerGroup::printAll(OS);
-}
-
-extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
-                                              size_t NameLen) {
-  return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
-}
-
-extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
-                                                    const char *Name,
-                                                    size_t NameLen,
-                                                    LLVMTypeRef FunctionTy) {
-  return wrap(unwrap(M)
-                  ->getOrInsertFunction(StringRef(Name, NameLen),
-                                        unwrap<FunctionType>(FunctionTy))
-#if LLVM_VERSION_GE(9, 0)
-                  .getCallee()
-#endif
-  );
-}
-
-extern "C" LLVMValueRef
-LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
-  StringRef NameRef(Name, NameLen);
-  return wrap(unwrap(M)->getOrInsertGlobal(NameRef, unwrap(Ty)));
-}
-
-extern "C" LLVMValueRef
-LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
-  return wrap(new GlobalVariable(*unwrap(M),
-                                 unwrap(Ty),
-                                 false,
-                                 GlobalValue::PrivateLinkage,
-                                 nullptr));
-}
-
-extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
-  return wrap(Type::getMetadataTy(*unwrap(C)));
-}
-
-static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
-  switch (Kind) {
-  case AlwaysInline:
-    return Attribute::AlwaysInline;
-  case ByVal:
-    return Attribute::ByVal;
-  case Cold:
-    return Attribute::Cold;
-  case InlineHint:
-    return Attribute::InlineHint;
-  case MinSize:
-    return Attribute::MinSize;
-  case Naked:
-    return Attribute::Naked;
-  case NoAlias:
-    return Attribute::NoAlias;
-  case NoCapture:
-    return Attribute::NoCapture;
-  case NoInline:
-    return Attribute::NoInline;
-  case NonNull:
-    return Attribute::NonNull;
-  case NoRedZone:
-    return Attribute::NoRedZone;
-  case NoReturn:
-    return Attribute::NoReturn;
-  case NoUnwind:
-    return Attribute::NoUnwind;
-  case OptimizeForSize:
-    return Attribute::OptimizeForSize;
-  case ReadOnly:
-    return Attribute::ReadOnly;
-  case SExt:
-    return Attribute::SExt;
-  case StructRet:
-    return Attribute::StructRet;
-  case UWTable:
-    return Attribute::UWTable;
-  case ZExt:
-    return Attribute::ZExt;
-  case InReg:
-    return Attribute::InReg;
-  case SanitizeThread:
-    return Attribute::SanitizeThread;
-  case SanitizeAddress:
-    return Attribute::SanitizeAddress;
-  case SanitizeMemory:
-    return Attribute::SanitizeMemory;
-  case NonLazyBind:
-    return Attribute::NonLazyBind;
-  case OptimizeNone:
-    return Attribute::OptimizeNone;
-  case ReturnsTwice:
-    return Attribute::ReturnsTwice;
-  case ReadNone:
-    return Attribute::ReadNone;
-  case InaccessibleMemOnly:
-    return Attribute::InaccessibleMemOnly;
-  }
-  report_fatal_error("bad AttributeKind");
-}
-
-extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
-                                             LLVMRustAttribute RustAttr) {
-  CallBase *Call = unwrap<CallBase>(Instr);
-  Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
-  Call->addAttribute(Index, Attr);
-}
-
-extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
-                                                 unsigned Index,
-                                                 uint32_t Bytes) {
-  CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addAlignmentAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
-}
-
-extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
-                                                       unsigned Index,
-                                                       uint64_t Bytes) {
-  CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addDereferenceableAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
-}
-
-extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr,
-                                                             unsigned Index,
-                                                             uint64_t Bytes) {
-  CallBase *Call = unwrap<CallBase>(Instr);
-  AttrBuilder B;
-  B.addDereferenceableOrNullAttr(Bytes);
-  Call->setAttributes(Call->getAttributes().addAttributes(
-      Call->getContext(), Index, B));
-}
-
-extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
-                                             LLVMTypeRef Ty) {
-  CallBase *Call = unwrap<CallBase>(Instr);
-#if LLVM_VERSION_GE(9, 0)
-  Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty));
-#else
-  Attribute Attr = Attribute::get(Call->getContext(), Attribute::ByVal);
-#endif
-  Call->addAttribute(Index, Attr);
-}
-
-extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
-                                             LLVMRustAttribute RustAttr) {
-  Function *A = unwrap<Function>(Fn);
-  Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
-  AttrBuilder B(Attr);
-  A->addAttributes(Index, B);
-}
-
-extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn,
-                                         unsigned Index,
-                                         uint32_t Bytes) {
-  Function *A = unwrap<Function>(Fn);
-  AttrBuilder B;
-  B.addAlignmentAttr(Bytes);
-  A->addAttributes(Index, B);
-}
-
-extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
-                                               uint64_t Bytes) {
-  Function *A = unwrap<Function>(Fn);
-  AttrBuilder B;
-  B.addDereferenceableAttr(Bytes);
-  A->addAttributes(Index, B);
-}
-
-extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn,
-                                                     unsigned Index,
-                                                     uint64_t Bytes) {
-  Function *A = unwrap<Function>(Fn);
-  AttrBuilder B;
-  B.addDereferenceableOrNullAttr(Bytes);
-  A->addAttributes(Index, B);
-}
-
-extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
-                                     LLVMTypeRef Ty) {
-  Function *F = unwrap<Function>(Fn);
-#if LLVM_VERSION_GE(9, 0)
-  Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty));
-#else
-  Attribute Attr = Attribute::get(F->getContext(), Attribute::ByVal);
-#endif
-  F->addAttribute(Index, Attr);
-}
-
-extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
-                                                   unsigned Index,
-                                                   const char *Name,
-                                                   const char *Value) {
-  Function *F = unwrap<Function>(Fn);
-  AttrBuilder B;
-  B.addAttribute(Name, Value);
-  F->addAttributes(Index, B);
-}
-
-extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
-                                                 unsigned Index,
-                                                 LLVMRustAttribute RustAttr) {
-  Function *F = unwrap<Function>(Fn);
-  Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
-  AttrBuilder B(Attr);
-  auto PAL = F->getAttributes();
-  auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
-  F->setAttributes(PALNew);
-}
-
-// enable fpmath flag UnsafeAlgebra
-extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
-  if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
-    I->setFast(true);
-  }
-}
-
-extern "C" LLVMValueRef
-LLVMRustBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef Source, const char *Name,
-                        LLVMAtomicOrdering Order) {
-  Value *Ptr = unwrap(Source);
-  Type *Ty = Ptr->getType()->getPointerElementType();
-  LoadInst *LI = unwrap(B)->CreateLoad(Ty, Ptr, Name);
-  LI->setAtomic(fromRust(Order));
-  return wrap(LI);
-}
-
-extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
-                                                 LLVMValueRef V,
-                                                 LLVMValueRef Target,
-                                                 LLVMAtomicOrdering Order) {
-  StoreInst *SI = unwrap(B)->CreateStore(unwrap(V), unwrap(Target));
-  SI->setAtomic(fromRust(Order));
-  return wrap(SI);
-}
-
-// FIXME: Use the C-API LLVMBuildAtomicCmpXchg and LLVMSetWeak
-// once we raise our minimum support to LLVM 10.
-extern "C" LLVMValueRef
-LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Target,
-                           LLVMValueRef Old, LLVMValueRef Source,
-                           LLVMAtomicOrdering Order,
-                           LLVMAtomicOrdering FailureOrder, LLVMBool Weak) {
-  AtomicCmpXchgInst *ACXI = unwrap(B)->CreateAtomicCmpXchg(
-      unwrap(Target), unwrap(Old), unwrap(Source), fromRust(Order),
-      fromRust(FailureOrder));
-  ACXI->setWeak(Weak);
-  return wrap(ACXI);
-}
-
-enum class LLVMRustSynchronizationScope {
-  SingleThread,
-  CrossThread,
-};
-
-static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
-  switch (Scope) {
-  case LLVMRustSynchronizationScope::SingleThread:
-    return SyncScope::SingleThread;
-  case LLVMRustSynchronizationScope::CrossThread:
-    return SyncScope::System;
-  default:
-    report_fatal_error("bad SynchronizationScope.");
-  }
-}
-
-extern "C" LLVMValueRef
-LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
-                         LLVMRustSynchronizationScope Scope) {
-  return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
-}
-
-enum class LLVMRustAsmDialect {
-  Att,
-  Intel,
-};
-
-static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
-  switch (Dialect) {
-  case LLVMRustAsmDialect::Att:
-    return InlineAsm::AD_ATT;
-  case LLVMRustAsmDialect::Intel:
-    return InlineAsm::AD_Intel;
-  default:
-    report_fatal_error("bad AsmDialect.");
-  }
-}
-
-extern "C" LLVMValueRef
-LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
-                  char *Constraints, size_t ConstraintsLen,
-                  LLVMBool HasSideEffects, LLVMBool IsAlignStack,
-                  LLVMRustAsmDialect Dialect) {
-  return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
-                             StringRef(AsmString, AsmStringLen),
-                             StringRef(Constraints, ConstraintsLen),
-                             HasSideEffects, IsAlignStack, fromRust(Dialect)));
-}
-
-extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
-                                        size_t ConstraintsLen) {
-  return InlineAsm::Verify(unwrap<FunctionType>(Ty),
-                           StringRef(Constraints, ConstraintsLen));
-}
-
-extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
-                                              size_t AsmLen) {
-  unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen));
-}
-
-typedef DIBuilder *LLVMRustDIBuilderRef;
-
-template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
-  return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
-}
-
-#define DIDescriptor DIScope
-#define DIArray DINodeArray
-#define unwrapDI unwrapDIPtr
-
-// These values **must** match debuginfo::DIFlags! They also *happen*
-// to match LLVM, but that isn't required as we do giant sets of
-// matching below. The value shouldn't be directly passed to LLVM.
-enum class LLVMRustDIFlags : uint32_t {
-  FlagZero = 0,
-  FlagPrivate = 1,
-  FlagProtected = 2,
-  FlagPublic = 3,
-  FlagFwdDecl = (1 << 2),
-  FlagAppleBlock = (1 << 3),
-  FlagBlockByrefStruct = (1 << 4),
-  FlagVirtual = (1 << 5),
-  FlagArtificial = (1 << 6),
-  FlagExplicit = (1 << 7),
-  FlagPrototyped = (1 << 8),
-  FlagObjcClassComplete = (1 << 9),
-  FlagObjectPointer = (1 << 10),
-  FlagVector = (1 << 11),
-  FlagStaticMember = (1 << 12),
-  FlagLValueReference = (1 << 13),
-  FlagRValueReference = (1 << 14),
-  FlagExternalTypeRef = (1 << 15),
-  FlagIntroducedVirtual = (1 << 18),
-  FlagBitField = (1 << 19),
-  FlagNoReturn = (1 << 20),
-  // Do not add values that are not supported by the minimum LLVM
-  // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
-};
-
-inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
-  return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
-                                      static_cast<uint32_t>(B));
-}
-
-inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
-  return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
-                                      static_cast<uint32_t>(B));
-}
-
-inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
-  return A = A | B;
-}
-
-inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
-
-inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
-  return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
-}
-
-static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
-  DINode::DIFlags Result = DINode::DIFlags::FlagZero;
-
-  switch (visibility(Flags)) {
-  case LLVMRustDIFlags::FlagPrivate:
-    Result |= DINode::DIFlags::FlagPrivate;
-    break;
-  case LLVMRustDIFlags::FlagProtected:
-    Result |= DINode::DIFlags::FlagProtected;
-    break;
-  case LLVMRustDIFlags::FlagPublic:
-    Result |= DINode::DIFlags::FlagPublic;
-    break;
-  default:
-    // The rest are handled below
-    break;
-  }
-
-  if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
-    Result |= DINode::DIFlags::FlagFwdDecl;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
-    Result |= DINode::DIFlags::FlagAppleBlock;
-  }
-#if LLVM_VERSION_LT(10, 0)
-  if (isSet(Flags & LLVMRustDIFlags::FlagBlockByrefStruct)) {
-    Result |= DINode::DIFlags::FlagBlockByrefStruct;
-  }
-#endif
-  if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
-    Result |= DINode::DIFlags::FlagVirtual;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
-    Result |= DINode::DIFlags::FlagArtificial;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
-    Result |= DINode::DIFlags::FlagExplicit;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
-    Result |= DINode::DIFlags::FlagPrototyped;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
-    Result |= DINode::DIFlags::FlagObjcClassComplete;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
-    Result |= DINode::DIFlags::FlagObjectPointer;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
-    Result |= DINode::DIFlags::FlagVector;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
-    Result |= DINode::DIFlags::FlagStaticMember;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
-    Result |= DINode::DIFlags::FlagLValueReference;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
-    Result |= DINode::DIFlags::FlagRValueReference;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
-    Result |= DINode::DIFlags::FlagIntroducedVirtual;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
-    Result |= DINode::DIFlags::FlagBitField;
-  }
-  if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
-    Result |= DINode::DIFlags::FlagNoReturn;
-  }
-
-  return Result;
-}
-
-// These values **must** match debuginfo::DISPFlags! They also *happen*
-// to match LLVM, but that isn't required as we do giant sets of
-// matching below. The value shouldn't be directly passed to LLVM.
-enum class LLVMRustDISPFlags : uint32_t {
-  SPFlagZero = 0,
-  SPFlagVirtual = 1,
-  SPFlagPureVirtual = 2,
-  SPFlagLocalToUnit = (1 << 2),
-  SPFlagDefinition = (1 << 3),
-  SPFlagOptimized = (1 << 4),
-  SPFlagMainSubprogram = (1 << 5),
-  // Do not add values that are not supported by the minimum LLVM
-  // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
-  // (In LLVM < 8, createFunction supported these as separate bool arguments.)
-};
-
-inline LLVMRustDISPFlags operator&(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
-  return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) &
-                                      static_cast<uint32_t>(B));
-}
-
-inline LLVMRustDISPFlags operator|(LLVMRustDISPFlags A, LLVMRustDISPFlags B) {
-  return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(A) |
-                                      static_cast<uint32_t>(B));
-}
-
-inline LLVMRustDISPFlags &operator|=(LLVMRustDISPFlags &A, LLVMRustDISPFlags B) {
-  return A = A | B;
-}
-
-inline bool isSet(LLVMRustDISPFlags F) { return F != LLVMRustDISPFlags::SPFlagZero; }
-
-inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) {
-  return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3);
-}
-
-static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) {
-  DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero;
-
-  switch (virtuality(SPFlags)) {
-  case LLVMRustDISPFlags::SPFlagVirtual:
-    Result |= DISubprogram::DISPFlags::SPFlagVirtual;
-    break;
-  case LLVMRustDISPFlags::SPFlagPureVirtual:
-    Result |= DISubprogram::DISPFlags::SPFlagPureVirtual;
-    break;
-  default:
-    // The rest are handled below
-    break;
-  }
-
-  if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit)) {
-    Result |= DISubprogram::DISPFlags::SPFlagLocalToUnit;
-  }
-  if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition)) {
-    Result |= DISubprogram::DISPFlags::SPFlagDefinition;
-  }
-  if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) {
-    Result |= DISubprogram::DISPFlags::SPFlagOptimized;
-  }
-#if LLVM_VERSION_GE(9, 0)
-  if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) {
-    Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram;
-  }
-#endif
-
-  return Result;
-}
-
-enum class LLVMRustDebugEmissionKind {
-  NoDebug,
-  FullDebug,
-  LineTablesOnly,
-};
-
-static DICompileUnit::DebugEmissionKind fromRust(LLVMRustDebugEmissionKind Kind) {
-  switch (Kind) {
-  case LLVMRustDebugEmissionKind::NoDebug:
-    return DICompileUnit::DebugEmissionKind::NoDebug;
-  case LLVMRustDebugEmissionKind::FullDebug:
-    return DICompileUnit::DebugEmissionKind::FullDebug;
-  case LLVMRustDebugEmissionKind::LineTablesOnly:
-    return DICompileUnit::DebugEmissionKind::LineTablesOnly;
-  default:
-    report_fatal_error("bad DebugEmissionKind.");
-  }
-}
-
-enum class LLVMRustChecksumKind {
-  None,
-  MD5,
-  SHA1,
-};
-
-static Optional<DIFile::ChecksumKind> fromRust(LLVMRustChecksumKind Kind) {
-  switch (Kind) {
-  case LLVMRustChecksumKind::None:
-    return None;
-  case LLVMRustChecksumKind::MD5:
-    return DIFile::ChecksumKind::CSK_MD5;
-  case LLVMRustChecksumKind::SHA1:
-    return DIFile::ChecksumKind::CSK_SHA1;
-  default:
-    report_fatal_error("bad ChecksumKind.");
-  }
-}
-
-extern "C" uint32_t LLVMRustDebugMetadataVersion() {
-  return DEBUG_METADATA_VERSION;
-}
-
-extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
-
-extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
-
-extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
-                                      uint32_t Value) {
-  unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
-}
-
-extern "C" LLVMValueRef LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
-  return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
-}
-
-extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
-  return new DIBuilder(*unwrap(M));
-}
-
-extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
-  delete Builder;
-}
-
-extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
-  Builder->finalize();
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
-    LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
-    const char *Producer, size_t ProducerLen, bool isOptimized,
-    const char *Flags, unsigned RuntimeVer,
-    const char *SplitName, size_t SplitNameLen,
-    LLVMRustDebugEmissionKind Kind) {
-  auto *File = unwrapDI<DIFile>(FileRef);
-
-  return wrap(Builder->createCompileUnit(Lang, File, StringRef(Producer, ProducerLen),
-                                         isOptimized, Flags, RuntimeVer,
-                                         StringRef(SplitName, SplitNameLen),
-                                         fromRust(Kind)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFile(
-    LLVMRustDIBuilderRef Builder,
-    const char *Filename, size_t FilenameLen,
-    const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind,
-    const char *Checksum, size_t ChecksumLen) {
-  Optional<DIFile::ChecksumKind> llvmCSKind = fromRust(CSKind);
-  Optional<DIFile::ChecksumInfo<StringRef>> CSInfo{};
-  if (llvmCSKind)
-    CSInfo.emplace(*llvmCSKind, StringRef{Checksum, ChecksumLen});
-  return wrap(Builder->createFile(StringRef(Filename, FilenameLen),
-                                  StringRef(Directory, DirectoryLen),
-                                  CSInfo));
-}
-
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
-                                      LLVMMetadataRef ParameterTypes) {
-  return wrap(Builder->createSubroutineType(
-      DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    const char *LinkageName, size_t LinkageNameLen,
-    LLVMMetadataRef File, unsigned LineNo,
-    LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
-    LLVMRustDISPFlags SPFlags, LLVMValueRef Fn, LLVMMetadataRef TParam,
-    LLVMMetadataRef Decl) {
-  DITemplateParameterArray TParams =
-      DITemplateParameterArray(unwrap<MDTuple>(TParam));
-  DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
-  DINode::DIFlags llvmFlags = fromRust(Flags);
-#if LLVM_VERSION_LT(9, 0)
-  if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram))
-    llvmFlags |= DINode::DIFlags::FlagMainSubprogram;
-#endif
-  DISubprogram *Sub = Builder->createFunction(
-      unwrapDI<DIScope>(Scope),
-      StringRef(Name, NameLen),
-      StringRef(LinkageName, LinkageNameLen),
-      unwrapDI<DIFile>(File), LineNo,
-      unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
-      llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
-  unwrap<Function>(Fn)->setSubprogram(Sub);
-  return wrap(Sub);
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
-    LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
-    uint64_t SizeInBits, unsigned Encoding) {
-  return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
-  return wrap(Builder->createTypedef(
-    unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
-    LineNo, unwrap<DIScope>(Scope)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
-    uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
-    const char *Name, size_t NameLen) {
-  return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
-                                         SizeInBits, AlignInBits,
-                                         AddressSpace,
-                                         StringRef(Name, NameLen)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
-    uint32_t AlignInBits, LLVMRustDIFlags Flags,
-    LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
-    unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
-    const char *UniqueId, size_t UniqueIdLen) {
-  return wrap(Builder->createStructType(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
-      unwrapDI<DIFile>(File), LineNumber,
-      SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIType>(DerivedFrom),
-      DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
-      unwrapDI<DIType>(VTableHolder), StringRef(UniqueId, UniqueIdLen)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
-    uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
-    LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) {
-  return wrap(Builder->createVariantPart(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
-      unwrapDI<DIFile>(File), LineNumber,
-      SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
-      DINodeArray(unwrapDI<MDTuple>(Elements)), StringRef(UniqueId, UniqueIdLen)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
-    uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
-    LLVMMetadataRef Ty) {
-  return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope),
-                                        StringRef(Name, NameLen),
-                                        unwrapDI<DIFile>(File), LineNo,
-                                        SizeInBits, AlignInBits, OffsetInBits,
-                                        fromRust(Flags), unwrapDI<DIType>(Ty)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo,
-    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
-    LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
-  llvm::ConstantInt* D = nullptr;
-  if (Discriminant) {
-    D = unwrap<llvm::ConstantInt>(Discriminant);
-  }
-  return wrap(Builder->createVariantMemberType(unwrapDI<DIDescriptor>(Scope),
-                                               StringRef(Name, NameLen),
-                                               unwrapDI<DIFile>(File), LineNo,
-                                               SizeInBits, AlignInBits, OffsetInBits, D,
-                                               fromRust(Flags), unwrapDI<DIType>(Ty)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    LLVMMetadataRef File, unsigned Line, unsigned Col) {
-  return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
-                                          unwrapDI<DIFile>(File), Line, Col));
-}
-
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
-                                        LLVMMetadataRef Scope,
-                                        LLVMMetadataRef File) {
-  return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
-                                              unwrapDI<DIFile>(File)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context,
-    const char *Name, size_t NameLen,
-    const char *LinkageName, size_t LinkageNameLen,
-    LLVMMetadataRef File, unsigned LineNo,
-    LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
-    LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
-  llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
-
-  llvm::DIExpression *InitExpr = nullptr;
-  if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
-    InitExpr = Builder->createConstantValueExpression(
-        IntVal->getValue().getSExtValue());
-  } else if (llvm::ConstantFP *FPVal =
-                 llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
-    InitExpr = Builder->createConstantValueExpression(
-        FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
-  }
-
-  llvm::DIGlobalVariableExpression *VarExpr = Builder->createGlobalVariableExpression(
-      unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
-      StringRef(LinkageName, LinkageNameLen),
-      unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
-#if LLVM_VERSION_GE(10, 0)
-      /* isDefined */ true,
-#endif
-      InitExpr, unwrapDIPtr<MDNode>(Decl),
-      /* templateParams */ nullptr,
-      AlignInBits);
-
-  InitVal->setMetadata("dbg", VarExpr);
-
-  return wrap(VarExpr);
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
-    LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNo,
-    LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
-    unsigned ArgNo, uint32_t AlignInBits) {
-  if (Tag == 0x100) { // DW_TAG_auto_variable
-    return wrap(Builder->createAutoVariable(
-        unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
-        unwrapDI<DIFile>(File), LineNo,
-        unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits));
-  } else {
-    return wrap(Builder->createParameterVariable(
-        unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ArgNo,
-        unwrapDI<DIFile>(File), LineNo,
-        unwrapDI<DIType>(Ty), AlwaysPreserve, fromRust(Flags)));
-  }
-}
-
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
-                                 uint32_t AlignInBits, LLVMMetadataRef Ty,
-                                 LLVMMetadataRef Subscripts) {
-  return wrap(
-      Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
-                               DINodeArray(unwrapDI<MDTuple>(Subscripts))));
-}
-
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
-                                     int64_t Count) {
-  return wrap(Builder->getOrCreateSubrange(Lo, Count));
-}
-
-extern "C" LLVMMetadataRef
-LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
-                                  LLVMMetadataRef *Ptr, unsigned Count) {
-  Metadata **DataValue = unwrap(Ptr);
-  return wrap(
-      Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
-}
-
-extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
-    LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
-    int64_t *AddrOps, unsigned AddrOpsCount, LLVMValueRef DL,
-    LLVMBasicBlockRef InsertAtEnd) {
-  return wrap(Builder->insertDeclare(
-      unwrap(V), unwrap<DILocalVariable>(VarInfo),
-      Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
-      DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
-      unwrap(InsertAtEnd)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
-    LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
-    int64_t Value, bool IsUnsigned) {
-  return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
-    uint32_t AlignInBits, LLVMMetadataRef Elements,
-    LLVMMetadataRef ClassTy, bool IsScoped) {
-  return wrap(Builder->createEnumerationType(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
-      unwrapDI<DIFile>(File), LineNumber,
-      SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
-      unwrapDI<DIType>(ClassTy), "", IsScoped));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen,
-    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
-    uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
-    unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen) {
-  return wrap(Builder->createUnionType(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIFile>(File),
-      LineNumber, SizeInBits, AlignInBits, fromRust(Flags),
-      DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang,
-      StringRef(UniqueId, UniqueIdLen)));
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen, LLVMMetadataRef Ty) {
-#if LLVM_VERSION_GE(11, 0)
-  bool IsDefault = false; // FIXME: should we ever set this true?
-  return wrap(Builder->createTemplateTypeParameter(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty), IsDefault));
-#else
-  return wrap(Builder->createTemplateTypeParameter(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), unwrapDI<DIType>(Ty)));
-#endif
-}
-
-extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateNameSpace(
-    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
-    const char *Name, size_t NameLen, bool ExportSymbols) {
-  return wrap(Builder->createNameSpace(
-      unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen), ExportSymbols
-  ));
-}
-
-extern "C" void
-LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
-                                     LLVMMetadataRef CompositeTy,
-                                     LLVMMetadataRef Elements,
-                                     LLVMMetadataRef Params) {
-  DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
-  Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
-                         DINodeArray(unwrap<MDTuple>(Params)));
-}
-
-extern "C" LLVMValueRef
-LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
-                                     unsigned Column, LLVMMetadataRef Scope,
-                                     LLVMMetadataRef InlinedAt) {
-  LLVMContext &Context = *unwrap(ContextRef);
-
-  DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
-                                     unwrapDIPtr<MDNode>(InlinedAt));
-
-  return wrap(MetadataAsValue::get(Context, debug_loc.getAsMDNode()));
-}
-
-extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
-  return dwarf::DW_OP_deref;
-}
-
-extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
-  return dwarf::DW_OP_plus_uconst;
-}
-
-extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
-  RawRustStringOstream OS(Str);
-  unwrap<llvm::Type>(Ty)->print(OS);
-}
-
-extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
-                                           RustStringRef Str) {
-  RawRustStringOstream OS(Str);
-  if (!V) {
-    OS << "(null)";
-  } else {
-    OS << "(";
-    unwrap<llvm::Value>(V)->getType()->print(OS);
-    OS << ":";
-    unwrap<llvm::Value>(V)->print(OS);
-    OS << ")";
-  }
-}
-
-// Note that the two following functions look quite similar to the
-// LLVMGetSectionName function. Sadly, it appears that this function only
-// returns a char* pointer, which isn't guaranteed to be null-terminated. The
-// function provided by LLVM doesn't return the length, so we've created our own
-// function which returns the length as well as the data pointer.
-//
-// For an example of this not returning a null terminated string, see
-// lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
-// branches explicitly creates a StringRef without a null terminator, and then
-// that's returned.
-
-inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
-  return reinterpret_cast<section_iterator *>(SI);
-}
-
-extern "C" size_t LLVMRustGetSectionName(LLVMSectionIteratorRef SI,
-                                         const char **Ptr) {
-#if LLVM_VERSION_GE(10, 0)
-  auto NameOrErr = (*unwrap(SI))->getName();
-  if (!NameOrErr)
-    report_fatal_error(NameOrErr.takeError());
-  *Ptr = NameOrErr->data();
-  return NameOrErr->size();
-#else
-  StringRef Ret;
-  if (std::error_code EC = (*unwrap(SI))->getName(Ret))
-    report_fatal_error(EC.message());
-  *Ptr = Ret.data();
-  return Ret.size();
-#endif
-}
-
-// LLVMArrayType function does not support 64-bit ElementCount
-extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
-                                         uint64_t ElementCount) {
-  return wrap(ArrayType::get(unwrap(ElementTy), ElementCount));
-}
-
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
-
-extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
-  RawRustStringOstream OS(Str);
-  unwrap(T)->print(OS);
-}
-
-extern "C" void LLVMRustUnpackOptimizationDiagnostic(
-    LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
-    LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
-    RustStringRef FilenameOut, RustStringRef MessageOut) {
-  // Undefined to call this not on an optimization diagnostic!
-  llvm::DiagnosticInfoOptimizationBase *Opt =
-      static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
-
-  RawRustStringOstream PassNameOS(PassNameOut);
-  PassNameOS << Opt->getPassName();
-  *FunctionOut = wrap(&Opt->getFunction());
-
-  RawRustStringOstream FilenameOS(FilenameOut);
-  DiagnosticLocation loc = Opt->getLocation();
-  if (loc.isValid()) {
-    *Line = loc.getLine();
-    *Column = loc.getColumn();
-    FilenameOS << loc.getAbsolutePath();
-  }
-
-  RawRustStringOstream MessageOS(MessageOut);
-  MessageOS << Opt->getMsg();
-}
-
-enum class LLVMRustDiagnosticLevel {
-    Error,
-    Warning,
-    Note,
-    Remark,
-};
-
-extern "C" void
-LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
-                                  LLVMRustDiagnosticLevel *LevelOut,
-                                  unsigned *CookieOut,
-                                  LLVMTwineRef *MessageOut,
-                                  LLVMValueRef *InstructionOut) {
-  // Undefined to call this not on an inline assembly diagnostic!
-  llvm::DiagnosticInfoInlineAsm *IA =
-      static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
-
-  *CookieOut = IA->getLocCookie();
-  *MessageOut = wrap(&IA->getMsgStr());
-  *InstructionOut = wrap(IA->getInstruction());
-
-  switch (IA->getSeverity()) {
-    case DS_Error:
-      *LevelOut = LLVMRustDiagnosticLevel::Error;
-      break;
-    case DS_Warning:
-      *LevelOut = LLVMRustDiagnosticLevel::Warning;
-      break;
-    case DS_Note:
-      *LevelOut = LLVMRustDiagnosticLevel::Note;
-      break;
-    case DS_Remark:
-      *LevelOut = LLVMRustDiagnosticLevel::Remark;
-      break;
-    default:
-      report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
-  }
-}
-
-extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
-                                                    RustStringRef Str) {
-  RawRustStringOstream OS(Str);
-  DiagnosticPrinterRawOStream DP(OS);
-  unwrap(DI)->print(DP);
-}
-
-enum class LLVMRustDiagnosticKind {
-  Other,
-  InlineAsm,
-  StackSize,
-  DebugMetadataVersion,
-  SampleProfile,
-  OptimizationRemark,
-  OptimizationRemarkMissed,
-  OptimizationRemarkAnalysis,
-  OptimizationRemarkAnalysisFPCommute,
-  OptimizationRemarkAnalysisAliasing,
-  OptimizationRemarkOther,
-  OptimizationFailure,
-  PGOProfile,
-  Linker,
-};
-
-static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
-  switch (Kind) {
-  case DK_InlineAsm:
-    return LLVMRustDiagnosticKind::InlineAsm;
-  case DK_StackSize:
-    return LLVMRustDiagnosticKind::StackSize;
-  case DK_DebugMetadataVersion:
-    return LLVMRustDiagnosticKind::DebugMetadataVersion;
-  case DK_SampleProfile:
-    return LLVMRustDiagnosticKind::SampleProfile;
-  case DK_OptimizationRemark:
-    return LLVMRustDiagnosticKind::OptimizationRemark;
-  case DK_OptimizationRemarkMissed:
-    return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
-  case DK_OptimizationRemarkAnalysis:
-    return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
-  case DK_OptimizationRemarkAnalysisFPCommute:
-    return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
-  case DK_OptimizationRemarkAnalysisAliasing:
-    return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
-  case DK_PGOProfile:
-    return LLVMRustDiagnosticKind::PGOProfile;
-  case DK_Linker:
-    return LLVMRustDiagnosticKind::Linker;
-  default:
-    return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
-               ? LLVMRustDiagnosticKind::OptimizationRemarkOther
-               : LLVMRustDiagnosticKind::Other;
-  }
-}
-
-extern "C" LLVMRustDiagnosticKind
-LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
-  return toRust((DiagnosticKind)unwrap(DI)->getKind());
-}
-
-// This is kept distinct from LLVMGetTypeKind, because when
-// a new type kind is added, the Rust-side enum must be
-// updated or UB will result.
-extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
-  switch (unwrap(Ty)->getTypeID()) {
-  case Type::VoidTyID:
-    return LLVMVoidTypeKind;
-  case Type::HalfTyID:
-    return LLVMHalfTypeKind;
-  case Type::FloatTyID:
-    return LLVMFloatTypeKind;
-  case Type::DoubleTyID:
-    return LLVMDoubleTypeKind;
-  case Type::X86_FP80TyID:
-    return LLVMX86_FP80TypeKind;
-  case Type::FP128TyID:
-    return LLVMFP128TypeKind;
-  case Type::PPC_FP128TyID:
-    return LLVMPPC_FP128TypeKind;
-  case Type::LabelTyID:
-    return LLVMLabelTypeKind;
-  case Type::MetadataTyID:
-    return LLVMMetadataTypeKind;
-  case Type::IntegerTyID:
-    return LLVMIntegerTypeKind;
-  case Type::FunctionTyID:
-    return LLVMFunctionTypeKind;
-  case Type::StructTyID:
-    return LLVMStructTypeKind;
-  case Type::ArrayTyID:
-    return LLVMArrayTypeKind;
-  case Type::PointerTyID:
-    return LLVMPointerTypeKind;
-#if LLVM_VERSION_GE(11, 0)
-  case Type::FixedVectorTyID:
-    return LLVMVectorTypeKind;
-#else
-  case Type::VectorTyID:
-    return LLVMVectorTypeKind;
-#endif
-  case Type::X86_MMXTyID:
-    return LLVMX86_MMXTypeKind;
-  case Type::TokenTyID:
-    return LLVMTokenTypeKind;
-#if LLVM_VERSION_GE(11, 0)
-  case Type::ScalableVectorTyID:
-    return LLVMScalableVectorTypeKind;
-  case Type::BFloatTyID:
-    return LLVMBFloatTypeKind;
-#endif
-  }
-  report_fatal_error("Unhandled TypeID.");
-}
-
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
-
-extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
-    LLVMContextRef C, LLVMContext::InlineAsmDiagHandlerTy H, void *CX) {
-  unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
-}
-
-extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
-                                           RustStringRef MessageOut,
-                                           RustStringRef BufferOut,
-                                           LLVMRustDiagnosticLevel* LevelOut,
-                                           unsigned* LocOut,
-                                           unsigned* RangesOut,
-                                           size_t* NumRanges) {
-  SMDiagnostic& D = *unwrap(DRef);
-  RawRustStringOstream MessageOS(MessageOut);
-  MessageOS << D.getMessage();
-
-  switch (D.getKind()) {
-    case SourceMgr::DK_Error:
-      *LevelOut = LLVMRustDiagnosticLevel::Error;
-      break;
-    case SourceMgr::DK_Warning:
-      *LevelOut = LLVMRustDiagnosticLevel::Warning;
-      break;
-    case SourceMgr::DK_Note:
-      *LevelOut = LLVMRustDiagnosticLevel::Note;
-      break;
-    case SourceMgr::DK_Remark:
-      *LevelOut = LLVMRustDiagnosticLevel::Remark;
-      break;
-    default:
-      report_fatal_error("Invalid LLVMRustDiagnosticLevel value!");
-  }
-
-  if (D.getLoc() == SMLoc())
-    return false;
-
-  const SourceMgr &LSM = *D.getSourceMgr();
-  const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
-  LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), LBuf->getBufferSize());
-
-  *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart();
-
-  *NumRanges = std::min(*NumRanges, D.getRanges().size());
-  size_t LineStart = *LocOut - (size_t)D.getColumnNo();
-  for (size_t i = 0; i < *NumRanges; i++) {
-    RangesOut[i * 2] = LineStart + D.getRanges()[i].first;
-    RangesOut[i * 2 + 1] = LineStart + D.getRanges()[i].second;
-  }
-
-  return true;
-}
-
-extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B,
-                                                LLVMValueRef ParentPad,
-                                                unsigned ArgCount,
-                                                LLVMValueRef *LLArgs,
-                                                const char *Name) {
-  Value **Args = unwrap(LLArgs);
-  if (ParentPad == nullptr) {
-    Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
-    ParentPad = wrap(Constant::getNullValue(Ty));
-  }
-  return wrap(unwrap(B)->CreateCleanupPad(
-      unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
-}
-
-extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B,
-                                                LLVMValueRef CleanupPad,
-                                                LLVMBasicBlockRef UnwindBB) {
-  CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
-  return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
-}
-
-extern "C" LLVMValueRef
-LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
-                      unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) {
-  Value **Args = unwrap(LLArgs);
-  return wrap(unwrap(B)->CreateCatchPad(
-      unwrap(ParentPad), ArrayRef<Value *>(Args, ArgCount), Name));
-}
-
-extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B,
-                                              LLVMValueRef Pad,
-                                              LLVMBasicBlockRef BB) {
-  return wrap(unwrap(B)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
-                                              unwrap(BB)));
-}
-
-extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B,
-                                                 LLVMValueRef ParentPad,
-                                                 LLVMBasicBlockRef BB,
-                                                 unsigned NumHandlers,
-                                                 const char *Name) {
-  if (ParentPad == nullptr) {
-    Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
-    ParentPad = wrap(Constant::getNullValue(Ty));
-  }
-  return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB),
-                                                 NumHandlers, Name));
-}
-
-extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
-                                   LLVMBasicBlockRef Handler) {
-  Value *CatchSwitch = unwrap(CatchSwitchRef);
-  cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
-}
-
-extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
-                                                           LLVMValueRef *Inputs,
-                                                           unsigned NumInputs) {
-  return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
-}
-
-extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) {
-  delete Bundle;
-}
-
-extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
-                                          LLVMValueRef *Args, unsigned NumArgs,
-                                          OperandBundleDef *Bundle) {
-  Value *Callee = unwrap(Fn);
-  FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
-  unsigned Len = Bundle ? 1 : 0;
-  ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
-  return wrap(unwrap(B)->CreateCall(
-      FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), Bundles));
-}
-
-extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
-  return wrap(llvm::Intrinsic::getDeclaration(unwrap(M),
-              (llvm::Intrinsic::ID)llvm::Intrinsic::instrprof_increment));
-}
-
-extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
-                                            LLVMValueRef Dst, unsigned DstAlign,
-                                            LLVMValueRef Src, unsigned SrcAlign,
-                                            LLVMValueRef Size, bool IsVolatile) {
-#if LLVM_VERSION_GE(10, 0)
-  return wrap(unwrap(B)->CreateMemCpy(
-      unwrap(Dst), MaybeAlign(DstAlign),
-      unwrap(Src), MaybeAlign(SrcAlign),
-      unwrap(Size), IsVolatile));
-#else
-  return wrap(unwrap(B)->CreateMemCpy(
-      unwrap(Dst), DstAlign,
-      unwrap(Src), SrcAlign,
-      unwrap(Size), IsVolatile));
-#endif
-}
-
-extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
-                                             LLVMValueRef Dst, unsigned DstAlign,
-                                             LLVMValueRef Src, unsigned SrcAlign,
-                                             LLVMValueRef Size, bool IsVolatile) {
-#if LLVM_VERSION_GE(10, 0)
-  return wrap(unwrap(B)->CreateMemMove(
-      unwrap(Dst), MaybeAlign(DstAlign),
-      unwrap(Src), MaybeAlign(SrcAlign),
-      unwrap(Size), IsVolatile));
-#else
-  return wrap(unwrap(B)->CreateMemMove(
-      unwrap(Dst), DstAlign,
-      unwrap(Src), SrcAlign,
-      unwrap(Size), IsVolatile));
-#endif
-}
-
-extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B,
-                                            LLVMValueRef Dst, unsigned DstAlign,
-                                            LLVMValueRef Val,
-                                            LLVMValueRef Size, bool IsVolatile) {
-#if LLVM_VERSION_GE(10, 0)
-  return wrap(unwrap(B)->CreateMemSet(
-      unwrap(Dst), unwrap(Val), unwrap(Size), MaybeAlign(DstAlign), IsVolatile));
-#else
-  return wrap(unwrap(B)->CreateMemSet(
-      unwrap(Dst), unwrap(Val), unwrap(Size), DstAlign, IsVolatile));
-#endif
-}
-
-extern "C" LLVMValueRef
-LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
-                    unsigned NumArgs, LLVMBasicBlockRef Then,
-                    LLVMBasicBlockRef Catch, OperandBundleDef *Bundle,
-                    const char *Name) {
-  Value *Callee = unwrap(Fn);
-  FunctionType *FTy = cast<FunctionType>(Callee->getType()->getPointerElementType());
-  unsigned Len = Bundle ? 1 : 0;
-  ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, Len);
-  return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch),
-                                      makeArrayRef(unwrap(Args), NumArgs),
-                                      Bundles, Name));
-}
-
-extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
-                                               LLVMBasicBlockRef BB) {
-  auto Point = unwrap(BB)->getFirstInsertionPt();
-  unwrap(B)->SetInsertPoint(unwrap(BB), Point);
-}
-
-extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
-                                  const char *Name, size_t NameLen) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
-  GlobalObject *GV = unwrap<GlobalObject>(V);
-  if (!TargetTriple.isOSBinFormatMachO()) {
-    StringRef NameRef(Name, NameLen);
-    GV->setComdat(unwrap(M)->getOrInsertComdat(NameRef));
-  }
-}
-
-extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
-  GlobalObject *GV = unwrap<GlobalObject>(V);
-  GV->setComdat(nullptr);
-}
-
-enum class LLVMRustLinkage {
-  ExternalLinkage = 0,
-  AvailableExternallyLinkage = 1,
-  LinkOnceAnyLinkage = 2,
-  LinkOnceODRLinkage = 3,
-  WeakAnyLinkage = 4,
-  WeakODRLinkage = 5,
-  AppendingLinkage = 6,
-  InternalLinkage = 7,
-  PrivateLinkage = 8,
-  ExternalWeakLinkage = 9,
-  CommonLinkage = 10,
-};
-
-static LLVMRustLinkage toRust(LLVMLinkage Linkage) {
-  switch (Linkage) {
-  case LLVMExternalLinkage:
-    return LLVMRustLinkage::ExternalLinkage;
-  case LLVMAvailableExternallyLinkage:
-    return LLVMRustLinkage::AvailableExternallyLinkage;
-  case LLVMLinkOnceAnyLinkage:
-    return LLVMRustLinkage::LinkOnceAnyLinkage;
-  case LLVMLinkOnceODRLinkage:
-    return LLVMRustLinkage::LinkOnceODRLinkage;
-  case LLVMWeakAnyLinkage:
-    return LLVMRustLinkage::WeakAnyLinkage;
-  case LLVMWeakODRLinkage:
-    return LLVMRustLinkage::WeakODRLinkage;
-  case LLVMAppendingLinkage:
-    return LLVMRustLinkage::AppendingLinkage;
-  case LLVMInternalLinkage:
-    return LLVMRustLinkage::InternalLinkage;
-  case LLVMPrivateLinkage:
-    return LLVMRustLinkage::PrivateLinkage;
-  case LLVMExternalWeakLinkage:
-    return LLVMRustLinkage::ExternalWeakLinkage;
-  case LLVMCommonLinkage:
-    return LLVMRustLinkage::CommonLinkage;
-  default:
-    report_fatal_error("Invalid LLVMRustLinkage value!");
-  }
-}
-
-static LLVMLinkage fromRust(LLVMRustLinkage Linkage) {
-  switch (Linkage) {
-  case LLVMRustLinkage::ExternalLinkage:
-    return LLVMExternalLinkage;
-  case LLVMRustLinkage::AvailableExternallyLinkage:
-    return LLVMAvailableExternallyLinkage;
-  case LLVMRustLinkage::LinkOnceAnyLinkage:
-    return LLVMLinkOnceAnyLinkage;
-  case LLVMRustLinkage::LinkOnceODRLinkage:
-    return LLVMLinkOnceODRLinkage;
-  case LLVMRustLinkage::WeakAnyLinkage:
-    return LLVMWeakAnyLinkage;
-  case LLVMRustLinkage::WeakODRLinkage:
-    return LLVMWeakODRLinkage;
-  case LLVMRustLinkage::AppendingLinkage:
-    return LLVMAppendingLinkage;
-  case LLVMRustLinkage::InternalLinkage:
-    return LLVMInternalLinkage;
-  case LLVMRustLinkage::PrivateLinkage:
-    return LLVMPrivateLinkage;
-  case LLVMRustLinkage::ExternalWeakLinkage:
-    return LLVMExternalWeakLinkage;
-  case LLVMRustLinkage::CommonLinkage:
-    return LLVMCommonLinkage;
-  }
-  report_fatal_error("Invalid LLVMRustLinkage value!");
-}
-
-extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
-  return toRust(LLVMGetLinkage(V));
-}
-
-extern "C" void LLVMRustSetLinkage(LLVMValueRef V,
-                                   LLVMRustLinkage RustLinkage) {
-  LLVMSetLinkage(V, fromRust(RustLinkage));
-}
-
-// Returns true if both high and low were successfully set. Fails in case constant wasn’t any of
-// the common sizes (1, 8, 16, 32, 64, 128 bits)
-extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *high, uint64_t *low)
-{
-    auto C = unwrap<llvm::ConstantInt>(CV);
-    if (C->getBitWidth() > 128) { return false; }
-    APInt AP;
-    if (sext) {
-        AP = C->getValue().sextOrSelf(128);
-    } else {
-        AP = C->getValue().zextOrSelf(128);
-    }
-    *low = AP.getLoBits(64).getZExtValue();
-    *high = AP.getHiBits(64).getZExtValue();
-    return true;
-}
-
-enum class LLVMRustVisibility {
-  Default = 0,
-  Hidden = 1,
-  Protected = 2,
-};
-
-static LLVMRustVisibility toRust(LLVMVisibility Vis) {
-  switch (Vis) {
-  case LLVMDefaultVisibility:
-    return LLVMRustVisibility::Default;
-  case LLVMHiddenVisibility:
-    return LLVMRustVisibility::Hidden;
-  case LLVMProtectedVisibility:
-    return LLVMRustVisibility::Protected;
-  }
-  report_fatal_error("Invalid LLVMRustVisibility value!");
-}
-
-static LLVMVisibility fromRust(LLVMRustVisibility Vis) {
-  switch (Vis) {
-  case LLVMRustVisibility::Default:
-    return LLVMDefaultVisibility;
-  case LLVMRustVisibility::Hidden:
-    return LLVMHiddenVisibility;
-  case LLVMRustVisibility::Protected:
-    return LLVMProtectedVisibility;
-  }
-  report_fatal_error("Invalid LLVMRustVisibility value!");
-}
-
-extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
-  return toRust(LLVMGetVisibility(V));
-}
-
-// Oh hey, a binding that makes sense for once? (because LLVM’s own do not)
-extern "C" LLVMValueRef LLVMRustBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
-                                             LLVMTypeRef DestTy, bool isSigned) {
-  return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), isSigned, ""));
-}
-
-extern "C" void LLVMRustSetVisibility(LLVMValueRef V,
-                                      LLVMRustVisibility RustVisibility) {
-  LLVMSetVisibility(V, fromRust(RustVisibility));
-}
-
-struct LLVMRustModuleBuffer {
-  std::string data;
-};
-
-extern "C" LLVMRustModuleBuffer*
-LLVMRustModuleBufferCreate(LLVMModuleRef M) {
-#if LLVM_VERSION_GE(10, 0)
-  auto Ret = std::make_unique<LLVMRustModuleBuffer>();
-#else
-  auto Ret = llvm::make_unique<LLVMRustModuleBuffer>();
-#endif
-  {
-    raw_string_ostream OS(Ret->data);
-    {
-      legacy::PassManager PM;
-      PM.add(createBitcodeWriterPass(OS));
-      PM.run(*unwrap(M));
-    }
-  }
-  return Ret.release();
-}
-
-extern "C" void
-LLVMRustModuleBufferFree(LLVMRustModuleBuffer *Buffer) {
-  delete Buffer;
-}
-
-extern "C" const void*
-LLVMRustModuleBufferPtr(const LLVMRustModuleBuffer *Buffer) {
-  return Buffer->data.data();
-}
-
-extern "C" size_t
-LLVMRustModuleBufferLen(const LLVMRustModuleBuffer *Buffer) {
-  return Buffer->data.length();
-}
-
-extern "C" uint64_t
-LLVMRustModuleCost(LLVMModuleRef M) {
-  auto f = unwrap(M)->functions();
-  return std::distance(std::begin(f), std::end(f));
-}
-
-// Vector reductions:
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateAddReduce(unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateMulReduce(unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateAndReduce(unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateOrReduce(unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) {
-    return wrap(unwrap(B)->CreateXorReduce(unwrap(Src)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
-    return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) {
-    return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
-   return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
-  return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
-}
-
-extern "C" LLVMValueRef
-LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
-    return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS)));
-}
-extern "C" LLVMValueRef
-LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) {
-    return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS)));
-}
diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h
deleted file mode 100644
index 57b8664d3b6..00000000000
--- a/src/rustllvm/rustllvm.h
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "llvm-c/BitReader.h"
-#include "llvm-c/Core.h"
-#include "llvm-c/Object.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Analysis/Lint.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Memory.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Vectorize.h"
-
-#define LLVM_VERSION_GE(major, minor)                                          \
-  (LLVM_VERSION_MAJOR > (major) ||                                             \
-   LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR >= (minor))
-
-#define LLVM_VERSION_EQ(major, minor)                                          \
-  (LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR == (minor))
-
-#define LLVM_VERSION_LE(major, minor)                                          \
-  (LLVM_VERSION_MAJOR < (major) ||                                             \
-   LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR <= (minor))
-
-#define LLVM_VERSION_LT(major, minor) (!LLVM_VERSION_GE((major), (minor)))
-
-#include "llvm/IR/LegacyPassManager.h"
-
-#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Bitcode/BitcodeWriter.h"
-
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/Linker/Linker.h"
-
-extern "C" void LLVMRustSetLastError(const char *);
-
-enum class LLVMRustResult { Success, Failure };
-
-enum LLVMRustAttribute {
-  AlwaysInline = 0,
-  ByVal = 1,
-  Cold = 2,
-  InlineHint = 3,
-  MinSize = 4,
-  Naked = 5,
-  NoAlias = 6,
-  NoCapture = 7,
-  NoInline = 8,
-  NonNull = 9,
-  NoRedZone = 10,
-  NoReturn = 11,
-  NoUnwind = 12,
-  OptimizeForSize = 13,
-  ReadOnly = 14,
-  SExt = 15,
-  StructRet = 16,
-  UWTable = 17,
-  ZExt = 18,
-  InReg = 19,
-  SanitizeThread = 20,
-  SanitizeAddress = 21,
-  SanitizeMemory = 22,
-  NonLazyBind = 23,
-  OptimizeNone = 24,
-  ReturnsTwice = 25,
-  ReadNone = 26,
-  InaccessibleMemOnly = 27,
-};
-
-typedef struct OpaqueRustString *RustStringRef;
-typedef struct LLVMOpaqueTwine *LLVMTwineRef;
-typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
-
-extern "C" void LLVMRustStringWriteImpl(RustStringRef Str, const char *Ptr,
-                                        size_t Size);
-
-class RawRustStringOstream : public llvm::raw_ostream {
-  RustStringRef Str;
-  uint64_t Pos;
-
-  void write_impl(const char *Ptr, size_t Size) override {
-    LLVMRustStringWriteImpl(Str, Ptr, Size);
-    Pos += Size;
-  }
-
-  uint64_t current_pos() const override { return Pos; }
-
-public:
-  explicit RawRustStringOstream(RustStringRef Str) : Str(Str), Pos(0) {}
-
-  ~RawRustStringOstream() {
-    // LLVM requires this.
-    flush();
-  }
-};
diff --git a/src/test/debuginfo/pretty-std-collections-hash.rs b/src/test/debuginfo/pretty-std-collections-hash.rs
index e8f52deabd8..9f59936a92d 100644
--- a/src/test/debuginfo/pretty-std-collections-hash.rs
+++ b/src/test/debuginfo/pretty-std-collections-hash.rs
@@ -1,3 +1,7 @@
+// CDB doesn't like how libstd.natvis casts to tuples before this version.
+// https://github.com/rust-lang/rust/issues/76352#issuecomment-687640746
+// min-cdb-version: 10.0.18362.1
+
 // cdb-only
 // compile-flags:-g
 
diff --git a/src/test/mir-opt/equal_true.opt.InstCombine.diff b/src/test/mir-opt/equal_true.opt.InstCombine.diff
new file mode 100644
index 00000000000..a26776e70d6
--- /dev/null
+++ b/src/test/mir-opt/equal_true.opt.InstCombine.diff
@@ -0,0 +1,35 @@
+- // MIR for `opt` before InstCombine
++ // MIR for `opt` after InstCombine
+  
+  fn opt(_1: bool) -> i32 {
+      debug x => _1;                       // in scope 0 at $DIR/equal_true.rs:3:8: 3:9
+      let mut _0: i32;                     // return place in scope 0 at $DIR/equal_true.rs:3:20: 3:23
+      let mut _2: bool;                    // in scope 0 at $DIR/equal_true.rs:4:8: 4:17
+      let mut _3: bool;                    // in scope 0 at $DIR/equal_true.rs:4:8: 4:9
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/equal_true.rs:4:8: 4:17
+          StorageLive(_3);                 // scope 0 at $DIR/equal_true.rs:4:8: 4:9
+          _3 = _1;                         // scope 0 at $DIR/equal_true.rs:4:8: 4:9
+-         _2 = Eq(move _3, const true);    // scope 0 at $DIR/equal_true.rs:4:8: 4:17
++         _2 = move _3;                    // scope 0 at $DIR/equal_true.rs:4:8: 4:17
+          StorageDead(_3);                 // scope 0 at $DIR/equal_true.rs:4:16: 4:17
+          switchInt(_2) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/equal_true.rs:4:5: 4:34
+      }
+  
+      bb1: {
+          _0 = const 1_i32;                // scope 0 at $DIR/equal_true.rs:4:31: 4:32
+          goto -> bb3;                     // scope 0 at $DIR/equal_true.rs:4:5: 4:34
+      }
+  
+      bb2: {
+          _0 = const 0_i32;                // scope 0 at $DIR/equal_true.rs:4:20: 4:21
+          goto -> bb3;                     // scope 0 at $DIR/equal_true.rs:4:5: 4:34
+      }
+  
+      bb3: {
+          StorageDead(_2);                 // scope 0 at $DIR/equal_true.rs:5:1: 5:2
+          return;                          // scope 0 at $DIR/equal_true.rs:5:2: 5:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/equal_true.rs b/src/test/mir-opt/equal_true.rs
new file mode 100644
index 00000000000..994cd194a45
--- /dev/null
+++ b/src/test/mir-opt/equal_true.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR equal_true.opt.InstCombine.diff
+
+fn opt(x: bool) -> i32 {
+    if x == true { 0 } else { 1 }
+}
+
+fn main() {
+    opt(true);
+}
diff --git a/src/test/mir-opt/graphviz.main.mir_map.0.dot b/src/test/mir-opt/graphviz.main.mir_map.0.dot
index f5d8b84812a..df4f11f0f21 100644
--- a/src/test/mir-opt/graphviz.main.mir_map.0.dot
+++ b/src/test/mir-opt/graphviz.main.mir_map.0.dot
@@ -1,7 +1,7 @@
 digraph Mir_0_3 {
-    graph [fontname="monospace"];
-    node [fontname="monospace"];
-    edge [fontname="monospace"];
+    graph [fontname="Courier, monospace"];
+    node [fontname="Courier, monospace"];
+    edge [fontname="Courier, monospace"];
     label=<fn main() -&gt; ()<br align="left"/>>;
     bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = const ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
     bb1__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>>];
diff --git a/src/test/mir-opt/inline/inline-compatibility.rs b/src/test/mir-opt/inline/inline-compatibility.rs
new file mode 100644
index 00000000000..ff9049edb4f
--- /dev/null
+++ b/src/test/mir-opt/inline/inline-compatibility.rs
@@ -0,0 +1,39 @@
+// Checks that only functions with compatible attributes are inlined.
+//
+// only-x86_64
+// needs-sanitizer-address
+// compile-flags: -Zsanitizer=address
+
+#![crate_type = "lib"]
+#![feature(no_sanitize)]
+#![feature(target_feature_11)]
+
+// EMIT_MIR inline_compatibility.inlined_target_feature.Inline.diff
+#[target_feature(enable = "sse2")]
+pub unsafe fn inlined_target_feature() {
+    target_feature();
+}
+
+// EMIT_MIR inline_compatibility.not_inlined_target_feature.Inline.diff
+pub unsafe fn not_inlined_target_feature() {
+    target_feature();
+}
+
+// EMIT_MIR inline_compatibility.inlined_no_sanitize.Inline.diff
+#[no_sanitize(address)]
+pub unsafe fn inlined_no_sanitize() {
+    no_sanitize();
+}
+
+// EMIT_MIR inline_compatibility.not_inlined_no_sanitize.Inline.diff
+pub unsafe fn not_inlined_no_sanitize() {
+    no_sanitize();
+}
+
+#[inline]
+#[target_feature(enable = "sse2")]
+pub unsafe fn target_feature() {}
+
+#[inline]
+#[no_sanitize(address, memory)]
+pub unsafe fn no_sanitize() {}
diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
new file mode 100644
index 00000000000..7b0ecaffdd7
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
@@ -0,0 +1,25 @@
+- // MIR for `inlined_no_sanitize` before Inline
++ // MIR for `inlined_no_sanitize` after Inline
+  
+  fn inlined_no_sanitize() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inline-compatibility.rs:24:37: 24:37
+      let _1: ();                          // in scope 0 at $DIR/inline-compatibility.rs:25:5: 25:18
++     scope 1 {
++     }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inline-compatibility.rs:25:5: 25:18
+-         _1 = no_sanitize() -> bb1;       // scope 0 at $DIR/inline-compatibility.rs:25:5: 25:18
+-                                          // mir::Constant
+-                                          // + span: $DIR/inline-compatibility.rs:25:5: 25:16
+-                                          // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(Scalar(<ZST>)) }
+-     }
+- 
+-     bb1: {
++         _1 = const ();                   // scope 1 at $DIR/inline-compatibility.rs:39:29: 39:31
+          StorageDead(_1);                 // scope 0 at $DIR/inline-compatibility.rs:25:18: 25:19
+          _0 = const ();                   // scope 0 at $DIR/inline-compatibility.rs:24:37: 26:2
+          return;                          // scope 0 at $DIR/inline-compatibility.rs:26:2: 26:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
new file mode 100644
index 00000000000..f55eae6c50a
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
@@ -0,0 +1,25 @@
+- // MIR for `inlined_target_feature` before Inline
++ // MIR for `inlined_target_feature` after Inline
+  
+  fn inlined_target_feature() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inline-compatibility.rs:13:40: 13:40
+      let _1: ();                          // in scope 0 at $DIR/inline-compatibility.rs:14:5: 14:21
++     scope 1 {
++     }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inline-compatibility.rs:14:5: 14:21
+-         _1 = target_feature() -> bb1;    // scope 0 at $DIR/inline-compatibility.rs:14:5: 14:21
+-                                          // mir::Constant
+-                                          // + span: $DIR/inline-compatibility.rs:14:5: 14:19
+-                                          // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(Scalar(<ZST>)) }
+-     }
+- 
+-     bb1: {
++         _1 = const ();                   // scope 1 at $DIR/inline-compatibility.rs:35:32: 35:34
+          StorageDead(_1);                 // scope 0 at $DIR/inline-compatibility.rs:14:21: 14:22
+          _0 = const ();                   // scope 0 at $DIR/inline-compatibility.rs:13:40: 15:2
+          return;                          // scope 0 at $DIR/inline-compatibility.rs:15:2: 15:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
new file mode 100644
index 00000000000..651eadc1e84
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
@@ -0,0 +1,22 @@
+- // MIR for `not_inlined_no_sanitize` before Inline
++ // MIR for `not_inlined_no_sanitize` after Inline
+  
+  fn not_inlined_no_sanitize() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inline-compatibility.rs:29:41: 29:41
+      let _1: ();                          // in scope 0 at $DIR/inline-compatibility.rs:30:5: 30:18
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inline-compatibility.rs:30:5: 30:18
+          _1 = no_sanitize() -> bb1;       // scope 0 at $DIR/inline-compatibility.rs:30:5: 30:18
+                                           // mir::Constant
+                                           // + span: $DIR/inline-compatibility.rs:30:5: 30:16
+                                           // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageDead(_1);                 // scope 0 at $DIR/inline-compatibility.rs:30:18: 30:19
+          _0 = const ();                   // scope 0 at $DIR/inline-compatibility.rs:29:41: 31:2
+          return;                          // scope 0 at $DIR/inline-compatibility.rs:31:2: 31:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
new file mode 100644
index 00000000000..55b9edf3adc
--- /dev/null
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
@@ -0,0 +1,22 @@
+- // MIR for `not_inlined_target_feature` before Inline
++ // MIR for `not_inlined_target_feature` after Inline
+  
+  fn not_inlined_target_feature() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inline-compatibility.rs:18:44: 18:44
+      let _1: ();                          // in scope 0 at $DIR/inline-compatibility.rs:19:5: 19:21
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inline-compatibility.rs:19:5: 19:21
+          _1 = target_feature() -> bb1;    // scope 0 at $DIR/inline-compatibility.rs:19:5: 19:21
+                                           // mir::Constant
+                                           // + span: $DIR/inline-compatibility.rs:19:5: 19:19
+                                           // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(Scalar(<ZST>)) }
+      }
+  
+      bb1: {
+          StorageDead(_1);                 // scope 0 at $DIR/inline-compatibility.rs:19:21: 19:22
+          _0 = const ();                   // scope 0 at $DIR/inline-compatibility.rs:18:44: 20:2
+          return;                          // scope 0 at $DIR/inline-compatibility.rs:20:2: 20:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff
new file mode 100644
index 00000000000..d8621b90ad8
--- /dev/null
+++ b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff
@@ -0,0 +1,72 @@
+- // MIR for `opt` before InstCombine
++ // MIR for `opt` after InstCombine
+  
+  fn opt(_1: Option<()>) -> bool {
+      debug x => _1;                       // in scope 0 at $DIR/not_equal_false.rs:3:8: 3:9
+      let mut _0: bool;                    // return place in scope 0 at $DIR/not_equal_false.rs:3:26: 3:30
+      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _3: isize;                   // in scope 0 at $DIR/not_equal_false.rs:4:17: 4:21
+      let mut _4: bool;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      let mut _5: isize;                   // in scope 0 at $DIR/not_equal_false.rs:4:38: 4:45
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _3 = discriminant(_1);           // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21
+          _2 = Eq(_3, const 0_isize);      // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          goto -> bb7;                     // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21
+      }
+  
+      bb1: {
+          _0 = const true;                 // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+          goto -> bb4;                     // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+      }
+  
+      bb2: {
+          _0 = const false;                // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+          goto -> bb4;                     // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+      }
+  
+      bb3: {
+          StorageLive(_4);                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          _5 = discriminant(_1);           // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45
+          _4 = Eq(_5, const 1_isize);      // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          goto -> bb10;                    // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45
+      }
+  
+      bb4: {
+          StorageDead(_4);                 // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46
+          StorageDead(_2);                 // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46
+          return;                          // scope 0 at $DIR/not_equal_false.rs:5:2: 5:2
+      }
+  
+      bb5: {
+          _2 = const false;                // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          goto -> bb7;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb6: {
+          _2 = const true;                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          goto -> bb7;                     // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb7: {
+          switchInt(move _2) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+      }
+  
+      bb8: {
+          _4 = const false;                // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          goto -> bb10;                    // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb9: {
+          _4 = const true;                 // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+          goto -> bb10;                    // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+      }
+  
+      bb10: {
+-         _0 = Ne(_4, const false);        // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
++         _0 = _4;                         // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+          goto -> bb4;                     // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46
+      }
+  }
+  
diff --git a/src/test/mir-opt/not_equal_false.rs b/src/test/mir-opt/not_equal_false.rs
new file mode 100644
index 00000000000..a98a2834e8e
--- /dev/null
+++ b/src/test/mir-opt/not_equal_false.rs
@@ -0,0 +1,9 @@
+// EMIT_MIR not_equal_false.opt.InstCombine.diff
+
+fn opt(x: Option<()>) -> bool {
+    matches!(x, None) || matches!(x, Some(_))
+}
+
+fn main() {
+    opt(None);
+}
diff --git a/src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff
index 869e3647f45..11f6b533741 100644
--- a/src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify_try_if_let.{{impl}}-append.SimplifyArmIdentity.diff
@@ -18,7 +18,8 @@
           debug tail => _4;                // in scope 1 at $DIR/simplify_try_if_let.rs:23:18: 23:26
           let _8: std::ptr::NonNull<Node>; // in scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
           scope 2 {
-              debug other_head => _8;      // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
+-             debug other_head => _8;      // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
++             debug other_head => ((_9 as Some).0: std::ptr::NonNull<Node>); // in scope 2 at $DIR/simplify_try_if_let.rs:26:29: 26:39
               scope 3 {
               }
           }
@@ -65,11 +66,12 @@
           StorageLive(_8);                 // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
           _8 = ((_5 as Some).0: std::ptr::NonNull<Node>); // scope 1 at $DIR/simplify_try_if_let.rs:26:29: 26:39
           StorageLive(_9);                 // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
-          StorageLive(_10);                // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
-          _10 = _8;                        // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
-          ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
-          discriminant(_9) = 1;            // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
-          StorageDead(_10);                // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
+-         StorageLive(_10);                // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
+-         _10 = _8;                        // scope 3 at $DIR/simplify_try_if_let.rs:28:51: 28:61
+-         ((_9 as Some).0: std::ptr::NonNull<Node>) = move _10; // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+-         discriminant(_9) = 1;            // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
+-         StorageDead(_10);                // scope 3 at $DIR/simplify_try_if_let.rs:28:61: 28:62
++         _9 = move _5;                    // scope 3 at $DIR/simplify_try_if_let.rs:28:46: 28:62
           StorageLive(_11);                // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:38
           StorageLive(_12);                // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
           _12 = &mut _4;                   // scope 3 at $DIR/simplify_try_if_let.rs:28:25: 28:29
diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.mir_map.0.html
index 7c1b7bc3b84..8f6b1307971 100644
--- a/src/test/mir-opt/spanview_block.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_block.main.mir_map.0.html
@@ -59,9 +59,9 @@
     </style>
 </head>
 <body>
-<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="bb0: $DIR/spanview-block.rs:5:11: 5:13:
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0: $DIR/spanview-block.rs:5:11: 5:13:
     5:11-5:13: Assign: _0 = const ()
-    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">@bb0:</span> {}</span></span><span><span class="code even" style="--layer: 1" title="bb2: $DIR/spanview-block.rs:5:13: 5:13:
-    5:13-5:13: Return: return"><span class="annotation">@bb2</span></span></span></span></div>
+    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">0⦊</span>{}<span class="annotation">⦉0</span></span></span><span><span class="code odd" style="--layer: 1" title="2: $DIR/spanview-block.rs:5:13: 5:13:
+    5:13-5:13: Return: return"><span class="annotation">2⦊</span>‸<span class="annotation">⦉2</span></span></span></span></div>
 </body>
 </html>
diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.mir_map.0.html
index f8662a3277a..072d22473a9 100644
--- a/src/test/mir-opt/spanview_statement.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_statement.main.mir_map.0.html
@@ -59,9 +59,9 @@
     </style>
 </head>
 <body>
-<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="bb0[0]: $DIR/spanview-statement.rs:5:11: 5:13:
-    5:11-5:13: Assign: _0 = const ()"><span class="annotation">@bb0[0]:</span> {}</span></span><span><span class="code even" style="--layer: 1" title="bb0`Goto`: $DIR/spanview-statement.rs:5:13: 5:13:
-    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">@bb0`Goto`</span></span></span><span><span class="code even" style="--layer: 1" title="bb2`Return`: $DIR/spanview-statement.rs:5:13: 5:13:
-    5:13-5:13: Return: return"><span class="annotation">@bb2`Return`</span></span></span></span></div>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0[0]: $DIR/spanview-statement.rs:5:11: 5:13:
+    5:11-5:13: Assign: _0 = const ()"><span class="annotation">0[0]⦊</span>{}<span class="annotation">⦉0[0]</span></span></span><span><span class="code odd" style="--layer: 1" title="0:Goto: $DIR/spanview-statement.rs:5:13: 5:13:
+    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">0:Goto⦊</span>‸<span class="annotation">⦉0:Goto</span></span></span><span><span class="code even" style="--layer: 1" title="2:Return: $DIR/spanview-statement.rs:5:13: 5:13:
+    5:13-5:13: Return: return"><span class="annotation">2:Return⦊</span>‸<span class="annotation">⦉2:Return</span></span></span></span></div>
 </body>
 </html>
diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
index d0a11a8d262..e023f0f8aea 100644
--- a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
@@ -59,8 +59,8 @@
     </style>
 </head>
 <body>
-<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="bb0`Goto`: $DIR/spanview-terminator.rs:5:13: 5:13:
-    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">@bb0`Goto`</span></span></span><span><span class="code even" style="--layer: 1" title="bb2`Return`: $DIR/spanview-terminator.rs:5:13: 5:13:
-    5:13-5:13: Return: return"><span class="annotation">@bb2`Return`</span></span></span></span></div>
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="0:Goto: $DIR/spanview-terminator.rs:5:13: 5:13:
+    5:13-5:13: Goto: goto -&gt; bb2"><span class="annotation">0:Goto⦊</span>‸<span class="annotation">⦉0:Goto</span></span></span><span><span class="code odd" style="--layer: 1" title="2:Return: $DIR/spanview-terminator.rs:5:13: 5:13:
+    5:13-5:13: Return: return"><span class="annotation">2:Return⦊</span>‸<span class="annotation">⦉2:Return</span></span></span></span></div>
 </body>
 </html>
diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile
index a16b4f61dcb..cb081fb641b 100644
--- a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile
+++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-base/Makefile
@@ -1,4 +1,8 @@
 # needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 # ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and
 # `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`.
diff --git a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile
index 08f311f1702..ab826d07e05 100644
--- a/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile
+++ b/src/test/run-make-fulldeps/instrument-coverage-cov-reports-link-dead-code/Makefile
@@ -1,5 +1,9 @@
 # needs-profiler-support
 # ignore-msvc
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 # LINK_DEAD_CODE requires ignore-msvc due to Issue #76038
 LINK_DEAD_CODE=yes
@@ -8,4 +12,4 @@ LINK_DEAD_CODE=yes
 
 # ISSUE(76038): When targeting MSVC, Rust binaries built with both `-Z instrument-coverage` and
 # `-C link-dead-code` typically crash (with a seg-fault) or at best generate an empty `*.profraw`.
-# See ../instrument-coverage/coverage_tools.mk for more information.
\ No newline at end of file
+# See ../instrument-coverage/coverage_tools.mk for more information.
diff --git a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html
index faa5d65e7e7..1ea9aba488e 100644
--- a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html
+++ b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-base/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html
@@ -62,12 +62,12 @@
 <div class="code" style="counter-reset: line 2"><span class="line"><span class="code" style="--layer: 0">fn main() {</span></span>
 <span class="line"><span class="code" style="--layer: 0">    let mut countdown = 0;</span></span>
 <span class="line"><span class="code" style="--layer: 0">    </span><span><span class="code even" style="--layer: 1" title="bb2: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
-    5:5-7:6: FalseEdge: falseEdge -&gt; [real: bb4, imaginary: bb3]"><span class="annotation">@2</span></span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: FalseEdge: falseEdge -&gt; [real: bb4, imaginary: bb3]"><span class="annotation">2⦊</span></span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     6:9-6:23: Assign: _1 = const 10_i32
     5:13-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">@4</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">4⦊</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">@3:</span> if </span><span class="code even" style="--layer: 4" title="bb0: ../instrument-coverage/coverage_of_if_else.rs:5:8: 5:12:
+    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">3⦊</span>if </span><span class="code even" style="--layer: 4" title="bb0: ../instrument-coverage/coverage_of_if_else.rs:5:8: 5:12:
     4:9-4:22: StorageLive: StorageLive(_1)
     4:25-4:26: Assign: _1 = const 0_i32
     4:9-4:22: FakeRead: FakeRead(ForLet, _1)
@@ -75,25 +75,29 @@
     5:8-5:12: StorageLive: StorageLive(_3)
     5:8-5:12: Assign: _3 = const true
     5:8-5:12: FakeRead: FakeRead(ForMatchedPlace, _3)
-    5:5-7:6: SwitchInt: switchInt(_3) -&gt; [false: bb3, otherwise: bb2]"><span class="annotation">@0:</span> true</span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: SwitchInt: switchInt(_3) -&gt; [false: bb3, otherwise: bb2]"><span class="annotation">0⦊</span>true<span class="annotation">⦉0</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">@3:</span>  {</span></span>
+    5:5-7:6: Goto: goto -&gt; bb5"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
     5:5-7:6: Goto: goto -&gt; bb5">        countdown = 10;</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5">    }</span><span class="code" style="--layer: 0"></span></span>
+    5:5-7:6: Goto: goto -&gt; bb5">    }<span class="annotation">⦉3</span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    6:9-6:23: Assign: _1 = const 10_i32
+    5:13-7:6: Assign: _2 = const ()
+    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">⦉4</span></span><span><span class="code even" style="--layer: 1" title="bb2: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: FalseEdge: falseEdge -&gt; [real: bb4, imaginary: bb3]"><span class="annotation">⦉2</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="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
-    9:5-18:6: FalseEdge: falseEdge -&gt; [real: bb8, imaginary: bb7]"><span class="annotation">@6</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+<span class="line"><span class="code" style="--layer: 0">    </span><span><span class="code odd" style="--layer: 1" title="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: FalseEdge: falseEdge -&gt; [real: bb8, imaginary: bb7]"><span class="annotation">6⦊</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     10:9-10:23: Assign: _1 = move (_7.0: i32)
     9:22-11:6: Assign: _4 = const ()
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@9</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">9⦊</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@25:</span> if </span><span class="code even" style="--layer: 4" title="bb5: ../instrument-coverage/coverage_of_if_else.rs:9:8: 9:21:
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">25⦊</span>if </span><span class="code even" style="--layer: 4" title="bb5: ../instrument-coverage/coverage_of_if_else.rs:9:8: 9:21:
     7:5-7:6: StorageDead: StorageDead(_3)
     7:5-7:6: StorageDead: StorageDead(_2)
     9:5-18:6: StorageLive: StorageLive(_4)
@@ -103,61 +107,61 @@
     9:8-9:21: Assign: _5 = Gt(move _6, const 7_i32)
     9:20-9:21: StorageDead: StorageDead(_6)
     9:8-9:21: FakeRead: FakeRead(ForMatchedPlace, _5)
-    9:5-18:6: SwitchInt: switchInt(_5) -&gt; [false: bb7, otherwise: bb6]"><span class="annotation">@5:</span> countdown &gt; 7</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: SwitchInt: switchInt(_5) -&gt; [false: bb7, otherwise: bb6]"><span class="annotation">5⦊</span>countdown &gt; 7<span class="annotation">⦉5</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@25:</span>  {</span></span>
+    9:5-18:6: Goto: goto -&gt; bb28"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     9:5-18:6: Goto: goto -&gt; bb28">        </span><span class="code odd" style="--layer: 4" title="bb8: ../instrument-coverage/coverage_of_if_else.rs:10:9: 10:23:
     10:9-10:23: Assign: _7 = CheckedSub(_1, const 4_i32)
-    10:9-10:23: Assert: assert(!move (_7.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 4_i32) -&gt; [success: bb9, unwind: bb1]"><span class="annotation">@8:</span> countdown -= 4</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    10:9-10:23: Assert: assert(!move (_7.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 4_i32) -&gt; [success: bb9, unwind: bb1]"><span class="annotation">8⦊</span>countdown -= 4<span class="annotation">⦉8</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@25:</span> ;</span></span>
+    9:5-18:6: Goto: goto -&gt; bb28">;</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     9:5-18:6: Goto: goto -&gt; bb28">    } else </span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
-    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> if </span><span class="code even" style="--layer: 5" title="bb7: ../instrument-coverage/coverage_of_if_else.rs:11:15: 11:28:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">10⦊</span>if </span><span class="code even" style="--layer: 5" title="bb7: ../instrument-coverage/coverage_of_if_else.rs:11:15: 11:28:
     11:15-11:28: StorageLive: StorageLive(_8)
     11:15-11:24: StorageLive: StorageLive(_9)
     11:15-11:24: Assign: _9 = _1
     11:15-11:28: Assign: _8 = Gt(move _9, const 2_i32)
     11:27-11:28: StorageDead: StorageDead(_9)
     11:15-11:28: FakeRead: FakeRead(ForMatchedPlace, _8)
-    11:12-18:6: SwitchInt: switchInt(_8) -&gt; [false: bb11, otherwise: bb10]"><span class="annotation">@7:</span> countdown &gt; 2</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
-    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span>  {</span></span>
+    11:12-18:6: SwitchInt: switchInt(_8) -&gt; [false: bb11, otherwise: bb10]"><span class="annotation">7⦊</span>countdown &gt; 2<span class="annotation">⦉7</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
     11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">        </span><span class="code odd" style="--layer: 5" title="bb22: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
     12:9-14:10: Assign: _10 = const ()
-    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">@22</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">22⦊</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
     13:13-13:26: Assign: _1 = const 0_i32
     12:61-14:10: Assign: _10 = const ()
-    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">@23</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
-    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span> if </span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">23⦊</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">21⦊</span>if </span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:12-12:60: Assign: _11 = const false
-    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">@14</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">14⦊</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:46-12:60: StorageLive: StorageLive(_17)
     12:46-12:55: StorageLive: StorageLive(_18)
     12:46-12:55: Assign: _18 = _1
     12:46-12:60: Assign: _17 = Ne(move _18, const 9_i32)
     12:59-12:60: StorageDead: StorageDead(_18)
-    12:12-12:60: SwitchInt: switchInt(move _17) -&gt; [false: bb14, otherwise: bb13]"><span class="annotation">@15</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: SwitchInt: switchInt(move _17) -&gt; [false: bb14, otherwise: bb13]"><span class="annotation">15⦊</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:59-12:60: StorageDead: StorageDead(_17)
     12:59-12:60: StorageDead: StorageDead(_12)
     12:12-12:60: FakeRead: FakeRead(ForMatchedPlace, _11)
-    12:9-14:10: SwitchInt: switchInt(_11) -&gt; [false: bb22, otherwise: bb21]"><span class="annotation">@16</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:9-14:10: SwitchInt: switchInt(_11) -&gt; [false: bb22, otherwise: bb21]"><span class="annotation">16⦊</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:12-12:60: Assign: _11 = const true
-    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">@13</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">13⦊</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:41-12:42: StorageDead: StorageDead(_15)
     12:41-12:42: StorageDead: StorageDead(_13)
-    12:12-12:60: SwitchInt: switchInt(move _12) -&gt; [false: bb15, otherwise: bb13]"><span class="annotation">@20</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: SwitchInt: switchInt(move _12) -&gt; [false: bb15, otherwise: bb13]"><span class="annotation">20⦊</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:9-14:10: StorageLive: StorageLive(_10)
     12:12-12:60: StorageLive: StorageLive(_11)
     12:12-12:42: StorageLive: StorageLive(_12)
@@ -166,17 +170,25 @@
     12:12-12:21: Assign: _14 = _1
     12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32)
     12:24-12:25: StorageDead: StorageDead(_14)
-    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"><span class="annotation">@12</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"><span class="annotation">12⦊</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
     12:12-12:42: Assign: _12 = const false
-    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">@18</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">18⦊</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
     12:29-12:42: StorageLive: StorageLive(_15)
     12:29-12:38: StorageLive: StorageLive(_16)
     12:29-12:38: Assign: _16 = _1
     12:29-12:42: Assign: _15 = Gt(move _16, const 5_i32)
     12:41-12:42: StorageDead: StorageDead(_16)
-    12:12-12:42: SwitchInt: switchInt(move _15) -&gt; [false: bb18, otherwise: bb17]"><span class="annotation">@19</span></span><span class="code even" style="--layer: 16" title="bb17: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: SwitchInt: switchInt(move _15) -&gt; [false: bb18, otherwise: bb17]"><span class="annotation">19⦊</span></span><span class="code even" style="--layer: 16" title="bb17: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
     12:12-12:42: Assign: _12 = const true
-    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">@17:</span> countdown &lt; 1 || countdown &gt; 5</span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">17⦊</span>countdown &lt; 1 || countdown &gt; 5<span class="annotation">⦉17</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:29-12:42: StorageLive: StorageLive(_15)
+    12:29-12:38: StorageLive: StorageLive(_16)
+    12:29-12:38: Assign: _16 = _1
+    12:29-12:42: Assign: _15 = Gt(move _16, const 5_i32)
+    12:41-12:42: StorageDead: StorageDead(_16)
+    12:12-12:42: SwitchInt: switchInt(move _15) -&gt; [false: bb18, otherwise: bb17]"><span class="annotation">⦉19</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: Assign: _12 = const false
+    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">⦉18</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:9-14:10: StorageLive: StorageLive(_10)
     12:12-12:60: StorageLive: StorageLive(_11)
     12:12-12:42: StorageLive: StorageLive(_12)
@@ -185,8 +197,25 @@
     12:12-12:21: Assign: _14 = _1
     12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32)
     12:24-12:25: StorageDead: StorageDead(_14)
-    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"><span class="annotation">@12:</span>  || countdown != 9</span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
-    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span>  {</span></span>
+    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"> || countdown != 9<span class="annotation">⦉12</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:41-12:42: StorageDead: StorageDead(_15)
+    12:41-12:42: StorageDead: StorageDead(_13)
+    12:12-12:60: SwitchInt: switchInt(move _12) -&gt; [false: bb15, otherwise: bb13]"><span class="annotation">⦉20</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Assign: _11 = const true
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">⦉13</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:59-12:60: StorageDead: StorageDead(_17)
+    12:59-12:60: StorageDead: StorageDead(_12)
+    12:12-12:60: FakeRead: FakeRead(ForMatchedPlace, _11)
+    12:9-14:10: SwitchInt: switchInt(_11) -&gt; [false: bb22, otherwise: bb21]"><span class="annotation">⦉16</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:46-12:60: StorageLive: StorageLive(_17)
+    12:46-12:55: StorageLive: StorageLive(_18)
+    12:46-12:55: Assign: _18 = _1
+    12:46-12:60: Assign: _17 = Ne(move _18, const 9_i32)
+    12:59-12:60: StorageDead: StorageDead(_18)
+    12:12-12:60: SwitchInt: switchInt(move _17) -&gt; [false: bb14, otherwise: bb13]"><span class="annotation">⦉15</span></span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Assign: _11 = const false
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">⦉14</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
     12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]">            countdown = 0;</span></span>
 <span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
@@ -194,32 +223,67 @@
     14:9-14:10: StorageDead: StorageDead(_11)
     14:9-14:10: StorageDead: StorageDead(_10)
     15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32)
-    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]"><span class="annotation">@24:</span> }</span></span>
+    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]"><span class="annotation">24⦊</span>}</span><span class="code odd" style="--layer: 5" title="bb22: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: Assign: _10 = const ()
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">⦉22</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    13:13-13:26: Assign: _1 = const 0_i32
+    12:61-14:10: Assign: _10 = const ()
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">⦉23</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">⦉21</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">⦉21</span></span><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23:
+    14:9-14:10: StorageDead: StorageDead(_11)
+    14:9-14:10: StorageDead: StorageDead(_10)
+    15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32)
+    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]"></span></span>
 <span class="line"><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23:
     14:9-14:10: StorageDead: StorageDead(_11)
     14:9-14:10: StorageDead: StorageDead(_10)
     15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32)
-    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]">        countdown -= 5</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
-    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> ;</span></span>
+    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]">        countdown -= 5<span class="annotation">⦉24</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">;</span></span>
 <span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
     11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">    } else {</span></span>
 <span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
     11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">        </span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
-    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">@27</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
+    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">27⦊</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
     17:9-17:15: Assign: _0 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     18:5-18:6: StorageDead: StorageDead(_5)
     18:5-18:6: StorageDead: StorageDead(_4)
-    17:9-17:15: Goto: goto -&gt; bb27"><span class="annotation">@11:</span> return;</span></span>
+    17:9-17:15: Goto: goto -&gt; bb27"><span class="annotation">11⦊</span>return;</span></span>
 <span class="line"><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
     17:9-17:15: Assign: _0 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     18:5-18:6: StorageDead: StorageDead(_5)
     18:5-18:6: StorageDead: StorageDead(_4)
-    17:9-17:15: Goto: goto -&gt; bb27">    }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
+    17:9-17:15: Goto: goto -&gt; bb27">    }<span class="annotation">⦉11</span></span><span><span class="code odd" style="--layer: 1" title="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: FalseEdge: falseEdge -&gt; [real: bb8, imaginary: bb7]"><span class="annotation">⦉6</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    10:9-10:23: Assign: _1 = move (_7.0: i32)
+    9:22-11:6: Assign: _4 = const ()
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉9</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    15:9-15:23: Assign: _1 = move (_19.0: i32)
+    11:29-16:6: Assign: _4 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉25</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    15:9-15:23: Assign: _1 = move (_19.0: i32)
+    11:29-16:6: Assign: _4 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉25</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    15:9-15:23: Assign: _1 = move (_19.0: i32)
+    11:29-16:6: Assign: _4 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉25</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">⦉10</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">⦉10</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">⦉10</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
+    17:9-17:15: Assign: _0 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    18:5-18:6: StorageDead: StorageDead(_5)
+    18:5-18:6: StorageDead: StorageDead(_4)
+    17:9-17:15: Goto: goto -&gt; bb27"><span class="annotation">⦉11</span></span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
-    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">@27:</span> </span></span>
+    17:9-17:15: Goto: goto -&gt; bb26"></span></span>
 <span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26"></span></span>
@@ -230,11 +294,11 @@
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26">    </span><span class="code odd" style="--layer: 6" title="bb30: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
     21:5-23:6: Assign: _22 = const ()
-    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">@30</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">30⦊</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
     22:9-22:23: Assign: _21 = const 10_i32
     21:13-23:6: Assign: _22 = const ()
-    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">@31</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
-    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span> if </span><span class="code even" style="--layer: 9" title="bb28: ../instrument-coverage/coverage_of_if_else.rs:21:8: 21:12:
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">31⦊</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"><span class="annotation">29⦊</span>if </span><span class="code even" style="--layer: 9" title="bb28: ../instrument-coverage/coverage_of_if_else.rs:21:8: 21:12:
     18:5-18:6: StorageDead: StorageDead(_5)
     18:5-18:6: StorageDead: StorageDead(_4)
     20:9-20:22: StorageLive: StorageLive(_21)
@@ -244,28 +308,33 @@
     21:8-21:12: StorageLive: StorageLive(_23)
     21:8-21:12: Assign: _23 = const true
     21:8-21:12: FakeRead: FakeRead(ForMatchedPlace, _23)
-    21:5-23:6: SwitchInt: switchInt(_23) -&gt; [false: bb30, otherwise: bb29]"><span class="annotation">@28:</span> true</span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
-    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span>  {</span></span>
+    21:5-23:6: SwitchInt: switchInt(_23) -&gt; [false: bb30, otherwise: bb29]"><span class="annotation">28⦊</span>true<span class="annotation">⦉28</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
     21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]">        countdown = 10;</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
-    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]">    }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
+    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]">    }<span class="annotation">⦉29</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    22:9-22:23: Assign: _21 = const 10_i32
+    21:13-23:6: Assign: _22 = const ()
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">⦉31</span></span><span class="code odd" style="--layer: 6" title="bb30: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: Assign: _22 = const ()
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">⦉30</span></span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
-    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">@27:</span> </span></span>
+    17:9-17:15: Goto: goto -&gt; bb26"></span></span>
 <span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26"></span></span>
 <span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26">    </span><span class="code even" style="--layer: 6" title="bb33: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
-    25:5-34:6: FalseEdge: falseEdge -&gt; [real: bb35, imaginary: bb34]"><span class="annotation">@33</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: FalseEdge: falseEdge -&gt; [real: bb35, imaginary: bb34]"><span class="annotation">33⦊</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     31:9-31:23: Assign: _21 = move (_39.0: i32)
     27:29-32:6: Assign: _24 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@52</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">52⦊</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@36:</span> if </span><span class="code even" style="--layer: 9" title="bb32: ../instrument-coverage/coverage_of_if_else.rs:25:8: 25:21:
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">36⦊</span>if </span><span class="code even" style="--layer: 9" title="bb32: ../instrument-coverage/coverage_of_if_else.rs:25:8: 25:21:
     23:5-23:6: StorageDead: StorageDead(_23)
     23:5-23:6: StorageDead: StorageDead(_22)
     25:5-34:6: StorageLive: StorageLive(_24)
@@ -275,40 +344,40 @@
     25:8-25:21: Assign: _25 = Gt(move _26, const 7_i32)
     25:20-25:21: StorageDead: StorageDead(_26)
     25:8-25:21: FakeRead: FakeRead(ForMatchedPlace, _25)
-    25:5-34:6: SwitchInt: switchInt(_25) -&gt; [false: bb34, otherwise: bb33]"><span class="annotation">@32:</span> countdown &gt; 7</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: SwitchInt: switchInt(_25) -&gt; [false: bb34, otherwise: bb33]"><span class="annotation">32⦊</span>countdown &gt; 7<span class="annotation">⦉32</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@36:</span>  {</span></span>
+    25:5-34:6: Goto: goto -&gt; bb53"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
     25:5-34:6: Goto: goto -&gt; bb53">        </span><span class="code odd" style="--layer: 9" title="bb35: ../instrument-coverage/coverage_of_if_else.rs:26:9: 26:23:
     26:9-26:23: Assign: _27 = CheckedSub(_21, const 4_i32)
-    26:9-26:23: Assert: assert(!move (_27.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 4_i32) -&gt; [success: bb36, unwind: bb1]"><span class="annotation">@35:</span> countdown -= 4</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assert: assert(!move (_27.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 4_i32) -&gt; [success: bb36, unwind: bb1]"><span class="annotation">35⦊</span>countdown -= 4<span class="annotation">⦉35</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@36:</span> ;</span></span>
+    25:5-34:6: Goto: goto -&gt; bb53">;</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
     25:5-34:6: Goto: goto -&gt; bb53">    } else </span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
-    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> if </span><span class="code even" style="--layer: 10" title="bb34: ../instrument-coverage/coverage_of_if_else.rs:27:15: 27:28:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">37⦊</span>if </span><span class="code even" style="--layer: 10" title="bb34: ../instrument-coverage/coverage_of_if_else.rs:27:15: 27:28:
     27:15-27:28: StorageLive: StorageLive(_28)
     27:15-27:24: StorageLive: StorageLive(_29)
     27:15-27:24: Assign: _29 = _21
     27:15-27:28: Assign: _28 = Gt(move _29, const 2_i32)
     27:27-27:28: StorageDead: StorageDead(_29)
     27:15-27:28: FakeRead: FakeRead(ForMatchedPlace, _28)
-    27:12-34:6: SwitchInt: switchInt(_28) -&gt; [false: bb38, otherwise: bb37]"><span class="annotation">@34:</span> countdown &gt; 2</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
-    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span>  {</span></span>
+    27:12-34:6: SwitchInt: switchInt(_28) -&gt; [false: bb38, otherwise: bb37]"><span class="annotation">34⦊</span>countdown &gt; 2<span class="annotation">⦉34</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
     27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]">        </span><span class="code odd" style="--layer: 10" title="bb48: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
-    28:9-30:10: FalseEdge: falseEdge -&gt; [real: bb50, imaginary: bb49]"><span class="annotation">@48</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: FalseEdge: falseEdge -&gt; [real: bb50, imaginary: bb49]"><span class="annotation">48⦊</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     29:13-29:26: Assign: _21 = const 0_i32
     28:61-30:10: Assign: _30 = const ()
-    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">@50</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">50⦊</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     28:9-30:10: Assign: _30 = const ()
-    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">@49:</span> if </span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">49⦊</span>if </span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:9-30:10: StorageLive: StorageLive(_30)
     28:12-28:60: StorageLive: StorageLive(_31)
     28:12-28:42: StorageLive: StorageLive(_32)
@@ -317,38 +386,70 @@
     28:12-28:21: Assign: _34 = _21
     28:12-28:25: Assign: _33 = Lt(move _34, const 1_i32)
     28:24-28:25: StorageDead: StorageDead(_34)
-    28:12-28:42: SwitchInt: switchInt(move _33) -&gt; [false: bb46, otherwise: bb44]"><span class="annotation">@39</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:42: SwitchInt: switchInt(move _33) -&gt; [false: bb46, otherwise: bb44]"><span class="annotation">39⦊</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:41-28:42: StorageDead: StorageDead(_35)
     28:41-28:42: StorageDead: StorageDead(_33)
-    28:12-28:60: SwitchInt: switchInt(move _32) -&gt; [false: bb42, otherwise: bb40]"><span class="annotation">@47</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: SwitchInt: switchInt(move _32) -&gt; [false: bb42, otherwise: bb40]"><span class="annotation">47⦊</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:12-28:60: Assign: _31 = const true
-    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">@40</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">40⦊</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:59-28:60: StorageDead: StorageDead(_37)
     28:59-28:60: StorageDead: StorageDead(_32)
     28:12-28:60: FakeRead: FakeRead(ForMatchedPlace, _31)
-    28:9-30:10: SwitchInt: switchInt(_31) -&gt; [false: bb49, otherwise: bb48]"><span class="annotation">@43</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:9-30:10: SwitchInt: switchInt(_31) -&gt; [false: bb49, otherwise: bb48]"><span class="annotation">43⦊</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:46-28:60: StorageLive: StorageLive(_37)
     28:46-28:55: StorageLive: StorageLive(_38)
     28:46-28:55: Assign: _38 = _21
     28:46-28:60: Assign: _37 = Ne(move _38, const 9_i32)
     28:59-28:60: StorageDead: StorageDead(_38)
-    28:12-28:60: SwitchInt: switchInt(move _37) -&gt; [false: bb41, otherwise: bb40]"><span class="annotation">@42</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: SwitchInt: switchInt(move _37) -&gt; [false: bb41, otherwise: bb40]"><span class="annotation">42⦊</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:12-28:60: Assign: _31 = const false
-    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">@41</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">41⦊</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
     28:29-28:42: StorageLive: StorageLive(_35)
     28:29-28:38: StorageLive: StorageLive(_36)
     28:29-28:38: Assign: _36 = _21
     28:29-28:42: Assign: _35 = Gt(move _36, const 5_i32)
     28:41-28:42: StorageDead: StorageDead(_36)
-    28:12-28:42: SwitchInt: switchInt(move _35) -&gt; [false: bb45, otherwise: bb44]"><span class="annotation">@46</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:42: SwitchInt: switchInt(move _35) -&gt; [false: bb45, otherwise: bb44]"><span class="annotation">46⦊</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
     28:12-28:42: Assign: _32 = const false
-    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">@45</span></span><span class="code even" style="--layer: 21" title="bb44: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">45⦊</span></span><span class="code even" style="--layer: 21" title="bb44: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
     28:12-28:42: Assign: _32 = const true
-    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">@44:</span> countdown &lt; 1 || countdown &gt; 5</span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">44⦊</span>countdown &lt; 1 || countdown &gt; 5<span class="annotation">⦉44</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:42: Assign: _32 = const false
+    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">⦉45</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:29-28:42: StorageLive: StorageLive(_35)
+    28:29-28:38: StorageLive: StorageLive(_36)
+    28:29-28:38: Assign: _36 = _21
+    28:29-28:42: Assign: _35 = Gt(move _36, const 5_i32)
+    28:41-28:42: StorageDead: StorageDead(_36)
+    28:12-28:42: SwitchInt: switchInt(move _35) -&gt; [false: bb45, otherwise: bb44]"><span class="annotation">⦉46</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:12-28:60: Assign: _31 = const false
-    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">@41:</span>  || countdown != 9</span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:12-28:60: Goto: goto -&gt; bb43"> || countdown != 9<span class="annotation">⦉41</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:46-28:60: StorageLive: StorageLive(_37)
+    28:46-28:55: StorageLive: StorageLive(_38)
+    28:46-28:55: Assign: _38 = _21
+    28:46-28:60: Assign: _37 = Ne(move _38, const 9_i32)
+    28:59-28:60: StorageDead: StorageDead(_38)
+    28:12-28:60: SwitchInt: switchInt(move _37) -&gt; [false: bb41, otherwise: bb40]"><span class="annotation">⦉42</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:59-28:60: StorageDead: StorageDead(_37)
+    28:59-28:60: StorageDead: StorageDead(_32)
+    28:12-28:60: FakeRead: FakeRead(ForMatchedPlace, _31)
+    28:9-30:10: SwitchInt: switchInt(_31) -&gt; [false: bb49, otherwise: bb48]"><span class="annotation">⦉43</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: Assign: _31 = const true
+    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">⦉40</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:41-28:42: StorageDead: StorageDead(_35)
+    28:41-28:42: StorageDead: StorageDead(_33)
+    28:12-28:60: SwitchInt: switchInt(move _32) -&gt; [false: bb42, otherwise: bb40]"><span class="annotation">⦉47</span></span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:9-30:10: StorageLive: StorageLive(_30)
+    28:12-28:60: StorageLive: StorageLive(_31)
+    28:12-28:42: StorageLive: StorageLive(_32)
+    28:12-28:25: StorageLive: StorageLive(_33)
+    28:12-28:21: StorageLive: StorageLive(_34)
+    28:12-28:21: Assign: _34 = _21
+    28:12-28:25: Assign: _33 = Lt(move _34, const 1_i32)
+    28:24-28:25: StorageDead: StorageDead(_34)
+    28:12-28:42: SwitchInt: switchInt(move _33) -&gt; [false: bb46, otherwise: bb44]"><span class="annotation">⦉39</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     28:9-30:10: Assign: _30 = const ()
-    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">@49:</span>  {</span></span>
+    28:9-30:10: Goto: goto -&gt; bb51"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     28:9-30:10: Assign: _30 = const ()
     28:9-30:10: Goto: goto -&gt; bb51">            countdown = 0;</span></span>
@@ -358,13 +459,25 @@
     30:9-30:10: StorageDead: StorageDead(_31)
     30:9-30:10: StorageDead: StorageDead(_30)
     31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32)
-    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]"><span class="annotation">@51:</span> }</span></span>
+    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]"><span class="annotation">51⦊</span>}</span><span class="code odd" style="--layer: 10" title="bb48: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: FalseEdge: falseEdge -&gt; [real: bb50, imaginary: bb49]"><span class="annotation">⦉48</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    29:13-29:26: Assign: _21 = const 0_i32
+    28:61-30:10: Assign: _30 = const ()
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">⦉50</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: Assign: _30 = const ()
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">⦉49</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: Assign: _30 = const ()
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">⦉49</span></span><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23:
+    30:9-30:10: StorageDead: StorageDead(_31)
+    30:9-30:10: StorageDead: StorageDead(_30)
+    31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32)
+    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]"></span></span>
 <span class="line"><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23:
     30:9-30:10: StorageDead: StorageDead(_31)
     30:9-30:10: StorageDead: StorageDead(_30)
     31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32)
-    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]">        countdown -= 5</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
-    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> ;</span></span>
+    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]">        countdown -= 5<span class="annotation">⦉51</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]">;</span></span>
 <span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
     27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]">    } else {</span></span>
 <span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
@@ -374,14 +487,37 @@
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     51:1-51:2: StorageDead: StorageDead(_21)
-    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">@38:</span> return;</span></span>
+    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">38⦊</span>return;</span></span>
 <span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     51:1-51:2: StorageDead: StorageDead(_21)
-    33:9-33:15: Goto: goto -&gt; bb27">    }</span></span>
+    33:9-33:15: Goto: goto -&gt; bb27">    }</span><span class="code even" style="--layer: 6" title="bb33: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: FalseEdge: falseEdge -&gt; [real: bb35, imaginary: bb34]"><span class="annotation">⦉33</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    31:9-31:23: Assign: _21 = move (_39.0: i32)
+    27:29-32:6: Assign: _24 = const ()
+    34:5-34:6: StorageDead: StorageDead(_28)
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉52</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assign: _21 = move (_27.0: i32)
+    25:22-27:6: Assign: _24 = const ()
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉36</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assign: _21 = move (_27.0: i32)
+    25:22-27:6: Assign: _24 = const ()
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉36</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assign: _21 = move (_27.0: i32)
+    25:22-27:6: Assign: _24 = const ()
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉36</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">⦉37</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">⦉37</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">⦉37</span></span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
+    33:9-33:15: Assign: _0 = const ()
+    34:5-34:6: StorageDead: StorageDead(_28)
+    34:5-34:6: StorageDead: StorageDead(_25)
+    34:5-34:6: StorageDead: StorageDead(_24)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    33:9-33:15: Goto: goto -&gt; bb27"></span></span>
 <span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
@@ -405,10 +541,10 @@
     33:9-33:15: Goto: goto -&gt; bb27">    </span><span class="code even" style="--layer: 11" title="bb56: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     38:9-38:23: Assign: _41 = const 10_i32
     37:13-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">@56</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
-    37:5-39:6: FalseEdge: falseEdge -&gt; [real: bb56, imaginary: bb55]"><span class="annotation">@54</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">56⦊</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: FalseEdge: falseEdge -&gt; [real: bb56, imaginary: bb55]"><span class="annotation">54⦊</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">@55:</span> if </span><span class="code even" style="--layer: 14" title="bb53: ../instrument-coverage/coverage_of_if_else.rs:37:8: 37:12:
+    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">55⦊</span>if </span><span class="code even" style="--layer: 14" title="bb53: ../instrument-coverage/coverage_of_if_else.rs:37:8: 37:12:
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     36:9-36:22: StorageLive: StorageLive(_41)
@@ -418,21 +554,25 @@
     37:8-37:12: StorageLive: StorageLive(_43)
     37:8-37:12: Assign: _43 = const true
     37:8-37:12: FakeRead: FakeRead(ForMatchedPlace, _43)
-    37:5-39:6: SwitchInt: switchInt(_43) -&gt; [false: bb55, otherwise: bb54]"><span class="annotation">@53:</span> true</span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: SwitchInt: switchInt(_43) -&gt; [false: bb55, otherwise: bb54]"><span class="annotation">53⦊</span>true<span class="annotation">⦉53</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">@55:</span>  {</span></span>
+    37:5-39:6: Goto: goto -&gt; bb57"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
     37:5-39:6: Goto: goto -&gt; bb57">        countdown = 10;</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57">    }</span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
+    37:5-39:6: Goto: goto -&gt; bb57">    }<span class="annotation">⦉55</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: FalseEdge: falseEdge -&gt; [real: bb56, imaginary: bb55]"><span class="annotation">⦉54</span></span><span class="code even" style="--layer: 11" title="bb56: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    38:9-38:23: Assign: _41 = const 10_i32
+    37:13-39:6: Assign: _42 = const ()
+    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">⦉56</span></span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     51:1-51:2: StorageDead: StorageDead(_21)
-    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">@38:</span> </span></span>
+    33:9-33:15: Goto: goto -&gt; bb27"></span></span>
 <span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
@@ -449,12 +589,12 @@
     33:9-33:15: Goto: goto -&gt; bb27">    </span><span class="code odd" style="--layer: 11" title="bb61: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     42:9-42:23: Assign: _41 = move (_46.0: i32)
     41:22-43:6: Assign: _0 = const ()
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@61</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
-    41:5-50:6: FalseEdge: falseEdge -&gt; [real: bb60, imaginary: bb59]"><span class="annotation">@58</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">61⦊</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: FalseEdge: falseEdge -&gt; [real: bb60, imaginary: bb59]"><span class="annotation">58⦊</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@77:</span> if </span><span class="code even" style="--layer: 14" title="bb57: ../instrument-coverage/coverage_of_if_else.rs:41:8: 41:21:
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">77⦊</span>if </span><span class="code even" style="--layer: 14" title="bb57: ../instrument-coverage/coverage_of_if_else.rs:41:8: 41:21:
     39:5-39:6: StorageDead: StorageDead(_43)
     39:5-39:6: StorageDead: StorageDead(_42)
     41:8-41:21: StorageLive: StorageLive(_44)
@@ -463,59 +603,59 @@
     41:8-41:21: Assign: _44 = Gt(move _45, const 7_i32)
     41:20-41:21: StorageDead: StorageDead(_45)
     41:8-41:21: FakeRead: FakeRead(ForMatchedPlace, _44)
-    41:5-50:6: SwitchInt: switchInt(_44) -&gt; [false: bb59, otherwise: bb58]"><span class="annotation">@57:</span> countdown &gt; 7</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: SwitchInt: switchInt(_44) -&gt; [false: bb59, otherwise: bb58]"><span class="annotation">57⦊</span>countdown &gt; 7<span class="annotation">⦉57</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@77:</span>  {</span></span>
+    41:5-50:6: Goto: goto -&gt; bb78"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
     41:5-50:6: Goto: goto -&gt; bb78">        </span><span class="code odd" style="--layer: 14" title="bb60: ../instrument-coverage/coverage_of_if_else.rs:42:9: 42:23:
     42:9-42:23: Assign: _46 = CheckedSub(_41, const 4_i32)
-    42:9-42:23: Assert: assert(!move (_46.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 4_i32) -&gt; [success: bb61, unwind: bb1]"><span class="annotation">@60:</span> countdown -= 4</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    42:9-42:23: Assert: assert(!move (_46.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 4_i32) -&gt; [success: bb61, unwind: bb1]"><span class="annotation">60⦊</span>countdown -= 4<span class="annotation">⦉60</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@77:</span> ;</span></span>
+    41:5-50:6: Goto: goto -&gt; bb78">;</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
     41:5-50:6: Goto: goto -&gt; bb78">    } else </span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
-    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> if </span><span class="code even" style="--layer: 15" title="bb59: ../instrument-coverage/coverage_of_if_else.rs:43:15: 43:28:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">62⦊</span>if </span><span class="code even" style="--layer: 15" title="bb59: ../instrument-coverage/coverage_of_if_else.rs:43:15: 43:28:
     43:15-43:28: StorageLive: StorageLive(_47)
     43:15-43:24: StorageLive: StorageLive(_48)
     43:15-43:24: Assign: _48 = _41
     43:15-43:28: Assign: _47 = Gt(move _48, const 2_i32)
     43:27-43:28: StorageDead: StorageDead(_48)
     43:15-43:28: FakeRead: FakeRead(ForMatchedPlace, _47)
-    43:12-50:6: SwitchInt: switchInt(_47) -&gt; [false: bb63, otherwise: bb62]"><span class="annotation">@59:</span> countdown &gt; 2</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
-    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span>  {</span></span>
+    43:12-50:6: SwitchInt: switchInt(_47) -&gt; [false: bb63, otherwise: bb62]"><span class="annotation">59⦊</span>countdown &gt; 2<span class="annotation">⦉59</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
     43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]">        </span><span class="code odd" style="--layer: 15" title="bb75: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
     45:13-45:26: Assign: _41 = const 0_i32
     44:61-46:10: Assign: _49 = const ()
-    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">@75</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">75⦊</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
     44:9-46:10: Assign: _49 = const ()
-    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">@74</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
-    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span> if </span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">74⦊</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">73⦊</span>if </span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:46-44:60: StorageLive: StorageLive(_56)
     44:46-44:55: StorageLive: StorageLive(_57)
     44:46-44:55: Assign: _57 = _41
     44:46-44:60: Assign: _56 = Ne(move _57, const 9_i32)
     44:59-44:60: StorageDead: StorageDead(_57)
-    44:12-44:60: SwitchInt: switchInt(move _56) -&gt; [false: bb66, otherwise: bb65]"><span class="annotation">@67</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: SwitchInt: switchInt(move _56) -&gt; [false: bb66, otherwise: bb65]"><span class="annotation">67⦊</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:59-44:60: StorageDead: StorageDead(_56)
     44:59-44:60: StorageDead: StorageDead(_51)
     44:12-44:60: FakeRead: FakeRead(ForMatchedPlace, _50)
-    44:9-46:10: SwitchInt: switchInt(_50) -&gt; [false: bb74, otherwise: bb73]"><span class="annotation">@68</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:9-46:10: SwitchInt: switchInt(_50) -&gt; [false: bb74, otherwise: bb73]"><span class="annotation">68⦊</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:12-44:60: Assign: _50 = const true
-    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">@65</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">65⦊</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:41-44:42: StorageDead: StorageDead(_54)
     44:41-44:42: StorageDead: StorageDead(_52)
-    44:12-44:60: SwitchInt: switchInt(move _51) -&gt; [false: bb67, otherwise: bb65]"><span class="annotation">@72</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: SwitchInt: switchInt(move _51) -&gt; [false: bb67, otherwise: bb65]"><span class="annotation">72⦊</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:9-46:10: StorageLive: StorageLive(_49)
     44:12-44:60: StorageLive: StorageLive(_50)
     44:12-44:42: StorageLive: StorageLive(_51)
@@ -524,22 +664,54 @@
     44:12-44:21: Assign: _53 = _41
     44:12-44:25: Assign: _52 = Lt(move _53, const 1_i32)
     44:24-44:25: StorageDead: StorageDead(_53)
-    44:12-44:42: SwitchInt: switchInt(move _52) -&gt; [false: bb71, otherwise: bb69]"><span class="annotation">@64</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:42: SwitchInt: switchInt(move _52) -&gt; [false: bb71, otherwise: bb69]"><span class="annotation">64⦊</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:12-44:60: Assign: _50 = const false
-    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">@66</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">66⦊</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
     44:12-44:42: Assign: _51 = const true
-    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">@69</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">69⦊</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
     44:29-44:42: StorageLive: StorageLive(_54)
     44:29-44:38: StorageLive: StorageLive(_55)
     44:29-44:38: Assign: _55 = _41
     44:29-44:42: Assign: _54 = Gt(move _55, const 5_i32)
     44:41-44:42: StorageDead: StorageDead(_55)
-    44:12-44:42: SwitchInt: switchInt(move _54) -&gt; [false: bb70, otherwise: bb69]"><span class="annotation">@71</span></span><span class="code even" style="--layer: 26" title="bb70: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:42: SwitchInt: switchInt(move _54) -&gt; [false: bb70, otherwise: bb69]"><span class="annotation">71⦊</span></span><span class="code even" style="--layer: 26" title="bb70: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
     44:12-44:42: Assign: _51 = const false
-    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">@70:</span> countdown &lt; 1 || countdown &gt; 5</span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">70⦊</span>countdown &lt; 1 || countdown &gt; 5<span class="annotation">⦉70</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:29-44:42: StorageLive: StorageLive(_54)
+    44:29-44:38: StorageLive: StorageLive(_55)
+    44:29-44:38: Assign: _55 = _41
+    44:29-44:42: Assign: _54 = Gt(move _55, const 5_i32)
+    44:41-44:42: StorageDead: StorageDead(_55)
+    44:12-44:42: SwitchInt: switchInt(move _54) -&gt; [false: bb70, otherwise: bb69]"><span class="annotation">⦉71</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:42: Assign: _51 = const true
+    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">⦉69</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:12-44:60: Assign: _50 = const false
-    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">@66:</span>  || countdown != 9</span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
-    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span>  {</span></span>
+    44:12-44:60: Goto: goto -&gt; bb68"> || countdown != 9<span class="annotation">⦉66</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:9-46:10: StorageLive: StorageLive(_49)
+    44:12-44:60: StorageLive: StorageLive(_50)
+    44:12-44:42: StorageLive: StorageLive(_51)
+    44:12-44:25: StorageLive: StorageLive(_52)
+    44:12-44:21: StorageLive: StorageLive(_53)
+    44:12-44:21: Assign: _53 = _41
+    44:12-44:25: Assign: _52 = Lt(move _53, const 1_i32)
+    44:24-44:25: StorageDead: StorageDead(_53)
+    44:12-44:42: SwitchInt: switchInt(move _52) -&gt; [false: bb71, otherwise: bb69]"><span class="annotation">⦉64</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:41-44:42: StorageDead: StorageDead(_54)
+    44:41-44:42: StorageDead: StorageDead(_52)
+    44:12-44:60: SwitchInt: switchInt(move _51) -&gt; [false: bb67, otherwise: bb65]"><span class="annotation">⦉72</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: Assign: _50 = const true
+    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">⦉65</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:59-44:60: StorageDead: StorageDead(_56)
+    44:59-44:60: StorageDead: StorageDead(_51)
+    44:12-44:60: FakeRead: FakeRead(ForMatchedPlace, _50)
+    44:9-46:10: SwitchInt: switchInt(_50) -&gt; [false: bb74, otherwise: bb73]"><span class="annotation">⦉68</span></span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:46-44:60: StorageLive: StorageLive(_56)
+    44:46-44:55: StorageLive: StorageLive(_57)
+    44:46-44:55: Assign: _57 = _41
+    44:46-44:60: Assign: _56 = Ne(move _57, const 9_i32)
+    44:59-44:60: StorageDead: StorageDead(_57)
+    44:12-44:60: SwitchInt: switchInt(move _56) -&gt; [false: bb66, otherwise: bb65]"><span class="annotation">⦉67</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
     44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]">            countdown = 0;</span></span>
 <span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
@@ -547,13 +719,24 @@
     46:9-46:10: StorageDead: StorageDead(_50)
     46:9-46:10: StorageDead: StorageDead(_49)
     47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32)
-    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]"><span class="annotation">@76:</span> }</span></span>
+    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]"><span class="annotation">76⦊</span>}</span><span class="code odd" style="--layer: 15" title="bb75: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    45:13-45:26: Assign: _41 = const 0_i32
+    44:61-46:10: Assign: _49 = const ()
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">⦉75</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: Assign: _49 = const ()
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">⦉74</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">⦉73</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">⦉73</span></span><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23:
+    46:9-46:10: StorageDead: StorageDead(_50)
+    46:9-46:10: StorageDead: StorageDead(_49)
+    47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32)
+    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]"></span></span>
 <span class="line"><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23:
     46:9-46:10: StorageDead: StorageDead(_50)
     46:9-46:10: StorageDead: StorageDead(_49)
     47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32)
-    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]">        countdown -= 5</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
-    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> ;</span></span>
+    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]">        countdown -= 5<span class="annotation">⦉76</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]">;</span></span>
 <span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
     43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]">    } else {</span></span>
 <span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
@@ -564,7 +747,7 @@
     51:1-51:2: StorageDead: StorageDead(_21)
     51:1-51:2: StorageDead: StorageDead(_1)
     51:1-51:2: StorageDead: StorageDead(_44)
-    49:9-49:15: Goto: goto -&gt; bb26"><span class="annotation">@63:</span> return;</span></span>
+    49:9-49:15: Goto: goto -&gt; bb26"><span class="annotation">63⦊</span>return;</span></span>
 <span class="line"><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2:
     49:9-49:15: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
@@ -572,12 +755,54 @@
     51:1-51:2: StorageDead: StorageDead(_21)
     51:1-51:2: StorageDead: StorageDead(_1)
     51:1-51:2: StorageDead: StorageDead(_44)
-    49:9-49:15: Goto: goto -&gt; bb26">    }</span><span class="code even" style="--layer: 16" title="bb78: ../instrument-coverage/coverage_of_if_else.rs:51:1: 51:2:
+    49:9-49:15: Goto: goto -&gt; bb26">    }</span><span class="code odd" style="--layer: 11" title="bb61: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    42:9-42:23: Assign: _41 = move (_46.0: i32)
+    41:22-43:6: Assign: _0 = const ()
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉61</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: FalseEdge: falseEdge -&gt; [real: bb60, imaginary: bb59]"><span class="annotation">⦉58</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    47:9-47:23: Assign: _41 = move (_58.0: i32)
+    43:29-48:6: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉77</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    47:9-47:23: Assign: _41 = move (_58.0: i32)
+    43:29-48:6: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉77</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    47:9-47:23: Assign: _41 = move (_58.0: i32)
+    43:29-48:6: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉77</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">⦉62</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">⦉62</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">⦉62</span></span><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2:
+    49:9-49:15: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    51:1-51:2: StorageDead: StorageDead(_41)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    51:1-51:2: StorageDead: StorageDead(_1)
+    51:1-51:2: StorageDead: StorageDead(_44)
+    49:9-49:15: Goto: goto -&gt; bb26"></span></span>
+<span class="line"><span class="code even" style="--layer: 16" title="bb78: ../instrument-coverage/coverage_of_if_else.rs:51:1: 51:2:
     51:1-51:2: StorageDead: StorageDead(_41)
     51:1-51:2: StorageDead: StorageDead(_21)
     51:1-51:2: StorageDead: StorageDead(_1)
     51:1-51:2: StorageDead: StorageDead(_44)
-    51:2-51:2: Goto: goto -&gt; bb26"><span class="annotation">@78:</span> }</span><span><span class="code even" style="--layer: 1" title="bb26: ../instrument-coverage/coverage_of_if_else.rs:51:2: 51:2:
-    51:2-51:2: Return: return"><span class="annotation">@26</span></span></span></span></div>
+    51:2-51:2: Goto: goto -&gt; bb26"><span class="annotation">78⦊</span>}<span class="annotation">⦉78</span></span><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2:
+    49:9-49:15: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    51:1-51:2: StorageDead: StorageDead(_41)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    51:1-51:2: StorageDead: StorageDead(_1)
+    51:1-51:2: StorageDead: StorageDead(_44)
+    49:9-49:15: Goto: goto -&gt; bb26"><span class="annotation">⦉63</span></span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
+    33:9-33:15: Assign: _0 = const ()
+    34:5-34:6: StorageDead: StorageDead(_28)
+    34:5-34:6: StorageDead: StorageDead(_25)
+    34:5-34:6: StorageDead: StorageDead(_24)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">⦉38</span></span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
+    51:1-51:2: StorageDead: StorageDead(_1)
+    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">⦉27</span></span><span><span class="code even" style="--layer: 1" title="bb26: ../instrument-coverage/coverage_of_if_else.rs:51:2: 51:2:
+    51:2-51:2: Return: return"><span class="annotation">26⦊</span>‸<span class="annotation">⦉26</span></span></span></span></div>
 </body>
 </html>
diff --git a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html
index faa5d65e7e7..1ea9aba488e 100644
--- a/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html
+++ b/src/test/run-make-fulldeps/instrument-coverage-mir-cov-html-link-dead-code/expected_mir_dump.coverage_of_if_else/coverage_of_if_else.main.-------.InstrumentCoverage.0.html
@@ -62,12 +62,12 @@
 <div class="code" style="counter-reset: line 2"><span class="line"><span class="code" style="--layer: 0">fn main() {</span></span>
 <span class="line"><span class="code" style="--layer: 0">    let mut countdown = 0;</span></span>
 <span class="line"><span class="code" style="--layer: 0">    </span><span><span class="code even" style="--layer: 1" title="bb2: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
-    5:5-7:6: FalseEdge: falseEdge -&gt; [real: bb4, imaginary: bb3]"><span class="annotation">@2</span></span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: FalseEdge: falseEdge -&gt; [real: bb4, imaginary: bb3]"><span class="annotation">2⦊</span></span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     6:9-6:23: Assign: _1 = const 10_i32
     5:13-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">@4</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">4⦊</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">@3:</span> if </span><span class="code even" style="--layer: 4" title="bb0: ../instrument-coverage/coverage_of_if_else.rs:5:8: 5:12:
+    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">3⦊</span>if </span><span class="code even" style="--layer: 4" title="bb0: ../instrument-coverage/coverage_of_if_else.rs:5:8: 5:12:
     4:9-4:22: StorageLive: StorageLive(_1)
     4:25-4:26: Assign: _1 = const 0_i32
     4:9-4:22: FakeRead: FakeRead(ForLet, _1)
@@ -75,25 +75,29 @@
     5:8-5:12: StorageLive: StorageLive(_3)
     5:8-5:12: Assign: _3 = const true
     5:8-5:12: FakeRead: FakeRead(ForMatchedPlace, _3)
-    5:5-7:6: SwitchInt: switchInt(_3) -&gt; [false: bb3, otherwise: bb2]"><span class="annotation">@0:</span> true</span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: SwitchInt: switchInt(_3) -&gt; [false: bb3, otherwise: bb2]"><span class="annotation">0⦊</span>true<span class="annotation">⦉0</span></span><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">@3:</span>  {</span></span>
+    5:5-7:6: Goto: goto -&gt; bb5"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
     5:5-7:6: Goto: goto -&gt; bb5">        countdown = 10;</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb3: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
     5:5-7:6: Assign: _2 = const ()
-    5:5-7:6: Goto: goto -&gt; bb5">    }</span><span class="code" style="--layer: 0"></span></span>
+    5:5-7:6: Goto: goto -&gt; bb5">    }<span class="annotation">⦉3</span></span><span class="code even" style="--layer: 2" title="bb4: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    6:9-6:23: Assign: _1 = const 10_i32
+    5:13-7:6: Assign: _2 = const ()
+    5:5-7:6: Goto: goto -&gt; bb5"><span class="annotation">⦉4</span></span><span><span class="code even" style="--layer: 1" title="bb2: ../instrument-coverage/coverage_of_if_else.rs:5:5: 7:6:
+    5:5-7:6: FalseEdge: falseEdge -&gt; [real: bb4, imaginary: bb3]"><span class="annotation">⦉2</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="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
-    9:5-18:6: FalseEdge: falseEdge -&gt; [real: bb8, imaginary: bb7]"><span class="annotation">@6</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+<span class="line"><span class="code" style="--layer: 0">    </span><span><span class="code odd" style="--layer: 1" title="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: FalseEdge: falseEdge -&gt; [real: bb8, imaginary: bb7]"><span class="annotation">6⦊</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     10:9-10:23: Assign: _1 = move (_7.0: i32)
     9:22-11:6: Assign: _4 = const ()
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@9</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">9⦊</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@25:</span> if </span><span class="code even" style="--layer: 4" title="bb5: ../instrument-coverage/coverage_of_if_else.rs:9:8: 9:21:
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">25⦊</span>if </span><span class="code even" style="--layer: 4" title="bb5: ../instrument-coverage/coverage_of_if_else.rs:9:8: 9:21:
     7:5-7:6: StorageDead: StorageDead(_3)
     7:5-7:6: StorageDead: StorageDead(_2)
     9:5-18:6: StorageLive: StorageLive(_4)
@@ -103,61 +107,61 @@
     9:8-9:21: Assign: _5 = Gt(move _6, const 7_i32)
     9:20-9:21: StorageDead: StorageDead(_6)
     9:8-9:21: FakeRead: FakeRead(ForMatchedPlace, _5)
-    9:5-18:6: SwitchInt: switchInt(_5) -&gt; [false: bb7, otherwise: bb6]"><span class="annotation">@5:</span> countdown &gt; 7</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: SwitchInt: switchInt(_5) -&gt; [false: bb7, otherwise: bb6]"><span class="annotation">5⦊</span>countdown &gt; 7<span class="annotation">⦉5</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@25:</span>  {</span></span>
+    9:5-18:6: Goto: goto -&gt; bb28"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     9:5-18:6: Goto: goto -&gt; bb28">        </span><span class="code odd" style="--layer: 4" title="bb8: ../instrument-coverage/coverage_of_if_else.rs:10:9: 10:23:
     10:9-10:23: Assign: _7 = CheckedSub(_1, const 4_i32)
-    10:9-10:23: Assert: assert(!move (_7.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 4_i32) -&gt; [success: bb9, unwind: bb1]"><span class="annotation">@8:</span> countdown -= 4</span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    10:9-10:23: Assert: assert(!move (_7.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 4_i32) -&gt; [success: bb9, unwind: bb1]"><span class="annotation">8⦊</span>countdown -= 4<span class="annotation">⦉8</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
-    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">@25:</span> ;</span></span>
+    9:5-18:6: Goto: goto -&gt; bb28">;</span></span>
 <span class="line"><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
     15:9-15:23: Assign: _1 = move (_19.0: i32)
     11:29-16:6: Assign: _4 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     9:5-18:6: Goto: goto -&gt; bb28">    } else </span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
-    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> if </span><span class="code even" style="--layer: 5" title="bb7: ../instrument-coverage/coverage_of_if_else.rs:11:15: 11:28:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">10⦊</span>if </span><span class="code even" style="--layer: 5" title="bb7: ../instrument-coverage/coverage_of_if_else.rs:11:15: 11:28:
     11:15-11:28: StorageLive: StorageLive(_8)
     11:15-11:24: StorageLive: StorageLive(_9)
     11:15-11:24: Assign: _9 = _1
     11:15-11:28: Assign: _8 = Gt(move _9, const 2_i32)
     11:27-11:28: StorageDead: StorageDead(_9)
     11:15-11:28: FakeRead: FakeRead(ForMatchedPlace, _8)
-    11:12-18:6: SwitchInt: switchInt(_8) -&gt; [false: bb11, otherwise: bb10]"><span class="annotation">@7:</span> countdown &gt; 2</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
-    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span>  {</span></span>
+    11:12-18:6: SwitchInt: switchInt(_8) -&gt; [false: bb11, otherwise: bb10]"><span class="annotation">7⦊</span>countdown &gt; 2<span class="annotation">⦉7</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
     11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">        </span><span class="code odd" style="--layer: 5" title="bb22: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
     12:9-14:10: Assign: _10 = const ()
-    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">@22</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">22⦊</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
     13:13-13:26: Assign: _1 = const 0_i32
     12:61-14:10: Assign: _10 = const ()
-    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">@23</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
-    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span> if </span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">23⦊</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">21⦊</span>if </span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:12-12:60: Assign: _11 = const false
-    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">@14</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">14⦊</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:46-12:60: StorageLive: StorageLive(_17)
     12:46-12:55: StorageLive: StorageLive(_18)
     12:46-12:55: Assign: _18 = _1
     12:46-12:60: Assign: _17 = Ne(move _18, const 9_i32)
     12:59-12:60: StorageDead: StorageDead(_18)
-    12:12-12:60: SwitchInt: switchInt(move _17) -&gt; [false: bb14, otherwise: bb13]"><span class="annotation">@15</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: SwitchInt: switchInt(move _17) -&gt; [false: bb14, otherwise: bb13]"><span class="annotation">15⦊</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:59-12:60: StorageDead: StorageDead(_17)
     12:59-12:60: StorageDead: StorageDead(_12)
     12:12-12:60: FakeRead: FakeRead(ForMatchedPlace, _11)
-    12:9-14:10: SwitchInt: switchInt(_11) -&gt; [false: bb22, otherwise: bb21]"><span class="annotation">@16</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:9-14:10: SwitchInt: switchInt(_11) -&gt; [false: bb22, otherwise: bb21]"><span class="annotation">16⦊</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:12-12:60: Assign: _11 = const true
-    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">@13</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">13⦊</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:41-12:42: StorageDead: StorageDead(_15)
     12:41-12:42: StorageDead: StorageDead(_13)
-    12:12-12:60: SwitchInt: switchInt(move _12) -&gt; [false: bb15, otherwise: bb13]"><span class="annotation">@20</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: SwitchInt: switchInt(move _12) -&gt; [false: bb15, otherwise: bb13]"><span class="annotation">20⦊</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:9-14:10: StorageLive: StorageLive(_10)
     12:12-12:60: StorageLive: StorageLive(_11)
     12:12-12:42: StorageLive: StorageLive(_12)
@@ -166,17 +170,25 @@
     12:12-12:21: Assign: _14 = _1
     12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32)
     12:24-12:25: StorageDead: StorageDead(_14)
-    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"><span class="annotation">@12</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"><span class="annotation">12⦊</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
     12:12-12:42: Assign: _12 = const false
-    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">@18</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">18⦊</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
     12:29-12:42: StorageLive: StorageLive(_15)
     12:29-12:38: StorageLive: StorageLive(_16)
     12:29-12:38: Assign: _16 = _1
     12:29-12:42: Assign: _15 = Gt(move _16, const 5_i32)
     12:41-12:42: StorageDead: StorageDead(_16)
-    12:12-12:42: SwitchInt: switchInt(move _15) -&gt; [false: bb18, otherwise: bb17]"><span class="annotation">@19</span></span><span class="code even" style="--layer: 16" title="bb17: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: SwitchInt: switchInt(move _15) -&gt; [false: bb18, otherwise: bb17]"><span class="annotation">19⦊</span></span><span class="code even" style="--layer: 16" title="bb17: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
     12:12-12:42: Assign: _12 = const true
-    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">@17:</span> countdown &lt; 1 || countdown &gt; 5</span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">17⦊</span>countdown &lt; 1 || countdown &gt; 5<span class="annotation">⦉17</span></span><span class="code even" style="--layer: 15" title="bb19: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:29-12:42: StorageLive: StorageLive(_15)
+    12:29-12:38: StorageLive: StorageLive(_16)
+    12:29-12:38: Assign: _16 = _1
+    12:29-12:42: Assign: _15 = Gt(move _16, const 5_i32)
+    12:41-12:42: StorageDead: StorageDead(_16)
+    12:12-12:42: SwitchInt: switchInt(move _15) -&gt; [false: bb18, otherwise: bb17]"><span class="annotation">⦉19</span></span><span class="code even" style="--layer: 14" title="bb18: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:42:
+    12:12-12:42: Assign: _12 = const false
+    12:12-12:42: Goto: goto -&gt; bb20"><span class="annotation">⦉18</span></span><span class="code even" style="--layer: 13" title="bb12: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
     12:9-14:10: StorageLive: StorageLive(_10)
     12:12-12:60: StorageLive: StorageLive(_11)
     12:12-12:42: StorageLive: StorageLive(_12)
@@ -185,8 +197,25 @@
     12:12-12:21: Assign: _14 = _1
     12:12-12:25: Assign: _13 = Lt(move _14, const 1_i32)
     12:24-12:25: StorageDead: StorageDead(_14)
-    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"><span class="annotation">@12:</span>  || countdown != 9</span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
-    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">@21:</span>  {</span></span>
+    12:12-12:42: SwitchInt: switchInt(move _13) -&gt; [false: bb19, otherwise: bb17]"> || countdown != 9<span class="annotation">⦉12</span></span><span class="code even" style="--layer: 12" title="bb20: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:41-12:42: StorageDead: StorageDead(_15)
+    12:41-12:42: StorageDead: StorageDead(_13)
+    12:12-12:60: SwitchInt: switchInt(move _12) -&gt; [false: bb15, otherwise: bb13]"><span class="annotation">⦉20</span></span><span class="code even" style="--layer: 11" title="bb13: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Assign: _11 = const true
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">⦉13</span></span><span class="code even" style="--layer: 10" title="bb16: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:59-12:60: StorageDead: StorageDead(_17)
+    12:59-12:60: StorageDead: StorageDead(_12)
+    12:12-12:60: FakeRead: FakeRead(ForMatchedPlace, _11)
+    12:9-14:10: SwitchInt: switchInt(_11) -&gt; [false: bb22, otherwise: bb21]"><span class="annotation">⦉16</span></span><span class="code even" style="--layer: 9" title="bb15: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:46-12:60: StorageLive: StorageLive(_17)
+    12:46-12:55: StorageLive: StorageLive(_18)
+    12:46-12:55: Assign: _18 = _1
+    12:46-12:60: Assign: _17 = Ne(move _18, const 9_i32)
+    12:59-12:60: StorageDead: StorageDead(_18)
+    12:12-12:60: SwitchInt: switchInt(move _17) -&gt; [false: bb14, otherwise: bb13]"><span class="annotation">⦉15</span></span><span class="code even" style="--layer: 8" title="bb14: ../instrument-coverage/coverage_of_if_else.rs:12:12: 12:60:
+    12:12-12:60: Assign: _11 = const false
+    12:12-12:60: Goto: goto -&gt; bb16"><span class="annotation">⦉14</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
     12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]">            countdown = 0;</span></span>
 <span class="line"><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
@@ -194,32 +223,67 @@
     14:9-14:10: StorageDead: StorageDead(_11)
     14:9-14:10: StorageDead: StorageDead(_10)
     15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32)
-    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]"><span class="annotation">@24:</span> }</span></span>
+    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]"><span class="annotation">24⦊</span>}</span><span class="code odd" style="--layer: 5" title="bb22: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: Assign: _10 = const ()
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">⦉22</span></span><span class="code even" style="--layer: 6" title="bb23: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    13:13-13:26: Assign: _1 = const 0_i32
+    12:61-14:10: Assign: _10 = const ()
+    12:9-14:10: Goto: goto -&gt; bb24"><span class="annotation">⦉23</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">⦉21</span></span><span class="code even" style="--layer: 7" title="bb21: ../instrument-coverage/coverage_of_if_else.rs:12:9: 14:10:
+    12:9-14:10: FalseEdge: falseEdge -&gt; [real: bb23, imaginary: bb22]"><span class="annotation">⦉21</span></span><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23:
+    14:9-14:10: StorageDead: StorageDead(_11)
+    14:9-14:10: StorageDead: StorageDead(_10)
+    15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32)
+    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]"></span></span>
 <span class="line"><span class="code odd" style="--layer: 8" title="bb24: ../instrument-coverage/coverage_of_if_else.rs:14:9: 15:23:
     14:9-14:10: StorageDead: StorageDead(_11)
     14:9-14:10: StorageDead: StorageDead(_10)
     15:9-15:23: Assign: _19 = CheckedSub(_1, const 5_i32)
-    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]">        countdown -= 5</span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
-    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">@10:</span> ;</span></span>
+    15:9-15:23: Assert: assert(!move (_19.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _1, const 5_i32) -&gt; [success: bb25, unwind: bb1]">        countdown -= 5<span class="annotation">⦉24</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">;</span></span>
 <span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
     11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">    } else {</span></span>
 <span class="line"><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
     11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]">        </span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
-    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">@27</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
+    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">27⦊</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
     17:9-17:15: Assign: _0 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     18:5-18:6: StorageDead: StorageDead(_5)
     18:5-18:6: StorageDead: StorageDead(_4)
-    17:9-17:15: Goto: goto -&gt; bb27"><span class="annotation">@11:</span> return;</span></span>
+    17:9-17:15: Goto: goto -&gt; bb27"><span class="annotation">11⦊</span>return;</span></span>
 <span class="line"><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
     17:9-17:15: Assign: _0 = const ()
     18:5-18:6: StorageDead: StorageDead(_8)
     18:5-18:6: StorageDead: StorageDead(_5)
     18:5-18:6: StorageDead: StorageDead(_4)
-    17:9-17:15: Goto: goto -&gt; bb27">    }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
+    17:9-17:15: Goto: goto -&gt; bb27">    }<span class="annotation">⦉11</span></span><span><span class="code odd" style="--layer: 1" title="bb6: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    9:5-18:6: FalseEdge: falseEdge -&gt; [real: bb8, imaginary: bb7]"><span class="annotation">⦉6</span></span></span><span class="code even" style="--layer: 2" title="bb9: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    10:9-10:23: Assign: _1 = move (_7.0: i32)
+    9:22-11:6: Assign: _4 = const ()
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉9</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    15:9-15:23: Assign: _1 = move (_19.0: i32)
+    11:29-16:6: Assign: _4 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉25</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    15:9-15:23: Assign: _1 = move (_19.0: i32)
+    11:29-16:6: Assign: _4 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉25</span></span><span class="code even" style="--layer: 3" title="bb25: ../instrument-coverage/coverage_of_if_else.rs:9:5: 18:6:
+    15:9-15:23: Assign: _1 = move (_19.0: i32)
+    11:29-16:6: Assign: _4 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    9:5-18:6: Goto: goto -&gt; bb28"><span class="annotation">⦉25</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">⦉10</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">⦉10</span></span><span class="code even" style="--layer: 4" title="bb10: ../instrument-coverage/coverage_of_if_else.rs:11:12: 18:6:
+    11:12-18:6: FalseEdge: falseEdge -&gt; [real: bb12, imaginary: bb11]"><span class="annotation">⦉10</span></span><span class="code even" style="--layer: 6" title="bb11: ../instrument-coverage/coverage_of_if_else.rs:17:9: 18:6:
+    17:9-17:15: Assign: _0 = const ()
+    18:5-18:6: StorageDead: StorageDead(_8)
+    18:5-18:6: StorageDead: StorageDead(_5)
+    18:5-18:6: StorageDead: StorageDead(_4)
+    17:9-17:15: Goto: goto -&gt; bb27"><span class="annotation">⦉11</span></span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
-    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">@27:</span> </span></span>
+    17:9-17:15: Goto: goto -&gt; bb26"></span></span>
 <span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26"></span></span>
@@ -230,11 +294,11 @@
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26">    </span><span class="code odd" style="--layer: 6" title="bb30: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
     21:5-23:6: Assign: _22 = const ()
-    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">@30</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">30⦊</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
     22:9-22:23: Assign: _21 = const 10_i32
     21:13-23:6: Assign: _22 = const ()
-    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">@31</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
-    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span> if </span><span class="code even" style="--layer: 9" title="bb28: ../instrument-coverage/coverage_of_if_else.rs:21:8: 21:12:
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">31⦊</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"><span class="annotation">29⦊</span>if </span><span class="code even" style="--layer: 9" title="bb28: ../instrument-coverage/coverage_of_if_else.rs:21:8: 21:12:
     18:5-18:6: StorageDead: StorageDead(_5)
     18:5-18:6: StorageDead: StorageDead(_4)
     20:9-20:22: StorageLive: StorageLive(_21)
@@ -244,28 +308,33 @@
     21:8-21:12: StorageLive: StorageLive(_23)
     21:8-21:12: Assign: _23 = const true
     21:8-21:12: FakeRead: FakeRead(ForMatchedPlace, _23)
-    21:5-23:6: SwitchInt: switchInt(_23) -&gt; [false: bb30, otherwise: bb29]"><span class="annotation">@28:</span> true</span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
-    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"><span class="annotation">@29:</span>  {</span></span>
+    21:5-23:6: SwitchInt: switchInt(_23) -&gt; [false: bb30, otherwise: bb29]"><span class="annotation">28⦊</span>true<span class="annotation">⦉28</span></span><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
     21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]">        countdown = 10;</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb29: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
-    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]">    }</span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
+    21:5-23:6: FalseEdge: falseEdge -&gt; [real: bb31, imaginary: bb30]">    }<span class="annotation">⦉29</span></span><span class="code even" style="--layer: 7" title="bb31: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    22:9-22:23: Assign: _21 = const 10_i32
+    21:13-23:6: Assign: _22 = const ()
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">⦉31</span></span><span class="code odd" style="--layer: 6" title="bb30: ../instrument-coverage/coverage_of_if_else.rs:21:5: 23:6:
+    21:5-23:6: Assign: _22 = const ()
+    21:5-23:6: Goto: goto -&gt; bb32"><span class="annotation">⦉30</span></span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
-    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">@27:</span> </span></span>
+    17:9-17:15: Goto: goto -&gt; bb26"></span></span>
 <span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26"></span></span>
 <span class="line"><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
     51:1-51:2: StorageDead: StorageDead(_1)
     17:9-17:15: Goto: goto -&gt; bb26">    </span><span class="code even" style="--layer: 6" title="bb33: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
-    25:5-34:6: FalseEdge: falseEdge -&gt; [real: bb35, imaginary: bb34]"><span class="annotation">@33</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: FalseEdge: falseEdge -&gt; [real: bb35, imaginary: bb34]"><span class="annotation">33⦊</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     31:9-31:23: Assign: _21 = move (_39.0: i32)
     27:29-32:6: Assign: _24 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@52</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">52⦊</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@36:</span> if </span><span class="code even" style="--layer: 9" title="bb32: ../instrument-coverage/coverage_of_if_else.rs:25:8: 25:21:
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">36⦊</span>if </span><span class="code even" style="--layer: 9" title="bb32: ../instrument-coverage/coverage_of_if_else.rs:25:8: 25:21:
     23:5-23:6: StorageDead: StorageDead(_23)
     23:5-23:6: StorageDead: StorageDead(_22)
     25:5-34:6: StorageLive: StorageLive(_24)
@@ -275,40 +344,40 @@
     25:8-25:21: Assign: _25 = Gt(move _26, const 7_i32)
     25:20-25:21: StorageDead: StorageDead(_26)
     25:8-25:21: FakeRead: FakeRead(ForMatchedPlace, _25)
-    25:5-34:6: SwitchInt: switchInt(_25) -&gt; [false: bb34, otherwise: bb33]"><span class="annotation">@32:</span> countdown &gt; 7</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: SwitchInt: switchInt(_25) -&gt; [false: bb34, otherwise: bb33]"><span class="annotation">32⦊</span>countdown &gt; 7<span class="annotation">⦉32</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@36:</span>  {</span></span>
+    25:5-34:6: Goto: goto -&gt; bb53"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
     25:5-34:6: Goto: goto -&gt; bb53">        </span><span class="code odd" style="--layer: 9" title="bb35: ../instrument-coverage/coverage_of_if_else.rs:26:9: 26:23:
     26:9-26:23: Assign: _27 = CheckedSub(_21, const 4_i32)
-    26:9-26:23: Assert: assert(!move (_27.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 4_i32) -&gt; [success: bb36, unwind: bb1]"><span class="annotation">@35:</span> countdown -= 4</span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assert: assert(!move (_27.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 4_i32) -&gt; [success: bb36, unwind: bb1]"><span class="annotation">35⦊</span>countdown -= 4<span class="annotation">⦉35</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
-    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">@36:</span> ;</span></span>
+    25:5-34:6: Goto: goto -&gt; bb53">;</span></span>
 <span class="line"><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
     26:9-26:23: Assign: _21 = move (_27.0: i32)
     25:22-27:6: Assign: _24 = const ()
     25:5-34:6: Goto: goto -&gt; bb53">    } else </span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
-    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> if </span><span class="code even" style="--layer: 10" title="bb34: ../instrument-coverage/coverage_of_if_else.rs:27:15: 27:28:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">37⦊</span>if </span><span class="code even" style="--layer: 10" title="bb34: ../instrument-coverage/coverage_of_if_else.rs:27:15: 27:28:
     27:15-27:28: StorageLive: StorageLive(_28)
     27:15-27:24: StorageLive: StorageLive(_29)
     27:15-27:24: Assign: _29 = _21
     27:15-27:28: Assign: _28 = Gt(move _29, const 2_i32)
     27:27-27:28: StorageDead: StorageDead(_29)
     27:15-27:28: FakeRead: FakeRead(ForMatchedPlace, _28)
-    27:12-34:6: SwitchInt: switchInt(_28) -&gt; [false: bb38, otherwise: bb37]"><span class="annotation">@34:</span> countdown &gt; 2</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
-    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span>  {</span></span>
+    27:12-34:6: SwitchInt: switchInt(_28) -&gt; [false: bb38, otherwise: bb37]"><span class="annotation">34⦊</span>countdown &gt; 2<span class="annotation">⦉34</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
     27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]">        </span><span class="code odd" style="--layer: 10" title="bb48: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
-    28:9-30:10: FalseEdge: falseEdge -&gt; [real: bb50, imaginary: bb49]"><span class="annotation">@48</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: FalseEdge: falseEdge -&gt; [real: bb50, imaginary: bb49]"><span class="annotation">48⦊</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     29:13-29:26: Assign: _21 = const 0_i32
     28:61-30:10: Assign: _30 = const ()
-    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">@50</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">50⦊</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     28:9-30:10: Assign: _30 = const ()
-    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">@49:</span> if </span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">49⦊</span>if </span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:9-30:10: StorageLive: StorageLive(_30)
     28:12-28:60: StorageLive: StorageLive(_31)
     28:12-28:42: StorageLive: StorageLive(_32)
@@ -317,38 +386,70 @@
     28:12-28:21: Assign: _34 = _21
     28:12-28:25: Assign: _33 = Lt(move _34, const 1_i32)
     28:24-28:25: StorageDead: StorageDead(_34)
-    28:12-28:42: SwitchInt: switchInt(move _33) -&gt; [false: bb46, otherwise: bb44]"><span class="annotation">@39</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:42: SwitchInt: switchInt(move _33) -&gt; [false: bb46, otherwise: bb44]"><span class="annotation">39⦊</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:41-28:42: StorageDead: StorageDead(_35)
     28:41-28:42: StorageDead: StorageDead(_33)
-    28:12-28:60: SwitchInt: switchInt(move _32) -&gt; [false: bb42, otherwise: bb40]"><span class="annotation">@47</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: SwitchInt: switchInt(move _32) -&gt; [false: bb42, otherwise: bb40]"><span class="annotation">47⦊</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:12-28:60: Assign: _31 = const true
-    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">@40</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">40⦊</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:59-28:60: StorageDead: StorageDead(_37)
     28:59-28:60: StorageDead: StorageDead(_32)
     28:12-28:60: FakeRead: FakeRead(ForMatchedPlace, _31)
-    28:9-30:10: SwitchInt: switchInt(_31) -&gt; [false: bb49, otherwise: bb48]"><span class="annotation">@43</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:9-30:10: SwitchInt: switchInt(_31) -&gt; [false: bb49, otherwise: bb48]"><span class="annotation">43⦊</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:46-28:60: StorageLive: StorageLive(_37)
     28:46-28:55: StorageLive: StorageLive(_38)
     28:46-28:55: Assign: _38 = _21
     28:46-28:60: Assign: _37 = Ne(move _38, const 9_i32)
     28:59-28:60: StorageDead: StorageDead(_38)
-    28:12-28:60: SwitchInt: switchInt(move _37) -&gt; [false: bb41, otherwise: bb40]"><span class="annotation">@42</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: SwitchInt: switchInt(move _37) -&gt; [false: bb41, otherwise: bb40]"><span class="annotation">42⦊</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:12-28:60: Assign: _31 = const false
-    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">@41</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">41⦊</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
     28:29-28:42: StorageLive: StorageLive(_35)
     28:29-28:38: StorageLive: StorageLive(_36)
     28:29-28:38: Assign: _36 = _21
     28:29-28:42: Assign: _35 = Gt(move _36, const 5_i32)
     28:41-28:42: StorageDead: StorageDead(_36)
-    28:12-28:42: SwitchInt: switchInt(move _35) -&gt; [false: bb45, otherwise: bb44]"><span class="annotation">@46</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:42: SwitchInt: switchInt(move _35) -&gt; [false: bb45, otherwise: bb44]"><span class="annotation">46⦊</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
     28:12-28:42: Assign: _32 = const false
-    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">@45</span></span><span class="code even" style="--layer: 21" title="bb44: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">45⦊</span></span><span class="code even" style="--layer: 21" title="bb44: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
     28:12-28:42: Assign: _32 = const true
-    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">@44:</span> countdown &lt; 1 || countdown &gt; 5</span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">44⦊</span>countdown &lt; 1 || countdown &gt; 5<span class="annotation">⦉44</span></span><span class="code even" style="--layer: 20" title="bb45: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:12-28:42: Assign: _32 = const false
+    28:12-28:42: Goto: goto -&gt; bb47"><span class="annotation">⦉45</span></span><span class="code even" style="--layer: 19" title="bb46: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:42:
+    28:29-28:42: StorageLive: StorageLive(_35)
+    28:29-28:38: StorageLive: StorageLive(_36)
+    28:29-28:38: Assign: _36 = _21
+    28:29-28:42: Assign: _35 = Gt(move _36, const 5_i32)
+    28:41-28:42: StorageDead: StorageDead(_36)
+    28:12-28:42: SwitchInt: switchInt(move _35) -&gt; [false: bb45, otherwise: bb44]"><span class="annotation">⦉46</span></span><span class="code even" style="--layer: 18" title="bb41: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
     28:12-28:60: Assign: _31 = const false
-    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">@41:</span>  || countdown != 9</span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:12-28:60: Goto: goto -&gt; bb43"> || countdown != 9<span class="annotation">⦉41</span></span><span class="code even" style="--layer: 17" title="bb42: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:46-28:60: StorageLive: StorageLive(_37)
+    28:46-28:55: StorageLive: StorageLive(_38)
+    28:46-28:55: Assign: _38 = _21
+    28:46-28:60: Assign: _37 = Ne(move _38, const 9_i32)
+    28:59-28:60: StorageDead: StorageDead(_38)
+    28:12-28:60: SwitchInt: switchInt(move _37) -&gt; [false: bb41, otherwise: bb40]"><span class="annotation">⦉42</span></span><span class="code even" style="--layer: 16" title="bb43: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:59-28:60: StorageDead: StorageDead(_37)
+    28:59-28:60: StorageDead: StorageDead(_32)
+    28:12-28:60: FakeRead: FakeRead(ForMatchedPlace, _31)
+    28:9-30:10: SwitchInt: switchInt(_31) -&gt; [false: bb49, otherwise: bb48]"><span class="annotation">⦉43</span></span><span class="code even" style="--layer: 15" title="bb40: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:12-28:60: Assign: _31 = const true
+    28:12-28:60: Goto: goto -&gt; bb43"><span class="annotation">⦉40</span></span><span class="code even" style="--layer: 14" title="bb47: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:41-28:42: StorageDead: StorageDead(_35)
+    28:41-28:42: StorageDead: StorageDead(_33)
+    28:12-28:60: SwitchInt: switchInt(move _32) -&gt; [false: bb42, otherwise: bb40]"><span class="annotation">⦉47</span></span><span class="code even" style="--layer: 13" title="bb39: ../instrument-coverage/coverage_of_if_else.rs:28:12: 28:60:
+    28:9-30:10: StorageLive: StorageLive(_30)
+    28:12-28:60: StorageLive: StorageLive(_31)
+    28:12-28:42: StorageLive: StorageLive(_32)
+    28:12-28:25: StorageLive: StorageLive(_33)
+    28:12-28:21: StorageLive: StorageLive(_34)
+    28:12-28:21: Assign: _34 = _21
+    28:12-28:25: Assign: _33 = Lt(move _34, const 1_i32)
+    28:24-28:25: StorageDead: StorageDead(_34)
+    28:12-28:42: SwitchInt: switchInt(move _33) -&gt; [false: bb46, otherwise: bb44]"><span class="annotation">⦉39</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     28:9-30:10: Assign: _30 = const ()
-    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">@49:</span>  {</span></span>
+    28:9-30:10: Goto: goto -&gt; bb51"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
     28:9-30:10: Assign: _30 = const ()
     28:9-30:10: Goto: goto -&gt; bb51">            countdown = 0;</span></span>
@@ -358,13 +459,25 @@
     30:9-30:10: StorageDead: StorageDead(_31)
     30:9-30:10: StorageDead: StorageDead(_30)
     31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32)
-    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]"><span class="annotation">@51:</span> }</span></span>
+    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]"><span class="annotation">51⦊</span>}</span><span class="code odd" style="--layer: 10" title="bb48: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: FalseEdge: falseEdge -&gt; [real: bb50, imaginary: bb49]"><span class="annotation">⦉48</span></span><span class="code even" style="--layer: 11" title="bb50: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    29:13-29:26: Assign: _21 = const 0_i32
+    28:61-30:10: Assign: _30 = const ()
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">⦉50</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: Assign: _30 = const ()
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">⦉49</span></span><span class="code even" style="--layer: 12" title="bb49: ../instrument-coverage/coverage_of_if_else.rs:28:9: 30:10:
+    28:9-30:10: Assign: _30 = const ()
+    28:9-30:10: Goto: goto -&gt; bb51"><span class="annotation">⦉49</span></span><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23:
+    30:9-30:10: StorageDead: StorageDead(_31)
+    30:9-30:10: StorageDead: StorageDead(_30)
+    31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32)
+    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]"></span></span>
 <span class="line"><span class="code odd" style="--layer: 13" title="bb51: ../instrument-coverage/coverage_of_if_else.rs:30:9: 31:23:
     30:9-30:10: StorageDead: StorageDead(_31)
     30:9-30:10: StorageDead: StorageDead(_30)
     31:9-31:23: Assign: _39 = CheckedSub(_21, const 5_i32)
-    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]">        countdown -= 5</span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
-    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">@37:</span> ;</span></span>
+    31:9-31:23: Assert: assert(!move (_39.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _21, const 5_i32) -&gt; [success: bb52, unwind: bb1]">        countdown -= 5<span class="annotation">⦉51</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]">;</span></span>
 <span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
     27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]">    } else {</span></span>
 <span class="line"><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
@@ -374,14 +487,37 @@
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     51:1-51:2: StorageDead: StorageDead(_21)
-    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">@38:</span> return;</span></span>
+    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">38⦊</span>return;</span></span>
 <span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     51:1-51:2: StorageDead: StorageDead(_21)
-    33:9-33:15: Goto: goto -&gt; bb27">    }</span></span>
+    33:9-33:15: Goto: goto -&gt; bb27">    }</span><span class="code even" style="--layer: 6" title="bb33: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    25:5-34:6: FalseEdge: falseEdge -&gt; [real: bb35, imaginary: bb34]"><span class="annotation">⦉33</span></span><span class="code even" style="--layer: 7" title="bb52: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    31:9-31:23: Assign: _21 = move (_39.0: i32)
+    27:29-32:6: Assign: _24 = const ()
+    34:5-34:6: StorageDead: StorageDead(_28)
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉52</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assign: _21 = move (_27.0: i32)
+    25:22-27:6: Assign: _24 = const ()
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉36</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assign: _21 = move (_27.0: i32)
+    25:22-27:6: Assign: _24 = const ()
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉36</span></span><span class="code even" style="--layer: 8" title="bb36: ../instrument-coverage/coverage_of_if_else.rs:25:5: 34:6:
+    26:9-26:23: Assign: _21 = move (_27.0: i32)
+    25:22-27:6: Assign: _24 = const ()
+    25:5-34:6: Goto: goto -&gt; bb53"><span class="annotation">⦉36</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">⦉37</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">⦉37</span></span><span class="code even" style="--layer: 9" title="bb37: ../instrument-coverage/coverage_of_if_else.rs:27:12: 34:6:
+    27:12-34:6: FalseEdge: falseEdge -&gt; [real: bb39, imaginary: bb38]"><span class="annotation">⦉37</span></span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
+    33:9-33:15: Assign: _0 = const ()
+    34:5-34:6: StorageDead: StorageDead(_28)
+    34:5-34:6: StorageDead: StorageDead(_25)
+    34:5-34:6: StorageDead: StorageDead(_24)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    33:9-33:15: Goto: goto -&gt; bb27"></span></span>
 <span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
@@ -405,10 +541,10 @@
     33:9-33:15: Goto: goto -&gt; bb27">    </span><span class="code even" style="--layer: 11" title="bb56: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     38:9-38:23: Assign: _41 = const 10_i32
     37:13-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">@56</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
-    37:5-39:6: FalseEdge: falseEdge -&gt; [real: bb56, imaginary: bb55]"><span class="annotation">@54</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">56⦊</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: FalseEdge: falseEdge -&gt; [real: bb56, imaginary: bb55]"><span class="annotation">54⦊</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">@55:</span> if </span><span class="code even" style="--layer: 14" title="bb53: ../instrument-coverage/coverage_of_if_else.rs:37:8: 37:12:
+    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">55⦊</span>if </span><span class="code even" style="--layer: 14" title="bb53: ../instrument-coverage/coverage_of_if_else.rs:37:8: 37:12:
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     36:9-36:22: StorageLive: StorageLive(_41)
@@ -418,21 +554,25 @@
     37:8-37:12: StorageLive: StorageLive(_43)
     37:8-37:12: Assign: _43 = const true
     37:8-37:12: FakeRead: FakeRead(ForMatchedPlace, _43)
-    37:5-39:6: SwitchInt: switchInt(_43) -&gt; [false: bb55, otherwise: bb54]"><span class="annotation">@53:</span> true</span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: SwitchInt: switchInt(_43) -&gt; [false: bb55, otherwise: bb54]"><span class="annotation">53⦊</span>true<span class="annotation">⦉53</span></span><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">@55:</span>  {</span></span>
+    37:5-39:6: Goto: goto -&gt; bb57"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
     37:5-39:6: Goto: goto -&gt; bb57">        countdown = 10;</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb55: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
     37:5-39:6: Assign: _42 = const ()
-    37:5-39:6: Goto: goto -&gt; bb57">    }</span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
+    37:5-39:6: Goto: goto -&gt; bb57">    }<span class="annotation">⦉55</span></span><span class="code even" style="--layer: 12" title="bb54: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    37:5-39:6: FalseEdge: falseEdge -&gt; [real: bb56, imaginary: bb55]"><span class="annotation">⦉54</span></span><span class="code even" style="--layer: 11" title="bb56: ../instrument-coverage/coverage_of_if_else.rs:37:5: 39:6:
+    38:9-38:23: Assign: _41 = const 10_i32
+    37:13-39:6: Assign: _42 = const ()
+    37:5-39:6: Goto: goto -&gt; bb57"><span class="annotation">⦉56</span></span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
     34:5-34:6: StorageDead: StorageDead(_25)
     34:5-34:6: StorageDead: StorageDead(_24)
     51:1-51:2: StorageDead: StorageDead(_21)
-    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">@38:</span> </span></span>
+    33:9-33:15: Goto: goto -&gt; bb27"></span></span>
 <span class="line"><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
     33:9-33:15: Assign: _0 = const ()
     34:5-34:6: StorageDead: StorageDead(_28)
@@ -449,12 +589,12 @@
     33:9-33:15: Goto: goto -&gt; bb27">    </span><span class="code odd" style="--layer: 11" title="bb61: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     42:9-42:23: Assign: _41 = move (_46.0: i32)
     41:22-43:6: Assign: _0 = const ()
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@61</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
-    41:5-50:6: FalseEdge: falseEdge -&gt; [real: bb60, imaginary: bb59]"><span class="annotation">@58</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">61⦊</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: FalseEdge: falseEdge -&gt; [real: bb60, imaginary: bb59]"><span class="annotation">58⦊</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@77:</span> if </span><span class="code even" style="--layer: 14" title="bb57: ../instrument-coverage/coverage_of_if_else.rs:41:8: 41:21:
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">77⦊</span>if </span><span class="code even" style="--layer: 14" title="bb57: ../instrument-coverage/coverage_of_if_else.rs:41:8: 41:21:
     39:5-39:6: StorageDead: StorageDead(_43)
     39:5-39:6: StorageDead: StorageDead(_42)
     41:8-41:21: StorageLive: StorageLive(_44)
@@ -463,59 +603,59 @@
     41:8-41:21: Assign: _44 = Gt(move _45, const 7_i32)
     41:20-41:21: StorageDead: StorageDead(_45)
     41:8-41:21: FakeRead: FakeRead(ForMatchedPlace, _44)
-    41:5-50:6: SwitchInt: switchInt(_44) -&gt; [false: bb59, otherwise: bb58]"><span class="annotation">@57:</span> countdown &gt; 7</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: SwitchInt: switchInt(_44) -&gt; [false: bb59, otherwise: bb58]"><span class="annotation">57⦊</span>countdown &gt; 7<span class="annotation">⦉57</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@77:</span>  {</span></span>
+    41:5-50:6: Goto: goto -&gt; bb78"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
     41:5-50:6: Goto: goto -&gt; bb78">        </span><span class="code odd" style="--layer: 14" title="bb60: ../instrument-coverage/coverage_of_if_else.rs:42:9: 42:23:
     42:9-42:23: Assign: _46 = CheckedSub(_41, const 4_i32)
-    42:9-42:23: Assert: assert(!move (_46.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 4_i32) -&gt; [success: bb61, unwind: bb1]"><span class="annotation">@60:</span> countdown -= 4</span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    42:9-42:23: Assert: assert(!move (_46.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 4_i32) -&gt; [success: bb61, unwind: bb1]"><span class="annotation">60⦊</span>countdown -= 4<span class="annotation">⦉60</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
-    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">@77:</span> ;</span></span>
+    41:5-50:6: Goto: goto -&gt; bb78">;</span></span>
 <span class="line"><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
     47:9-47:23: Assign: _41 = move (_58.0: i32)
     43:29-48:6: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
     41:5-50:6: Goto: goto -&gt; bb78">    } else </span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
-    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> if </span><span class="code even" style="--layer: 15" title="bb59: ../instrument-coverage/coverage_of_if_else.rs:43:15: 43:28:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">62⦊</span>if </span><span class="code even" style="--layer: 15" title="bb59: ../instrument-coverage/coverage_of_if_else.rs:43:15: 43:28:
     43:15-43:28: StorageLive: StorageLive(_47)
     43:15-43:24: StorageLive: StorageLive(_48)
     43:15-43:24: Assign: _48 = _41
     43:15-43:28: Assign: _47 = Gt(move _48, const 2_i32)
     43:27-43:28: StorageDead: StorageDead(_48)
     43:15-43:28: FakeRead: FakeRead(ForMatchedPlace, _47)
-    43:12-50:6: SwitchInt: switchInt(_47) -&gt; [false: bb63, otherwise: bb62]"><span class="annotation">@59:</span> countdown &gt; 2</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
-    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span>  {</span></span>
+    43:12-50:6: SwitchInt: switchInt(_47) -&gt; [false: bb63, otherwise: bb62]"><span class="annotation">59⦊</span>countdown &gt; 2<span class="annotation">⦉59</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
     43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]">        </span><span class="code odd" style="--layer: 15" title="bb75: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
     45:13-45:26: Assign: _41 = const 0_i32
     44:61-46:10: Assign: _49 = const ()
-    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">@75</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">75⦊</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
     44:9-46:10: Assign: _49 = const ()
-    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">@74</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
-    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span> if </span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">74⦊</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">73⦊</span>if </span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:46-44:60: StorageLive: StorageLive(_56)
     44:46-44:55: StorageLive: StorageLive(_57)
     44:46-44:55: Assign: _57 = _41
     44:46-44:60: Assign: _56 = Ne(move _57, const 9_i32)
     44:59-44:60: StorageDead: StorageDead(_57)
-    44:12-44:60: SwitchInt: switchInt(move _56) -&gt; [false: bb66, otherwise: bb65]"><span class="annotation">@67</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: SwitchInt: switchInt(move _56) -&gt; [false: bb66, otherwise: bb65]"><span class="annotation">67⦊</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:59-44:60: StorageDead: StorageDead(_56)
     44:59-44:60: StorageDead: StorageDead(_51)
     44:12-44:60: FakeRead: FakeRead(ForMatchedPlace, _50)
-    44:9-46:10: SwitchInt: switchInt(_50) -&gt; [false: bb74, otherwise: bb73]"><span class="annotation">@68</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:9-46:10: SwitchInt: switchInt(_50) -&gt; [false: bb74, otherwise: bb73]"><span class="annotation">68⦊</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:12-44:60: Assign: _50 = const true
-    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">@65</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">65⦊</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:41-44:42: StorageDead: StorageDead(_54)
     44:41-44:42: StorageDead: StorageDead(_52)
-    44:12-44:60: SwitchInt: switchInt(move _51) -&gt; [false: bb67, otherwise: bb65]"><span class="annotation">@72</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: SwitchInt: switchInt(move _51) -&gt; [false: bb67, otherwise: bb65]"><span class="annotation">72⦊</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:9-46:10: StorageLive: StorageLive(_49)
     44:12-44:60: StorageLive: StorageLive(_50)
     44:12-44:42: StorageLive: StorageLive(_51)
@@ -524,22 +664,54 @@
     44:12-44:21: Assign: _53 = _41
     44:12-44:25: Assign: _52 = Lt(move _53, const 1_i32)
     44:24-44:25: StorageDead: StorageDead(_53)
-    44:12-44:42: SwitchInt: switchInt(move _52) -&gt; [false: bb71, otherwise: bb69]"><span class="annotation">@64</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:42: SwitchInt: switchInt(move _52) -&gt; [false: bb71, otherwise: bb69]"><span class="annotation">64⦊</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:12-44:60: Assign: _50 = const false
-    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">@66</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">66⦊</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
     44:12-44:42: Assign: _51 = const true
-    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">@69</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">69⦊</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
     44:29-44:42: StorageLive: StorageLive(_54)
     44:29-44:38: StorageLive: StorageLive(_55)
     44:29-44:38: Assign: _55 = _41
     44:29-44:42: Assign: _54 = Gt(move _55, const 5_i32)
     44:41-44:42: StorageDead: StorageDead(_55)
-    44:12-44:42: SwitchInt: switchInt(move _54) -&gt; [false: bb70, otherwise: bb69]"><span class="annotation">@71</span></span><span class="code even" style="--layer: 26" title="bb70: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:42: SwitchInt: switchInt(move _54) -&gt; [false: bb70, otherwise: bb69]"><span class="annotation">71⦊</span></span><span class="code even" style="--layer: 26" title="bb70: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
     44:12-44:42: Assign: _51 = const false
-    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">@70:</span> countdown &lt; 1 || countdown &gt; 5</span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">70⦊</span>countdown &lt; 1 || countdown &gt; 5<span class="annotation">⦉70</span></span><span class="code even" style="--layer: 25" title="bb71: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:29-44:42: StorageLive: StorageLive(_54)
+    44:29-44:38: StorageLive: StorageLive(_55)
+    44:29-44:38: Assign: _55 = _41
+    44:29-44:42: Assign: _54 = Gt(move _55, const 5_i32)
+    44:41-44:42: StorageDead: StorageDead(_55)
+    44:12-44:42: SwitchInt: switchInt(move _54) -&gt; [false: bb70, otherwise: bb69]"><span class="annotation">⦉71</span></span><span class="code even" style="--layer: 24" title="bb69: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:42:
+    44:12-44:42: Assign: _51 = const true
+    44:12-44:42: Goto: goto -&gt; bb72"><span class="annotation">⦉69</span></span><span class="code even" style="--layer: 23" title="bb66: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
     44:12-44:60: Assign: _50 = const false
-    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">@66:</span>  || countdown != 9</span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
-    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">@73:</span>  {</span></span>
+    44:12-44:60: Goto: goto -&gt; bb68"> || countdown != 9<span class="annotation">⦉66</span></span><span class="code even" style="--layer: 22" title="bb64: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:9-46:10: StorageLive: StorageLive(_49)
+    44:12-44:60: StorageLive: StorageLive(_50)
+    44:12-44:42: StorageLive: StorageLive(_51)
+    44:12-44:25: StorageLive: StorageLive(_52)
+    44:12-44:21: StorageLive: StorageLive(_53)
+    44:12-44:21: Assign: _53 = _41
+    44:12-44:25: Assign: _52 = Lt(move _53, const 1_i32)
+    44:24-44:25: StorageDead: StorageDead(_53)
+    44:12-44:42: SwitchInt: switchInt(move _52) -&gt; [false: bb71, otherwise: bb69]"><span class="annotation">⦉64</span></span><span class="code even" style="--layer: 21" title="bb72: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:41-44:42: StorageDead: StorageDead(_54)
+    44:41-44:42: StorageDead: StorageDead(_52)
+    44:12-44:60: SwitchInt: switchInt(move _51) -&gt; [false: bb67, otherwise: bb65]"><span class="annotation">⦉72</span></span><span class="code even" style="--layer: 20" title="bb65: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:12-44:60: Assign: _50 = const true
+    44:12-44:60: Goto: goto -&gt; bb68"><span class="annotation">⦉65</span></span><span class="code even" style="--layer: 19" title="bb68: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:59-44:60: StorageDead: StorageDead(_56)
+    44:59-44:60: StorageDead: StorageDead(_51)
+    44:12-44:60: FakeRead: FakeRead(ForMatchedPlace, _50)
+    44:9-46:10: SwitchInt: switchInt(_50) -&gt; [false: bb74, otherwise: bb73]"><span class="annotation">⦉68</span></span><span class="code even" style="--layer: 18" title="bb67: ../instrument-coverage/coverage_of_if_else.rs:44:12: 44:60:
+    44:46-44:60: StorageLive: StorageLive(_56)
+    44:46-44:55: StorageLive: StorageLive(_57)
+    44:46-44:55: Assign: _57 = _41
+    44:46-44:60: Assign: _56 = Ne(move _57, const 9_i32)
+    44:59-44:60: StorageDead: StorageDead(_57)
+    44:12-44:60: SwitchInt: switchInt(move _56) -&gt; [false: bb66, otherwise: bb65]"><span class="annotation">⦉67</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"> {</span></span>
 <span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
     44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]">            countdown = 0;</span></span>
 <span class="line"><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
@@ -547,13 +719,24 @@
     46:9-46:10: StorageDead: StorageDead(_50)
     46:9-46:10: StorageDead: StorageDead(_49)
     47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32)
-    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]"><span class="annotation">@76:</span> }</span></span>
+    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]"><span class="annotation">76⦊</span>}</span><span class="code odd" style="--layer: 15" title="bb75: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    45:13-45:26: Assign: _41 = const 0_i32
+    44:61-46:10: Assign: _49 = const ()
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">⦉75</span></span><span class="code even" style="--layer: 16" title="bb74: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: Assign: _49 = const ()
+    44:9-46:10: Goto: goto -&gt; bb76"><span class="annotation">⦉74</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">⦉73</span></span><span class="code even" style="--layer: 17" title="bb73: ../instrument-coverage/coverage_of_if_else.rs:44:9: 46:10:
+    44:9-46:10: FalseEdge: falseEdge -&gt; [real: bb75, imaginary: bb74]"><span class="annotation">⦉73</span></span><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23:
+    46:9-46:10: StorageDead: StorageDead(_50)
+    46:9-46:10: StorageDead: StorageDead(_49)
+    47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32)
+    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]"></span></span>
 <span class="line"><span class="code odd" style="--layer: 18" title="bb76: ../instrument-coverage/coverage_of_if_else.rs:46:9: 47:23:
     46:9-46:10: StorageDead: StorageDead(_50)
     46:9-46:10: StorageDead: StorageDead(_49)
     47:9-47:23: Assign: _58 = CheckedSub(_41, const 5_i32)
-    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]">        countdown -= 5</span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
-    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">@62:</span> ;</span></span>
+    47:9-47:23: Assert: assert(!move (_58.1: bool), &quot;attempt to compute `{} - {}` which would overflow&quot;, _41, const 5_i32) -&gt; [success: bb77, unwind: bb1]">        countdown -= 5<span class="annotation">⦉76</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]">;</span></span>
 <span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
     43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]">    } else {</span></span>
 <span class="line"><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
@@ -564,7 +747,7 @@
     51:1-51:2: StorageDead: StorageDead(_21)
     51:1-51:2: StorageDead: StorageDead(_1)
     51:1-51:2: StorageDead: StorageDead(_44)
-    49:9-49:15: Goto: goto -&gt; bb26"><span class="annotation">@63:</span> return;</span></span>
+    49:9-49:15: Goto: goto -&gt; bb26"><span class="annotation">63⦊</span>return;</span></span>
 <span class="line"><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2:
     49:9-49:15: Assign: _0 = const ()
     50:5-50:6: StorageDead: StorageDead(_47)
@@ -572,12 +755,54 @@
     51:1-51:2: StorageDead: StorageDead(_21)
     51:1-51:2: StorageDead: StorageDead(_1)
     51:1-51:2: StorageDead: StorageDead(_44)
-    49:9-49:15: Goto: goto -&gt; bb26">    }</span><span class="code even" style="--layer: 16" title="bb78: ../instrument-coverage/coverage_of_if_else.rs:51:1: 51:2:
+    49:9-49:15: Goto: goto -&gt; bb26">    }</span><span class="code odd" style="--layer: 11" title="bb61: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    42:9-42:23: Assign: _41 = move (_46.0: i32)
+    41:22-43:6: Assign: _0 = const ()
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉61</span></span><span class="code even" style="--layer: 12" title="bb58: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    41:5-50:6: FalseEdge: falseEdge -&gt; [real: bb60, imaginary: bb59]"><span class="annotation">⦉58</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    47:9-47:23: Assign: _41 = move (_58.0: i32)
+    43:29-48:6: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉77</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    47:9-47:23: Assign: _41 = move (_58.0: i32)
+    43:29-48:6: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉77</span></span><span class="code even" style="--layer: 13" title="bb77: ../instrument-coverage/coverage_of_if_else.rs:41:5: 50:6:
+    47:9-47:23: Assign: _41 = move (_58.0: i32)
+    43:29-48:6: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    41:5-50:6: Goto: goto -&gt; bb78"><span class="annotation">⦉77</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">⦉62</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">⦉62</span></span><span class="code even" style="--layer: 14" title="bb62: ../instrument-coverage/coverage_of_if_else.rs:43:12: 50:6:
+    43:12-50:6: FalseEdge: falseEdge -&gt; [real: bb64, imaginary: bb63]"><span class="annotation">⦉62</span></span><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2:
+    49:9-49:15: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    51:1-51:2: StorageDead: StorageDead(_41)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    51:1-51:2: StorageDead: StorageDead(_1)
+    51:1-51:2: StorageDead: StorageDead(_44)
+    49:9-49:15: Goto: goto -&gt; bb26"></span></span>
+<span class="line"><span class="code even" style="--layer: 16" title="bb78: ../instrument-coverage/coverage_of_if_else.rs:51:1: 51:2:
     51:1-51:2: StorageDead: StorageDead(_41)
     51:1-51:2: StorageDead: StorageDead(_21)
     51:1-51:2: StorageDead: StorageDead(_1)
     51:1-51:2: StorageDead: StorageDead(_44)
-    51:2-51:2: Goto: goto -&gt; bb26"><span class="annotation">@78:</span> }</span><span><span class="code even" style="--layer: 1" title="bb26: ../instrument-coverage/coverage_of_if_else.rs:51:2: 51:2:
-    51:2-51:2: Return: return"><span class="annotation">@26</span></span></span></span></div>
+    51:2-51:2: Goto: goto -&gt; bb26"><span class="annotation">78⦊</span>}<span class="annotation">⦉78</span></span><span class="code even" style="--layer: 15" title="bb63: ../instrument-coverage/coverage_of_if_else.rs:49:9: 51:2:
+    49:9-49:15: Assign: _0 = const ()
+    50:5-50:6: StorageDead: StorageDead(_47)
+    51:1-51:2: StorageDead: StorageDead(_41)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    51:1-51:2: StorageDead: StorageDead(_1)
+    51:1-51:2: StorageDead: StorageDead(_44)
+    49:9-49:15: Goto: goto -&gt; bb26"><span class="annotation">⦉63</span></span><span class="code even" style="--layer: 10" title="bb38: ../instrument-coverage/coverage_of_if_else.rs:33:9: 51:2:
+    33:9-33:15: Assign: _0 = const ()
+    34:5-34:6: StorageDead: StorageDead(_28)
+    34:5-34:6: StorageDead: StorageDead(_25)
+    34:5-34:6: StorageDead: StorageDead(_24)
+    51:1-51:2: StorageDead: StorageDead(_21)
+    33:9-33:15: Goto: goto -&gt; bb27"><span class="annotation">⦉38</span></span><span class="code even" style="--layer: 5" title="bb27: ../instrument-coverage/coverage_of_if_else.rs:17:9: 51:2:
+    51:1-51:2: StorageDead: StorageDead(_1)
+    17:9-17:15: Goto: goto -&gt; bb26"><span class="annotation">⦉27</span></span><span><span class="code even" style="--layer: 1" title="bb26: ../instrument-coverage/coverage_of_if_else.rs:51:2: 51:2:
+    51:2-51:2: Return: return"><span class="annotation">26⦊</span>‸<span class="annotation">⦉26</span></span></span></span></div>
 </body>
 </html>
diff --git a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
index c13297b3a61..18828b66ce8 100644
--- a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
+++ b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile
@@ -1,4 +1,8 @@
 # needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 -include ../tools.mk
 
diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
index 6c70d951c35..f1ac39aa0ea 100644
--- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
@@ -1,4 +1,8 @@
 # needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 -include ../tools.mk
 
diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile
index 3b66427c14c..69b19801bf0 100644
--- a/src/test/run-make-fulldeps/pgo-gen/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen/Makefile
@@ -1,4 +1,8 @@
 # needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 -include ../tools.mk
 
diff --git a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
index e61018752c3..876a9b2c439 100644
--- a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
+++ b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile
@@ -1,4 +1,8 @@
 # needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 -include ../tools.mk
 
diff --git a/src/test/run-make-fulldeps/pgo-use/Makefile b/src/test/run-make-fulldeps/pgo-use/Makefile
index 61a73587759..cb5e9e9a455 100644
--- a/src/test/run-make-fulldeps/pgo-use/Makefile
+++ b/src/test/run-make-fulldeps/pgo-use/Makefile
@@ -1,4 +1,8 @@
 # needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
 
 -include ../tools.mk
 
diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk
index f9b6d342295..634c9ece3f5 100644
--- a/src/test/run-make-fulldeps/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -11,8 +11,8 @@ BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)'
 RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS)
 RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR)
 ifdef RUSTC_LINKER
-RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER)
-RUSTDOC := $(RUSTDOC) -Clinker=$(RUSTC_LINKER)
+RUSTC := $(RUSTC) -Clinker='$(RUSTC_LINKER)'
+RUSTDOC := $(RUSTDOC) -Clinker='$(RUSTC_LINKER)'
 endif
 #CC := $(CC) -L $(TMPDIR)
 HTMLDOCCK := '$(PYTHON)' '$(S)/src/etc/htmldocck.py'
diff --git a/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr b/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr
index 8827c9351a6..92d27179e8c 100644
--- a/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr
+++ b/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr
@@ -2,14 +2,13 @@ error: unresolved link to `S::fmt`
   --> $DIR/assoc-item-not-in-scope.rs:4:14
    |
 LL | /// Link to [`S::fmt`]
-   |              ^^^^^^^^ unresolved link
+   |              ^^^^^^^^ the struct `S` has no field or associated item named `fmt`
    |
 note: the lint level is defined here
   --> $DIR/assoc-item-not-in-scope.rs:1:9
    |
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
index 7530e3ad0f5..5020b97b2f2 100644
--- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
@@ -2,7 +2,7 @@ error: unresolved link to `v2`
   --> $DIR/deny-intra-link-resolution-failure.rs:3:6
    |
 LL | /// [v2]
-   |      ^^ unresolved link
+   |      ^^ no item named `v2` in `deny_intra_link_resolution_failure`
    |
 note: the lint level is defined here
   --> $DIR/deny-intra-link-resolution-failure.rs:1:9
diff --git a/src/test/rustdoc-ui/failed-doctest-output.rs b/src/test/rustdoc-ui/failed-doctest-output.rs
index fcbd7cabc69..90cdb5127be 100644
--- a/src/test/rustdoc-ui/failed-doctest-output.rs
+++ b/src/test/rustdoc-ui/failed-doctest-output.rs
@@ -2,7 +2,7 @@
 // FIXME: if/when the output of the test harness can be tested on its own, this test should be
 // adapted to use that, and that normalize line can go away
 
-// compile-flags:--test
+// compile-flags:--test --test-args --test-threads=1
 // rustc-env:RUST_BACKTRACE=0
 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
 // failure-status: 101
diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr
index f1c07e31cd7..771fc2204f5 100644
--- a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr
+++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr
@@ -2,14 +2,13 @@ error: unresolved link to `TypeAlias::hoge`
   --> $DIR/intra-doc-alias-ice.rs:5:30
    |
 LL | /// [broken cross-reference](TypeAlias::hoge)
-   |                              ^^^^^^^^^^^^^^^ unresolved link
+   |                              ^^^^^^^^^^^^^^^ the type alias `TypeAlias` has no associated item named `hoge`
    |
 note: the lint level is defined here
   --> $DIR/intra-doc-alias-ice.rs:1:9
    |
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs
new file mode 100644
index 00000000000..26b629b1313
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-link-errors.rs
@@ -0,0 +1,88 @@
+#![deny(broken_intra_doc_links)]
+//~^ NOTE lint level is defined
+
+// FIXME: this should say that it was skipped (maybe an allowed by default lint?)
+/// [<invalid syntax>]
+
+/// [path::to::nonexistent::module]
+//~^ ERROR unresolved link
+//~| NOTE no item named `path` in `intra_link_errors`
+
+/// [path::to::nonexistent::macro!]
+//~^ ERROR unresolved link
+//~| NOTE no item named `path` in `intra_link_errors`
+
+/// [type@path::to::nonexistent::type]
+//~^ ERROR unresolved link
+//~| NOTE no item named `path` in `intra_link_errors`
+
+/// [std::io::not::here]
+//~^ ERROR unresolved link
+//~| NOTE the module `io` has no inner item
+
+/// [std::io::Error::x]
+//~^ ERROR unresolved link
+//~| NOTE the struct `Error` has no field
+
+/// [std::io::ErrorKind::x]
+//~^ ERROR unresolved link
+//~| NOTE the enum `ErrorKind` has no variant
+
+/// [f::A]
+//~^ ERROR unresolved link
+//~| NOTE `f` is a function, not a module
+
+/// [S::A]
+//~^ ERROR unresolved link
+//~| NOTE struct `S` has no field or associated item
+
+/// [S::fmt]
+//~^ ERROR unresolved link
+//~| NOTE struct `S` has no field or associated item
+
+/// [E::D]
+//~^ ERROR unresolved link
+//~| NOTE enum `E` has no variant or associated item
+
+/// [u8::not_found]
+//~^ ERROR unresolved link
+//~| NOTE the builtin type `u8` does not have an associated item named `not_found`
+
+/// [S!]
+//~^ ERROR unresolved link
+//~| HELP to link to the struct, prefix with `struct@`
+//~| NOTE this link resolves to the struct `S`
+pub fn f() {}
+#[derive(Debug)]
+pub struct S;
+
+pub enum E { A, B, C }
+
+/// [type@S::h]
+//~^ ERROR unresolved link
+//~| HELP to link to the associated function
+//~| NOTE not in the type namespace
+impl S {
+    pub fn h() {}
+}
+
+/// [type@T::g]
+//~^ ERROR unresolved link
+//~| HELP to link to the associated function
+//~| NOTE not in the type namespace
+
+/// [T::h!]
+//~^ ERROR unresolved link
+//~| NOTE `T` has no macro named `h`
+pub trait T {
+    fn g() {}
+}
+
+/// [m()]
+//~^ ERROR unresolved link
+//~| HELP to link to the macro
+//~| NOTE not in the value namespace
+#[macro_export]
+macro_rules! m {
+    () => {};
+}
diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr
new file mode 100644
index 00000000000..fbf3dcbbec2
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-link-errors.stderr
@@ -0,0 +1,116 @@
+error: unresolved link to `path::to::nonexistent::module`
+  --> $DIR/intra-link-errors.rs:7:6
+   |
+LL | /// [path::to::nonexistent::module]
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in `intra_link_errors`
+   |
+note: the lint level is defined here
+  --> $DIR/intra-link-errors.rs:1:9
+   |
+LL | #![deny(broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unresolved link to `path::to::nonexistent::macro`
+  --> $DIR/intra-link-errors.rs:11:6
+   |
+LL | /// [path::to::nonexistent::macro!]
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in `intra_link_errors`
+
+error: unresolved link to `path::to::nonexistent::type`
+  --> $DIR/intra-link-errors.rs:15:6
+   |
+LL | /// [type@path::to::nonexistent::type]
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in `intra_link_errors`
+
+error: unresolved link to `std::io::not::here`
+  --> $DIR/intra-link-errors.rs:19:6
+   |
+LL | /// [std::io::not::here]
+   |      ^^^^^^^^^^^^^^^^^^ the module `io` has no inner item named `not`
+
+error: unresolved link to `std::io::Error::x`
+  --> $DIR/intra-link-errors.rs:23:6
+   |
+LL | /// [std::io::Error::x]
+   |      ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x`
+
+error: unresolved link to `std::io::ErrorKind::x`
+  --> $DIR/intra-link-errors.rs:27:6
+   |
+LL | /// [std::io::ErrorKind::x]
+   |      ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x`
+
+error: unresolved link to `f::A`
+  --> $DIR/intra-link-errors.rs:31:6
+   |
+LL | /// [f::A]
+   |      ^^^^ `f` is a function, not a module or type, and cannot have associated items
+
+error: unresolved link to `S::A`
+  --> $DIR/intra-link-errors.rs:35:6
+   |
+LL | /// [S::A]
+   |      ^^^^ the struct `S` has no field or associated item named `A`
+
+error: unresolved link to `S::fmt`
+  --> $DIR/intra-link-errors.rs:39:6
+   |
+LL | /// [S::fmt]
+   |      ^^^^^^ the struct `S` has no field or associated item named `fmt`
+
+error: unresolved link to `E::D`
+  --> $DIR/intra-link-errors.rs:43:6
+   |
+LL | /// [E::D]
+   |      ^^^^ the enum `E` has no variant or associated item named `D`
+
+error: unresolved link to `u8::not_found`
+  --> $DIR/intra-link-errors.rs:47:6
+   |
+LL | /// [u8::not_found]
+   |      ^^^^^^^^^^^^^ the builtin type `u8` does not have an associated item named `not_found`
+
+error: unresolved link to `S`
+  --> $DIR/intra-link-errors.rs:51:6
+   |
+LL | /// [S!]
+   |      ^^
+   |      |
+   |      this link resolves to the struct `S`, which is not in the macro namespace
+   |      help: to link to the struct, prefix with `struct@`: `struct@S`
+
+error: unresolved link to `T::g`
+  --> $DIR/intra-link-errors.rs:69:6
+   |
+LL | /// [type@T::g]
+   |      ^^^^^^^^^
+   |      |
+   |      this link resolves to the associated function `g`, which is not in the type namespace
+   |      help: to link to the associated function, add parentheses: `T::g()`
+
+error: unresolved link to `T::h`
+  --> $DIR/intra-link-errors.rs:74:6
+   |
+LL | /// [T::h!]
+   |      ^^^^^ the trait `T` has no macro named `h`
+
+error: unresolved link to `S::h`
+  --> $DIR/intra-link-errors.rs:61:6
+   |
+LL | /// [type@S::h]
+   |      ^^^^^^^^^
+   |      |
+   |      this link resolves to the associated function `h`, which is not in the type namespace
+   |      help: to link to the associated function, add parentheses: `S::h()`
+
+error: unresolved link to `m`
+  --> $DIR/intra-link-errors.rs:81:6
+   |
+LL | /// [m()]
+   |      ^^^
+   |      |
+   |      this link resolves to the macro `m`, which is not in the value namespace
+   |      help: to link to the macro, add an exclamation mark: `m!`
+
+error: aborting due to 16 previous errors
+
diff --git a/src/test/rustdoc-ui/intra-link-prim-conflict.rs b/src/test/rustdoc-ui/intra-link-prim-conflict.rs
index 548d3e2544a..85738ceae8e 100644
--- a/src/test/rustdoc-ui/intra-link-prim-conflict.rs
+++ b/src/test/rustdoc-ui/intra-link-prim-conflict.rs
@@ -18,13 +18,13 @@
 
 /// [struct@char]
 //~^ ERROR incompatible link
-//~| HELP prefix with the item kind
+//~| HELP prefix with `mod@`
 //~| NOTE resolved to a module
 pub mod char {}
 
 pub mod inner {
     //! [struct@char]
     //~^ ERROR incompatible link
-    //~| HELP prefix with the item kind
+    //~| HELP prefix with `prim@`
     //~| NOTE resolved to a builtin type
 }
diff --git a/src/test/rustdoc-ui/intra-link-prim-conflict.stderr b/src/test/rustdoc-ui/intra-link-prim-conflict.stderr
index 53dccfbf1a2..43587a80021 100644
--- a/src/test/rustdoc-ui/intra-link-prim-conflict.stderr
+++ b/src/test/rustdoc-ui/intra-link-prim-conflict.stderr
@@ -9,11 +9,11 @@ note: the lint level is defined here
    |
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-help: to link to the module, prefix with the item kind
+help: to link to the module, prefix with `mod@`
    |
 LL | /// [mod@char]
    |      ^^^^^^^^
-help: to link to the builtin type, prefix with the item kind
+help: to link to the builtin type, prefix with `prim@`
    |
 LL | /// [prim@char]
    |      ^^^^^^^^^
@@ -24,11 +24,11 @@ error: `char` is both a module and a builtin type
 LL | /// [type@char]
    |      ^^^^^^^^^ ambiguous link
    |
-help: to link to the module, prefix with the item kind
+help: to link to the module, prefix with `mod@`
    |
 LL | /// [mod@char]
    |      ^^^^^^^^
-help: to link to the builtin type, prefix with the item kind
+help: to link to the builtin type, prefix with `prim@`
    |
 LL | /// [prim@char]
    |      ^^^^^^^^^
@@ -37,25 +37,17 @@ error: incompatible link kind for `char`
   --> $DIR/intra-link-prim-conflict.rs:19:6
    |
 LL | /// [struct@char]
-   |      ^^^^^^^^^^^
+   |      ^^^^^^^^^^^ help: to link to the module, prefix with `mod@`: `mod@char`
    |
    = note: this link resolved to a module, which is not a struct
-help: to link to the module, prefix with the item kind
-   |
-LL | /// [mod@char]
-   |      ^^^^^^^^
 
 error: incompatible link kind for `char`
   --> $DIR/intra-link-prim-conflict.rs:26:10
    |
 LL |     //! [struct@char]
-   |          ^^^^^^^^^^^
+   |          ^^^^^^^^^^^ help: to link to the builtin type, prefix with `prim@`: `prim@char`
    |
    = note: this link resolved to a builtin type, which is not a struct
-help: to link to the builtin type, prefix with the item kind
-   |
-LL |     //! [prim@char]
-   |          ^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
index 6b0ff8f1162..3c13df20588 100644
--- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
+++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
@@ -2,7 +2,7 @@ error: unresolved link to `i`
   --> $DIR/intra-link-span-ice-55723.rs:9:10
    |
 LL | /// (arr[i])
-   |           ^ unresolved link
+   |           ^ no item named `i` in `intra_link_span_ice_55723`
    |
 note: the lint level is defined here
   --> $DIR/intra-link-span-ice-55723.rs:1:9
diff --git a/src/test/rustdoc-ui/intra-links-ambiguity.stderr b/src/test/rustdoc-ui/intra-links-ambiguity.stderr
index 7912c046f1c..17891ca05ef 100644
--- a/src/test/rustdoc-ui/intra-links-ambiguity.stderr
+++ b/src/test/rustdoc-ui/intra-links-ambiguity.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-help: to link to the struct, prefix with the item kind
+help: to link to the struct, prefix with `struct@`
    |
 LL | /// [`struct@ambiguous`] is ambiguous.
    |      ^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ error: `ambiguous` is both a struct and a function
 LL | /// [ambiguous] is ambiguous.
    |      ^^^^^^^^^ ambiguous link
    |
-help: to link to the struct, prefix with the item kind
+help: to link to the struct, prefix with `struct@`
    |
 LL | /// [struct@ambiguous] is ambiguous.
    |      ^^^^^^^^^^^^^^^^
@@ -39,7 +39,7 @@ error: `multi_conflict` is a struct, a function, and a macro
 LL | /// [`multi_conflict`] is a three-way conflict.
    |      ^^^^^^^^^^^^^^^^ ambiguous link
    |
-help: to link to the struct, prefix with the item kind
+help: to link to the struct, prefix with `struct@`
    |
 LL | /// [`struct@multi_conflict`] is a three-way conflict.
    |      ^^^^^^^^^^^^^^^^^^^^^^^
@@ -58,11 +58,11 @@ error: `type_and_value` is both a module and a constant
 LL | /// Ambiguous [type_and_value].
    |                ^^^^^^^^^^^^^^ ambiguous link
    |
-help: to link to the module, prefix with the item kind
+help: to link to the module, prefix with `mod@`
    |
 LL | /// Ambiguous [mod@type_and_value].
    |                ^^^^^^^^^^^^^^^^^^
-help: to link to the constant, prefix with the item kind
+help: to link to the constant, prefix with `const@`
    |
 LL | /// Ambiguous [const@type_and_value].
    |                ^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ error: `foo::bar` is both an enum and a function
 LL | /// Ambiguous non-implied shortcut link [`foo::bar`].
    |                                          ^^^^^^^^^^ ambiguous link
    |
-help: to link to the enum, prefix with the item kind
+help: to link to the enum, prefix with `enum@`
    |
 LL | /// Ambiguous non-implied shortcut link [`enum@foo::bar`].
    |                                          ^^^^^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/intra-links-anchors.stderr b/src/test/rustdoc-ui/intra-links-anchors.stderr
index e737b84320d..1825a4ad1fa 100644
--- a/src/test/rustdoc-ui/intra-links-anchors.stderr
+++ b/src/test/rustdoc-ui/intra-links-anchors.stderr
@@ -1,4 +1,4 @@
-error: `Foo::f#hola` contains an anchor, but links to struct fields are already anchored
+error: `Foo::f#hola` contains an anchor, but links to fields are already anchored
   --> $DIR/intra-links-anchors.rs:25:15
    |
 LL | /// Or maybe [Foo::f#hola].
@@ -16,13 +16,13 @@ error: `hello#people#!` contains multiple anchors
 LL | /// Another anchor error: [hello#people#!].
    |                            ^^^^^^^^^^^^^^ contains invalid anchor
 
-error: `Enum::A#whatever` contains an anchor, but links to enum variants are already anchored
+error: `Enum::A#whatever` contains an anchor, but links to variants are already anchored
   --> $DIR/intra-links-anchors.rs:37:28
    |
 LL | /// Damn enum's variants: [Enum::A#whatever].
    |                            ^^^^^^^^^^^^^^^^ contains invalid anchor
 
-error: `u32#hello` contains an anchor, but links to primitive types are already anchored
+error: `u32#hello` contains an anchor, but links to builtin types are already anchored
   --> $DIR/intra-links-anchors.rs:43:6
    |
 LL | /// [u32#hello]
diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs
index 54e507adfe5..b9c8e033b1b 100644
--- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs
+++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs
@@ -14,27 +14,27 @@ trait T {}
 /// Link to [struct@S]
 //~^ ERROR incompatible link kind for `S`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `enum@`
 
 /// Link to [mod@S]
 //~^ ERROR incompatible link kind for `S`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `enum@`
 
 /// Link to [union@S]
 //~^ ERROR incompatible link kind for `S`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `enum@`
 
 /// Link to [trait@S]
 //~^ ERROR incompatible link kind for `S`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `enum@`
 
 /// Link to [struct@T]
 //~^ ERROR incompatible link kind for `T`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `trait@`
 
 /// Link to [derive@m]
 //~^ ERROR incompatible link kind for `m`
@@ -44,22 +44,22 @@ trait T {}
 /// Link to [const@s]
 //~^ ERROR incompatible link kind for `s`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `static@`
 
 /// Link to [static@c]
 //~^ ERROR incompatible link kind for `c`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `const@`
 
 /// Link to [fn@c]
 //~^ ERROR incompatible link kind for `c`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `const@`
 
 /// Link to [c()]
 //~^ ERROR incompatible link kind for `c`
 //~| NOTE this link resolved
-//~| HELP prefix with the item kind
+//~| HELP prefix with `const@`
 
 /// Link to [const@f]
 //~^ ERROR incompatible link kind for `f`
diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr
index 27b94af0378..2e732baf6e0 100644
--- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr
+++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr
@@ -2,7 +2,7 @@ error: incompatible link kind for `S`
   --> $DIR/intra-links-disambiguator-mismatch.rs:14:14
    |
 LL | /// Link to [struct@S]
-   |              ^^^^^^^^
+   |              ^^^^^^^^ help: to link to the enum, prefix with `enum@`: `enum@S`
    |
 note: the lint level is defined here
   --> $DIR/intra-links-disambiguator-mismatch.rs:1:9
@@ -10,58 +10,38 @@ note: the lint level is defined here
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
    = note: this link resolved to an enum, which is not a struct
-help: to link to the enum, prefix with the item kind
-   |
-LL | /// Link to [enum@S]
-   |              ^^^^^^
 
 error: incompatible link kind for `S`
   --> $DIR/intra-links-disambiguator-mismatch.rs:19:14
    |
 LL | /// Link to [mod@S]
-   |              ^^^^^
+   |              ^^^^^ help: to link to the enum, prefix with `enum@`: `enum@S`
    |
    = note: this link resolved to an enum, which is not a module
-help: to link to the enum, prefix with the item kind
-   |
-LL | /// Link to [enum@S]
-   |              ^^^^^^
 
 error: incompatible link kind for `S`
   --> $DIR/intra-links-disambiguator-mismatch.rs:24:14
    |
 LL | /// Link to [union@S]
-   |              ^^^^^^^
+   |              ^^^^^^^ help: to link to the enum, prefix with `enum@`: `enum@S`
    |
    = note: this link resolved to an enum, which is not a union
-help: to link to the enum, prefix with the item kind
-   |
-LL | /// Link to [enum@S]
-   |              ^^^^^^
 
 error: incompatible link kind for `S`
   --> $DIR/intra-links-disambiguator-mismatch.rs:29:14
    |
 LL | /// Link to [trait@S]
-   |              ^^^^^^^
+   |              ^^^^^^^ help: to link to the enum, prefix with `enum@`: `enum@S`
    |
    = note: this link resolved to an enum, which is not a trait
-help: to link to the enum, prefix with the item kind
-   |
-LL | /// Link to [enum@S]
-   |              ^^^^^^
 
 error: incompatible link kind for `T`
   --> $DIR/intra-links-disambiguator-mismatch.rs:34:14
    |
 LL | /// Link to [struct@T]
-   |              ^^^^^^^^
+   |              ^^^^^^^^ help: to link to the trait, prefix with `trait@`: `trait@T`
    |
    = note: this link resolved to a trait, which is not a struct
-help: to link to the trait, prefix with the item kind
-   |
-LL | /// Link to [trait@T]
-   |              ^^^^^^^
 
 error: incompatible link kind for `m`
   --> $DIR/intra-links-disambiguator-mismatch.rs:39:14
@@ -75,49 +55,33 @@ error: incompatible link kind for `s`
   --> $DIR/intra-links-disambiguator-mismatch.rs:44:14
    |
 LL | /// Link to [const@s]
-   |              ^^^^^^^
+   |              ^^^^^^^ help: to link to the static, prefix with `static@`: `static@s`
    |
    = note: this link resolved to a static, which is not a constant
-help: to link to the static, prefix with the item kind
-   |
-LL | /// Link to [static@s]
-   |              ^^^^^^^^
 
 error: incompatible link kind for `c`
   --> $DIR/intra-links-disambiguator-mismatch.rs:49:14
    |
 LL | /// Link to [static@c]
-   |              ^^^^^^^^
+   |              ^^^^^^^^ help: to link to the constant, prefix with `const@`: `const@c`
    |
    = note: this link resolved to a constant, which is not a static
-help: to link to the constant, prefix with the item kind
-   |
-LL | /// Link to [const@c]
-   |              ^^^^^^^
 
 error: incompatible link kind for `c`
   --> $DIR/intra-links-disambiguator-mismatch.rs:54:14
    |
 LL | /// Link to [fn@c]
-   |              ^^^^
+   |              ^^^^ help: to link to the constant, prefix with `const@`: `const@c`
    |
    = note: this link resolved to a constant, which is not a function
-help: to link to the constant, prefix with the item kind
-   |
-LL | /// Link to [const@c]
-   |              ^^^^^^^
 
 error: incompatible link kind for `c`
   --> $DIR/intra-links-disambiguator-mismatch.rs:59:14
    |
 LL | /// Link to [c()]
-   |              ^^^
+   |              ^^^ help: to link to the constant, prefix with `const@`: `const@c`
    |
    = note: this link resolved to a constant, which is not a function
-help: to link to the constant, prefix with the item kind
-   |
-LL | /// Link to [const@c]
-   |              ^^^^^^^
 
 error: incompatible link kind for `f`
   --> $DIR/intra-links-disambiguator-mismatch.rs:64:14
diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
index 1e3a26fadfa..351f8fafa64 100644
--- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
@@ -2,7 +2,7 @@ warning: unresolved link to `error`
   --> $DIR/intra-links-warning-crlf.rs:7:6
    |
 LL | /// [error]
-   |      ^^^^^ unresolved link
+   |      ^^^^^ no item named `error` in `intra_links_warning_crlf`
    |
    = note: `#[warn(broken_intra_doc_links)]` on by default
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
@@ -11,7 +11,7 @@ warning: unresolved link to `error1`
   --> $DIR/intra-links-warning-crlf.rs:12:11
    |
 LL | /// docs [error1]
-   |           ^^^^^^ unresolved link
+   |           ^^^^^^ no item named `error1` in `intra_links_warning_crlf`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -19,7 +19,7 @@ warning: unresolved link to `error2`
   --> $DIR/intra-links-warning-crlf.rs:15:11
    |
 LL | /// docs [error2]
-   |           ^^^^^^ unresolved link
+   |           ^^^^^^ no item named `error2` in `intra_links_warning_crlf`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -27,7 +27,7 @@ warning: unresolved link to `error`
   --> $DIR/intra-links-warning-crlf.rs:23:20
    |
 LL |  * It also has an [error].
-   |                    ^^^^^ unresolved link
+   |                    ^^^^^ no item named `error` in `intra_links_warning_crlf`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr
index 53f2476295e..0832e00d35a 100644
--- a/src/test/rustdoc-ui/intra-links-warning.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning.stderr
@@ -2,56 +2,45 @@ warning: unresolved link to `Foo::baz`
   --> $DIR/intra-links-warning.rs:3:23
    |
 LL |        //! Test with [Foo::baz], [Bar::foo], ...
-   |                       ^^^^^^^^ unresolved link
+   |                       ^^^^^^^^ the struct `Foo` has no field or associated item named `baz`
    |
    = note: `#[warn(broken_intra_doc_links)]` on by default
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `Bar::foo`
   --> $DIR/intra-links-warning.rs:3:35
    |
 LL |        //! Test with [Foo::baz], [Bar::foo], ...
-   |                                   ^^^^^^^^ unresolved link
-   |
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   |                                   ^^^^^^^^ no item named `Bar` in `intra_links_warning`
 
 warning: unresolved link to `Uniooon::X`
   --> $DIR/intra-links-warning.rs:6:13
    |
 LL |      //! , [Uniooon::X] and [Qux::Z].
-   |             ^^^^^^^^^^ unresolved link
-   |
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   |             ^^^^^^^^^^ no item named `Uniooon` in `intra_links_warning`
 
 warning: unresolved link to `Qux::Z`
   --> $DIR/intra-links-warning.rs:6:30
    |
 LL |      //! , [Uniooon::X] and [Qux::Z].
-   |                              ^^^^^^ unresolved link
-   |
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   |                              ^^^^^^ no item named `Qux` in `intra_links_warning`
 
 warning: unresolved link to `Uniooon::X`
   --> $DIR/intra-links-warning.rs:10:14
    |
 LL |       //! , [Uniooon::X] and [Qux::Z].
-   |              ^^^^^^^^^^ unresolved link
-   |
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   |              ^^^^^^^^^^ no item named `Uniooon` in `intra_links_warning`
 
 warning: unresolved link to `Qux::Z`
   --> $DIR/intra-links-warning.rs:10:31
    |
 LL |       //! , [Uniooon::X] and [Qux::Z].
-   |                               ^^^^^^ unresolved link
-   |
-   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+   |                               ^^^^^^ no item named `Qux` in `intra_links_warning`
 
 warning: unresolved link to `Qux:Y`
   --> $DIR/intra-links-warning.rs:14:13
    |
 LL |        /// [Qux:Y]
-   |             ^^^^^ unresolved link
+   |             ^^^^^ no item named `Qux:Y` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -59,7 +48,7 @@ warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:58:30
    |
 LL |  * time to introduce a link [error]*/
-   |                              ^^^^^ unresolved link
+   |                              ^^^^^ no item named `error` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -67,7 +56,7 @@ warning: unresolved link to `error`
   --> $DIR/intra-links-warning.rs:64:30
    |
 LL |  * time to introduce a link [error]
-   |                              ^^^^^ unresolved link
+   |                              ^^^^^ no item named `error` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -81,6 +70,7 @@ LL | #[doc = "single line [error]"]
            
            single line [error]
                         ^^^^^
+   = note: no item named `error` in `intra_links_warning`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error`
@@ -93,6 +83,7 @@ LL | #[doc = "single line with \"escaping\" [error]"]
            
            single line with "escaping" [error]
                                         ^^^^^
+   = note: no item named `error` in `intra_links_warning`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error`
@@ -107,13 +98,14 @@ LL | | /// [error]
            
            [error]
             ^^^^^
+   = note: no item named `error` in `intra_links_warning`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error1`
   --> $DIR/intra-links-warning.rs:80:11
    |
 LL | /// docs [error1]
-   |           ^^^^^^ unresolved link
+   |           ^^^^^^ no item named `error1` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -121,7 +113,7 @@ warning: unresolved link to `error2`
   --> $DIR/intra-links-warning.rs:82:11
    |
 LL | /// docs [error2]
-   |           ^^^^^^ unresolved link
+   |           ^^^^^^ no item named `error2` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -129,7 +121,7 @@ warning: unresolved link to `BarA`
   --> $DIR/intra-links-warning.rs:21:10
    |
 LL | /// bar [BarA] bar
-   |          ^^^^ unresolved link
+   |          ^^^^ no item named `BarA` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -137,7 +129,7 @@ warning: unresolved link to `BarB`
   --> $DIR/intra-links-warning.rs:27:9
    |
 LL |  * bar [BarB] bar
-   |         ^^^^ unresolved link
+   |         ^^^^ no item named `BarB` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -145,7 +137,7 @@ warning: unresolved link to `BarC`
   --> $DIR/intra-links-warning.rs:34:6
    |
 LL | bar [BarC] bar
-   |      ^^^^ unresolved link
+   |      ^^^^ no item named `BarC` in `intra_links_warning`
    |
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
@@ -159,6 +151,7 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
            
            bar [BarD] bar
                 ^^^^
+   = note: no item named `BarD` in `intra_links_warning`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `BarF`
@@ -174,6 +167,7 @@ LL | f!("Foo\nbar [BarF] bar\nbaz");
            
            bar [BarF] bar
                 ^^^^
+   = note: no item named `BarF` in `intra_links_warning`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
    = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr
index 04296d2e44a..550b79f6e89 100644
--- a/src/test/rustdoc-ui/lint-group.stderr
+++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -32,7 +32,7 @@ error: unresolved link to `error`
   --> $DIR/lint-group.rs:9:29
    |
 LL | /// what up, let's make an [error]
-   |                             ^^^^^ unresolved link
+   |                             ^^^^^ no item named `error` in `lint_group`
    |
 note: the lint level is defined here
   --> $DIR/lint-group.rs:7:9
diff --git a/src/test/rustdoc/auxiliary/intra-link-pub-use.rs b/src/test/rustdoc/auxiliary/intra-link-pub-use.rs
new file mode 100644
index 00000000000..a4db2ffc445
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/intra-link-pub-use.rs
@@ -0,0 +1,4 @@
+#![crate_name = "inner"]
+
+/// Documentation, including a link to [std::ptr]
+pub fn f() {}
diff --git a/src/test/rustdoc/const-generics/type-alias.rs b/src/test/rustdoc/const-generics/type-alias.rs
new file mode 100644
index 00000000000..3064d0701e3
--- /dev/null
+++ b/src/test/rustdoc/const-generics/type-alias.rs
@@ -0,0 +1,6 @@
+// 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];'
+pub type CellIndex<const D: usize> = [i64; D];
diff --git a/src/test/rustdoc/intra-link-disambiguators-removed.rs b/src/test/rustdoc/intra-link-disambiguators-removed.rs
new file mode 100644
index 00000000000..26d05b484b9
--- /dev/null
+++ b/src/test/rustdoc/intra-link-disambiguators-removed.rs
@@ -0,0 +1,51 @@
+// ignore-tidy-linelength
+#![deny(intra_doc_link_resolution_failure)]
+// first try backticks
+/// Trait: [`trait@Name`], fn: [`fn@Name`], [`Name`][`macro@Name`]
+// @has intra_link_disambiguators_removed/struct.AtDisambiguator.html
+// @has - '//a[@href="../intra_link_disambiguators_removed/trait.Name.html"][code]' "Name"
+// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"][code]' "Name"
+// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"][code]' "Name"
+pub struct AtDisambiguator;
+
+/// fn: [`Name()`], macro: [`Name!`]
+// @has intra_link_disambiguators_removed/struct.SymbolDisambiguator.html
+// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"][code]' "Name()"
+// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"][code]' "Name!"
+pub struct SymbolDisambiguator;
+
+// Now make sure that backticks aren't added if they weren't already there
+/// [fn@Name]
+// @has intra_link_disambiguators_removed/trait.Name.html
+// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"]' "Name"
+// @!has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"][code]' "Name"
+
+// FIXME: this will turn !() into ! alone
+/// [Name!()]
+// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"]' "Name!"
+pub trait Name {}
+
+#[allow(non_snake_case)]
+
+// Try collapsed reference links
+/// [macro@Name][]
+// @has intra_link_disambiguators_removed/fn.Name.html
+// @has - '//a[@href="../intra_link_disambiguators_removed/macro.Name.html"]' "Name"
+
+// Try links that have the same text as a generated URL
+/// Weird URL aligned [../intra_link_disambiguators_removed/macro.Name.html][trait@Name]
+// @has - '//a[@href="../intra_link_disambiguators_removed/trait.Name.html"]' "../intra_link_disambiguators_removed/macro.Name.html"
+pub fn Name() {}
+
+#[macro_export]
+// Rustdoc doesn't currently handle links that have weird interspersing of inline code blocks.
+/// [fn@Na`m`e]
+// @has intra_link_disambiguators_removed/macro.Name.html
+// @has - '//a[@href="../intra_link_disambiguators_removed/fn.Name.html"]' "fn@Name"
+
+// It also doesn't handle any case where the code block isn't the whole link text:
+/// [trait@`Name`]
+// @has - '//a[@href="../intra_link_disambiguators_removed/trait.Name.html"]' "trait@Name"
+macro_rules! Name {
+    () => ()
+}
diff --git a/src/test/rustdoc/intra-link-pub-use.rs b/src/test/rustdoc/intra-link-pub-use.rs
new file mode 100644
index 00000000000..dd52249abc6
--- /dev/null
+++ b/src/test/rustdoc/intra-link-pub-use.rs
@@ -0,0 +1,27 @@
+// aux-build: intra-link-pub-use.rs
+#![deny(broken_intra_doc_links)]
+#![crate_name = "outer"]
+
+extern crate inner;
+
+/// [mod@std::env] [g]
+
+// FIXME: This can't be tested because rustdoc doesn't show documentation on pub re-exports.
+// Until then, comment out the `htmldocck` test.
+// This test still does something; namely check that no incorrect errors are emitted when
+// documenting the re-export.
+
+// @has outer/index.html
+// @ has - '//a[@href="https://doc.rust-lang.org/nightly/std/env/fn.var.html"]' "std::env"
+// @ has - '//a[@href="../outer/fn.f.html"]' "g"
+pub use f as g;
+
+// FIXME: same as above
+/// [std::env]
+extern crate self as _;
+
+// Make sure the documentation is actually correct by documenting an inlined re-export
+/// [mod@std::env]
+// @has outer/fn.f.html
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/env/index.html"]' "std::env"
+pub use inner::f;
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 633d153e391..caf55bec53d 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -62,7 +62,7 @@ fn expr(kind: ExprKind) -> P<Expr> {
 
 fn make_x() -> P<Expr> {
     let seg = PathSegment::from_ident(Ident::from_str("x"));
-    let path = Path { segments: vec![seg], span: DUMMY_SP };
+    let path = Path { segments: vec![seg], span: DUMMY_SP, tokens: None };
     expr(ExprKind::Path(None, path))
 }
 
@@ -113,6 +113,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                     id: DUMMY_NODE_ID,
                     rules: BlockCheckMode::Default,
                     span: DUMMY_SP,
+                    tokens: None,
                 });
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
             },
diff --git a/src/test/ui-fulldeps/session-derive-errors.rs b/src/test/ui-fulldeps/session-derive-errors.rs
new file mode 100644
index 00000000000..7967b32a4a4
--- /dev/null
+++ b/src/test/ui-fulldeps/session-derive-errors.rs
@@ -0,0 +1,260 @@
+// check-fail
+// Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_span;
+use rustc_span::Span;
+use rustc_span::symbol::Ident;
+
+extern crate rustc_macros;
+use rustc_macros::SessionDiagnostic;
+
+extern crate rustc_middle;
+use rustc_middle::ty::Ty;
+
+extern crate rustc_errors;
+use rustc_errors::Applicability;
+
+extern crate rustc_session;
+
+#[derive(SessionDiagnostic)]
+#[message = "Hello, world!"]
+#[error = "E0123"]
+struct Hello {}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+//~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs
+enum SessionDiagnosticOnEnum {
+    Foo,
+    Bar,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[label = "This is in the wrong place"]
+//~^ ERROR `#[label = ...]` is not a valid SessionDiagnostic struct attribute
+struct WrongPlace {}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct WrongPlaceField {
+    #[suggestion = "this is the wrong kind of attribute"]
+//~^ ERROR `#[suggestion = ...]` is not a valid SessionDiagnostic field attribute
+    sp: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[message = "Hello, world!"]
+#[error = "E0123"]
+#[error = "E0456"] //~ ERROR `error` specified multiple times
+struct ErrorSpecifiedTwice {}
+
+#[derive(SessionDiagnostic)]
+#[message = "Hello, world!"]
+#[error = "E0123"]
+#[lint = "some_useful_lint"] //~ ERROR `lint` specified when `error` was already specified
+struct LintSpecifiedAfterError {}
+
+#[derive(SessionDiagnostic)]
+#[message = "Some lint message"]
+#[error = "E0123"]
+struct LintButHasErrorCode {}
+
+#[derive(SessionDiagnostic)]
+struct ErrorCodeNotProvided {} //~ ERROR `code` not specified
+
+// FIXME: Uncomment when emitting lints is supported.
+/*
+#[derive(SessionDiagnostic)]
+#[message = "Hello, world!"]
+#[lint = "clashing_extern_declarations"]
+#[lint = "improper_ctypes"] // FIXME: ERROR `lint` specified multiple times
+struct LintSpecifiedTwice {}
+
+#[derive(SessionDiagnostic)]
+#[lint = "Some lint message"]
+#[message = "Some error message"]
+#[error = "E0123"] // ERROR `error` specified when `lint` was already specified
+struct ErrorSpecifiedAfterLint {}
+*/
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct ErrorWithField {
+    name: String,
+    #[message = "This error has a field, and references {name}"]
+    span: Span
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct ErrorWithMessageAppliedToField {
+    #[message = "this message is applied to a String field"]
+    //~^ ERROR the `#[message = "..."]` attribute can only be applied to fields of type Span
+    name: String,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[message = "This error has a field, and references {name}"]
+//~^ ERROR `name` doesn't refer to a field on this type
+struct ErrorWithNonexistentField {
+    span: Span
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[message = "This is missing a closing brace: {name"]
+//~^ ERROR invalid format string: expected `'}'`
+struct ErrorMissingClosingBrace {
+    name: String,
+    span: Span
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[message = "This is missing an opening brace: name}"]
+//~^ ERROR invalid format string: unmatched `}`
+struct ErrorMissingOpeningBrace {
+    name: String,
+    span: Span
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[message = "Something something"]
+struct LabelOnSpan {
+    #[label = "See here"]
+    sp: Span
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[message = "Something something"]
+struct LabelOnNonSpan {
+    #[label = "See here"]
+    //~^ ERROR The `#[label = ...]` attribute can only be applied to fields of type Span
+    id: u32,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct Suggest {
+    #[suggestion(message = "This is a suggestion", code = "This is the suggested code")]
+    #[suggestion_short(message = "This is a suggestion", code = "This is the suggested code")]
+    #[suggestion_hidden(message = "This is a suggestion", code = "This is the suggested code")]
+    #[suggestion_verbose(message = "This is a suggestion", code = "This is the suggested code")]
+    suggestion: (Span, Applicability),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithoutCode {
+    #[suggestion(message = "This is a suggestion")]
+    suggestion: (Span, Applicability),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithBadKey {
+    #[suggestion(nonsense = "This is nonsense")]
+    //~^ ERROR `nonsense` is not a valid key for `#[suggestion(...)]`
+    suggestion: (Span, Applicability),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithShorthandMsg {
+    #[suggestion(msg = "This is a suggestion")]
+    //~^ ERROR `msg` is not a valid key for `#[suggestion(...)]`
+    suggestion: (Span, Applicability),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithoutMsg {
+    #[suggestion(code = "This is suggested code")]
+    //~^ ERROR missing suggestion message
+    suggestion: (Span, Applicability),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithTypesSwapped {
+    #[suggestion(message = "This is a message", code = "This is suggested code")]
+    suggestion: (Applicability, Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithWrongTypeApplicabilityOnly {
+    #[suggestion(message = "This is a message", code = "This is suggested code")]
+    //~^ ERROR wrong field type for suggestion
+    suggestion: Applicability,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithSpanOnly{
+    #[suggestion(message = "This is a message", code = "This is suggested code")]
+    suggestion: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithDuplicateSpanAndApplicability {
+    #[suggestion(message = "This is a message", code = "This is suggested code")]
+    //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one Span
+    suggestion: (Span, Span, Applicability),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct SuggestWithDuplicateApplicabilityAndSpan {
+    #[suggestion(message = "This is a message", code = "This is suggested code")]
+    //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
+    suggestion: (Applicability, Applicability, Span),
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct WrongKindOfAnnotation {
+    #[label("wrong kind of annotation for label")]
+    //~^ ERROR invalid annotation list `#[label(...)]`
+    z: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+#[message = "Something something else"]
+struct OptionsInErrors {
+    #[label = "Label message"]
+    label: Option<Span>,
+    #[suggestion(message = "suggestion message")]
+    opt_sugg: Option<(Span, Applicability)>,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0456"]
+struct MoveOutOfBorrowError<'tcx> {
+    name: Ident,
+    ty: Ty<'tcx>,
+    #[message = "cannot move {ty} out of borrow"]
+    #[label = "cannot move out of borrow"]
+    span: Span,
+    #[label = "`{ty}` first borrowed here"]
+    other_span: Span,
+    #[suggestion(message = "consider cloning here", code = "{name}.clone()")]
+    opt_sugg: Option<(Span, Applicability)>,
+}
+
+#[derive(SessionDiagnostic)]
+#[error = "E0123"]
+struct ErrorWithLifetime<'a> {
+    #[message = "Some message that references {name}"]
+    span: Span,
+    name: &'a str,
+}
diff --git a/src/test/ui-fulldeps/session-derive-errors.stderr b/src/test/ui-fulldeps/session-derive-errors.stderr
new file mode 100644
index 00000000000..c1be151f1c1
--- /dev/null
+++ b/src/test/ui-fulldeps/session-derive-errors.stderr
@@ -0,0 +1,135 @@
+error: `#[derive(SessionDiagnostic)]` can only be used on structs
+  --> $DIR/session-derive-errors.rs:28:1
+   |
+LL | / #[error = "E0123"]
+LL | |
+LL | | enum SessionDiagnosticOnEnum {
+LL | |     Foo,
+LL | |     Bar,
+LL | | }
+   | |_^
+
+error: `#[label = ...]` is not a valid SessionDiagnostic struct attribute
+  --> $DIR/session-derive-errors.rs:37:1
+   |
+LL | #[label = "This is in the wrong place"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#[suggestion = ...]` is not a valid SessionDiagnostic field attribute
+  --> $DIR/session-derive-errors.rs:44:5
+   |
+LL |     #[suggestion = "this is the wrong kind of attribute"]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `error` specified multiple times
+  --> $DIR/session-derive-errors.rs:52:11
+   |
+LL | #[error = "E0456"]
+   |           ^^^^^^^
+
+error: `lint` specified when `error` was already specified
+  --> $DIR/session-derive-errors.rs:58:10
+   |
+LL | #[lint = "some_useful_lint"]
+   |          ^^^^^^^^^^^^^^^^^^
+
+error: `code` not specified
+  --> $DIR/session-derive-errors.rs:67:1
+   |
+LL | struct ErrorCodeNotProvided {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use the [code = "..."] attribute to set this diagnostic's error code 
+
+error: the `#[message = "..."]` attribute can only be applied to fields of type Span
+  --> $DIR/session-derive-errors.rs:95:5
+   |
+LL |     #[message = "this message is applied to a String field"]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `name` doesn't refer to a field on this type
+  --> $DIR/session-derive-errors.rs:102:1
+   |
+LL | #[message = "This error has a field, and references {name}"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: invalid format string: expected `'}'` but string was terminated
+  --> $DIR/session-derive-errors.rs:110:1
+   |
+LL | #[error = "E0123"]
+   |               - because of this opening brace
+LL | #[message = "This is missing a closing brace: {name"]
+   | ^ expected `'}'` in format string
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: invalid format string: unmatched `}` found
+  --> $DIR/session-derive-errors.rs:119:1
+   |
+LL | #[message = "This is missing an opening brace: name}"]
+   | ^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: The `#[label = ...]` attribute can only be applied to fields of type Span
+  --> $DIR/session-derive-errors.rs:138:5
+   |
+LL |     #[label = "See here"]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: `nonsense` is not a valid key for `#[suggestion(...)]`
+  --> $DIR/session-derive-errors.rs:163:18
+   |
+LL |     #[suggestion(nonsense = "This is nonsense")]
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `msg` is not a valid key for `#[suggestion(...)]`
+  --> $DIR/session-derive-errors.rs:171:18
+   |
+LL |     #[suggestion(msg = "This is a suggestion")]
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing suggestion message
+  --> $DIR/session-derive-errors.rs:179:7
+   |
+LL |     #[suggestion(code = "This is suggested code")]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: provide a suggestion message using #[suggestion(message = "...")]
+
+error: wrong field type for suggestion
+  --> $DIR/session-derive-errors.rs:194:5
+   |
+LL | /     #[suggestion(message = "This is a message", code = "This is suggested code")]
+LL | |
+LL | |     suggestion: Applicability,
+   | |_____________________________^
+   |
+   = help: #[suggestion(...)] should be applied to fields of type Span or (Span, Applicability)
+
+error: type of field annotated with `#[suggestion(...)]` contains more than one Span
+  --> $DIR/session-derive-errors.rs:209:5
+   |
+LL | /     #[suggestion(message = "This is a message", code = "This is suggested code")]
+LL | |
+LL | |     suggestion: (Span, Span, Applicability),
+   | |___________________________________________^
+
+error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
+  --> $DIR/session-derive-errors.rs:217:5
+   |
+LL | /     #[suggestion(message = "This is a message", code = "This is suggested code")]
+LL | |
+LL | |     suggestion: (Applicability, Applicability, Span),
+   | |____________________________________________________^
+
+error: invalid annotation list `#[label(...)]`
+  --> $DIR/session-derive-errors.rs:225:7
+   |
+LL |     #[label("wrong kind of annotation for label")]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 18 previous errors
+
diff --git a/src/test/ui/array-slice-vec/slice-2.rs b/src/test/ui/array-slice-vec/slice-2.rs
deleted file mode 100644
index 01733f48234..00000000000
--- a/src/test/ui/array-slice-vec/slice-2.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-// run-pass
-
-// Test slicing expressions on slices and Vecs.
-
-
-fn main() {
-    let x: &[isize] = &[1, 2, 3, 4, 5];
-    let cmp: &[isize] = &[1, 2, 3, 4, 5];
-    assert_eq!(&x[..], cmp);
-    let cmp: &[isize] = &[3, 4, 5];
-    assert_eq!(&x[2..], cmp);
-    let cmp: &[isize] = &[1, 2, 3];
-    assert_eq!(&x[..3], cmp);
-    let cmp: &[isize] = &[2, 3, 4];
-    assert_eq!(&x[1..4], cmp);
-
-    let x: Vec<isize> = vec![1, 2, 3, 4, 5];
-    let cmp: &[isize] = &[1, 2, 3, 4, 5];
-    assert_eq!(&x[..], cmp);
-    let cmp: &[isize] = &[3, 4, 5];
-    assert_eq!(&x[2..], cmp);
-    let cmp: &[isize] = &[1, 2, 3];
-    assert_eq!(&x[..3], cmp);
-    let cmp: &[isize] = &[2, 3, 4];
-    assert_eq!(&x[1..4], cmp);
-
-    let x: &mut [isize] = &mut [1, 2, 3, 4, 5];
-    {
-        let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5];
-        assert_eq!(&mut x[..], cmp);
-    }
-    {
-        let cmp: &mut [isize] = &mut [3, 4, 5];
-        assert_eq!(&mut x[2..], cmp);
-    }
-    {
-        let cmp: &mut [isize] = &mut [1, 2, 3];
-        assert_eq!(&mut x[..3], cmp);
-    }
-    {
-        let cmp: &mut [isize] = &mut [2, 3, 4];
-        assert_eq!(&mut x[1..4], cmp);
-    }
-
-    let mut x: Vec<isize> = vec![1, 2, 3, 4, 5];
-    {
-        let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5];
-        assert_eq!(&mut x[..], cmp);
-    }
-    {
-        let cmp: &mut [isize] = &mut [3, 4, 5];
-        assert_eq!(&mut x[2..], cmp);
-    }
-    {
-        let cmp: &mut [isize] = &mut [1, 2, 3];
-        assert_eq!(&mut x[..3], cmp);
-    }
-    {
-        let cmp: &mut [isize] = &mut [2, 3, 4];
-        assert_eq!(&mut x[1..4], cmp);
-    }
-}
diff --git a/src/test/ui/array-slice-vec/vec-concat.rs b/src/test/ui/array-slice-vec/vec-concat.rs
deleted file mode 100644
index 1f493679b79..00000000000
--- a/src/test/ui/array-slice-vec/vec-concat.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// run-pass
-
-use std::vec;
-
-pub fn main() {
-    let a: Vec<isize> = vec![1, 2, 3, 4, 5];
-    let b: Vec<isize> = vec![6, 7, 8, 9, 0];
-    let mut v: Vec<isize> = a;
-    v.extend_from_slice(&b);
-    println!("{}", v[9]);
-    assert_eq!(v[0], 1);
-    assert_eq!(v[7], 8);
-    assert_eq!(v[9], 0);
-}
diff --git a/src/test/ui/array-slice-vec/vec-growth.rs b/src/test/ui/array-slice-vec/vec-growth.rs
deleted file mode 100644
index b09f08bb85a..00000000000
--- a/src/test/ui/array-slice-vec/vec-growth.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-
-
-
-pub fn main() {
-    let mut v = vec![1];
-    v.push(2);
-    v.push(3);
-    v.push(4);
-    v.push(5);
-    assert_eq!(v[0], 1);
-    assert_eq!(v[1], 2);
-    assert_eq!(v[2], 3);
-    assert_eq!(v[3], 4);
-    assert_eq!(v[4], 5);
-}
diff --git a/src/test/ui/array-slice-vec/vec-push.rs b/src/test/ui/array-slice-vec/vec-push.rs
deleted file mode 100644
index 466ab3fab1c..00000000000
--- a/src/test/ui/array-slice-vec/vec-push.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-// run-pass
-
-pub fn main() { let mut v = vec![1, 2, 3]; v.push(1); }
diff --git a/src/test/ui/array-slice-vec/vec-slice.rs b/src/test/ui/array-slice-vec/vec-slice.rs
deleted file mode 100644
index 1f090ddd9c9..00000000000
--- a/src/test/ui/array-slice-vec/vec-slice.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-
-
-pub fn main() {
-    let  v = vec![1,2,3,4,5];
-    let v2 = &v[1..3];
-    assert_eq!(v2[0], 2);
-    assert_eq!(v2[1], 3);
-}
diff --git a/src/test/ui/array-slice-vec/vec-to_str.rs b/src/test/ui/array-slice-vec/vec-to_str.rs
deleted file mode 100644
index a11cfc8e9b5..00000000000
--- a/src/test/ui/array-slice-vec/vec-to_str.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// run-pass
-
-
-pub fn main() {
-    assert_eq!(format!("{:?}", vec![0, 1]), "[0, 1]".to_string());
-
-    let foo = vec![3, 4];
-    let bar: &[isize] = &[4, 5];
-
-    assert_eq!(format!("{:?}", foo), "[3, 4]");
-    assert_eq!(format!("{:?}", bar), "[4, 5]");
-}
diff --git a/src/test/ui/array-slice-vec/vec.rs b/src/test/ui/array-slice-vec/vec.rs
deleted file mode 100644
index e76c1ab440e..00000000000
--- a/src/test/ui/array-slice-vec/vec.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-
-
-pub fn main() {
-    let v: Vec<isize> = vec![10, 20];
-    assert_eq!(v[0], 10);
-    assert_eq!(v[1], 20);
-    let mut x: usize = 0;
-    assert_eq!(v[x], 10);
-    assert_eq!(v[x + 1], 20);
-    x = x + 1;
-    assert_eq!(v[x], 20);
-    assert_eq!(v[x - 1], 10);
-}
diff --git a/src/test/ui/ast-json/ast-json-noexpand-output.stdout b/src/test/ui/ast-json/ast-json-noexpand-output.stdout
index d0942f78bb8..3d7d476cf6c 100644
--- a/src/test/ui/ast-json/ast-json-noexpand-output.stdout
+++ b/src/test/ui/ast-json/ast-json-noexpand-output.stdout
@@ -1 +1 @@
-{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"NonJoint"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
+{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout
index dc06fd74a4b..a4ce6061b4c 100644
--- a/src/test/ui/ast-json/ast-json-output.stdout
+++ b/src/test/ui/ast-json/ast-json-output.stdout
@@ -1 +1 @@
-{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"NonJoint"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
+{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
diff --git a/src/test/ui/attributes/register-attr-tool-prelude.rs b/src/test/ui/attributes/register-attr-tool-prelude.rs
index a491773f5eb..d217a8146d2 100644
--- a/src/test/ui/attributes/register-attr-tool-prelude.rs
+++ b/src/test/ui/attributes/register-attr-tool-prelude.rs
@@ -7,7 +7,7 @@
 #[no_implicit_prelude]
 mod m {
     #[attr] //~ ERROR cannot find attribute `attr` in this scope
-    #[tool::attr] //~ ERROR failed to resolve: use of undeclared type or module `tool`
+    #[tool::attr] //~ ERROR failed to resolve: use of undeclared crate or module `tool`
     fn check() {}
 }
 
diff --git a/src/test/ui/attributes/register-attr-tool-prelude.stderr b/src/test/ui/attributes/register-attr-tool-prelude.stderr
index 66a4eeb6aa4..905b661206a 100644
--- a/src/test/ui/attributes/register-attr-tool-prelude.stderr
+++ b/src/test/ui/attributes/register-attr-tool-prelude.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `tool`
+error[E0433]: failed to resolve: use of undeclared crate or module `tool`
   --> $DIR/register-attr-tool-prelude.rs:10:7
    |
 LL |     #[tool::attr]
-   |       ^^^^ use of undeclared type or module `tool`
+   |       ^^^^ use of undeclared crate or module `tool`
 
 error: cannot find attribute `attr` in this scope
   --> $DIR/register-attr-tool-prelude.rs:9:7
diff --git a/src/test/ui/bad/bad-module.rs b/src/test/ui/bad/bad-module.rs
index a496c816e94..b23e97c2cf6 100644
--- a/src/test/ui/bad/bad-module.rs
+++ b/src/test/ui/bad/bad-module.rs
@@ -1,7 +1,7 @@
 fn main() {
     let foo = thing::len(Vec::new());
-    //~^ ERROR failed to resolve: use of undeclared type or module `thing`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `thing`
 
     let foo = foo::bar::baz();
-    //~^ ERROR failed to resolve: use of undeclared type or module `foo`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `foo`
 }
diff --git a/src/test/ui/bad/bad-module.stderr b/src/test/ui/bad/bad-module.stderr
index 45d4c5abd93..581a6619814 100644
--- a/src/test/ui/bad/bad-module.stderr
+++ b/src/test/ui/bad/bad-module.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve: use of undeclared type or module `thing`
+error[E0433]: failed to resolve: use of undeclared crate or module `thing`
   --> $DIR/bad-module.rs:2:15
    |
 LL |     let foo = thing::len(Vec::new());
-   |               ^^^^^ use of undeclared type or module `thing`
+   |               ^^^^^ use of undeclared crate or module `thing`
 
-error[E0433]: failed to resolve: use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared crate or module `foo`
   --> $DIR/bad-module.rs:5:15
    |
 LL |     let foo = foo::bar::baz();
-   |               ^^^ use of undeclared type or module `foo`
+   |               ^^^ use of undeclared crate or module `foo`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/coherence/conflicting-impl-with-err.stderr b/src/test/ui/coherence/conflicting-impl-with-err.stderr
index a8a5730accd..3009b452dc7 100644
--- a/src/test/ui/coherence/conflicting-impl-with-err.stderr
+++ b/src/test/ui/coherence/conflicting-impl-with-err.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve: use of undeclared type or module `nope`
+error[E0433]: failed to resolve: use of undeclared crate or module `nope`
   --> $DIR/conflicting-impl-with-err.rs:4:11
    |
 LL | impl From<nope::Thing> for Error {
-   |           ^^^^ use of undeclared type or module `nope`
+   |           ^^^^ use of undeclared crate or module `nope`
 
-error[E0433]: failed to resolve: use of undeclared type or module `nope`
+error[E0433]: failed to resolve: use of undeclared crate or module `nope`
   --> $DIR/conflicting-impl-with-err.rs:5:16
    |
 LL |     fn from(_: nope::Thing) -> Self {
-   |                ^^^^ use of undeclared type or module `nope`
+   |                ^^^^ use of undeclared crate or module `nope`
 
 error: aborting due to 2 previous errors
 
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 901fb5dd054..899a5a1836c 100644
--- a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
+++ b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
@@ -1,4 +1,6 @@
-#![feature(const_generics)]
+#![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/impl-const.rs b/src/test/ui/const-generics/auxiliary/impl-const.rs
index fc993d63927..2e25dadf119 100644
--- a/src/test/ui/const-generics/auxiliary/impl-const.rs
+++ b/src/test/ui/const-generics/auxiliary/impl-const.rs
@@ -1,4 +1,6 @@
-#![feature(const_generics)]
+#![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/const-argument-cross-crate-mismatch.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.full.stderr
index aefd514f7a6..a35c3abc113 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.full.stderr
@@ -1,11 +1,11 @@
 error[E0308]: mismatched types
-  --> $DIR/const-argument-cross-crate-mismatch.rs:6:67
+  --> $DIR/const-argument-cross-crate-mismatch.rs:7:67
    |
 LL |     let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
    |                                                                   ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
 
 error[E0308]: mismatched types
-  --> $DIR/const-argument-cross-crate-mismatch.rs:8:65
+  --> $DIR/const-argument-cross-crate-mismatch.rs:9:65
    |
 LL |     let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
    |                                                                 ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr
new file mode 100644
index 00000000000..a35c3abc113
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/const-argument-cross-crate-mismatch.rs:7:67
+   |
+LL |     let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
+   |                                                                   ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+
+error[E0308]: mismatched types
+  --> $DIR/const-argument-cross-crate-mismatch.rs:9:65
+   |
+LL |     let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
+   |                                                                 ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
index d863d097d5c..9ae2ae50ba0 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
@@ -1,4 +1,5 @@
 // aux-build:const_generic_lib.rs
+// revisions: full min
 
 extern crate const_generic_lib;
 
diff --git a/src/test/ui/const-generics/const-argument-cross-crate.rs b/src/test/ui/const-generics/const-argument-cross-crate.rs
index 98cf39a7ee1..fda3ec3eef7 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate.rs
+++ b/src/test/ui/const-generics/const-argument-cross-crate.rs
@@ -1,4 +1,5 @@
 // run-pass
+// revisions: full min
 // aux-build:const_generic_lib.rs
 
 extern crate const_generic_lib;
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
new file mode 100644
index 00000000000..b2816367ea1
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/feature-gate-const_evaluatable_checked.rs:9:30
+   |
+LL | fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
+   |                              ^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
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
new file mode 100644
index 00000000000..269710db164
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/feature-gate-const_evaluatable_checked.rs:6:33
+   |
+LL | type Arr<const N: usize> = [u8; N - 1];
+   |                                 ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
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
new file mode 100644
index 00000000000..af3090115f2
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
@@ -0,0 +1,17 @@
+// 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 must not be used inside of non trivial constant values
+
+fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
+    //[full]~^ ERROR constant expression depends
+    Default::default()
+}
+
+fn main() {
+    let x = test::<33>();
+    assert_eq!(x, [0; 32]);
+}
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
new file mode 100644
index 00000000000..da8ccdaee41
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/simple.rs:8:33
+   |
+LL | type Arr<const N: usize> = [u8; N - 1];
+   |                                 ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple.rs b/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
new file mode 100644
index 00000000000..27dc6b10320
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
@@ -0,0 +1,18 @@
+// [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)]
+
+type Arr<const N: usize> = [u8; N - 1];
+//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
+
+fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
+    Default::default()
+}
+
+fn main() {
+    let x = test::<33>();
+    assert_eq!(x, [0; 32]);
+}
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
new file mode 100644
index 00000000000..104cab8667c
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/simple_fail.rs:7:33
+   |
+LL | type Arr<const N: usize> = [u8; N - 1];
+   |                                 ^^^^^ attempt to compute `0_usize - 1_usize` which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
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
new file mode 100644
index 00000000000..042710f1327
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/simple_fail.rs:7:33
+   |
+LL | type Arr<const N: usize> = [u8; N - 1];
+   |                                 ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
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
new file mode 100644
index 00000000000..b15e0ff1839
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
@@ -0,0 +1,16 @@
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+#![feature(const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+type Arr<const N: usize> = [u8; N - 1]; //[full]~ ERROR evaluation of constant
+//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
+
+fn test<const N: usize>() -> Arr<N> where Arr<N>: Sized {
+    todo!()
+}
+
+fn main() {
+    test::<0>();
+}
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
new file mode 100644
index 00000000000..0574ddfb255
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr
@@ -0,0 +1,8 @@
+error: type parameters must be declared prior to const parameters
+  --> $DIR/complex-unord-param.rs:9: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>`
+
+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 72967640a8e..e83a96388c1 100644
--- a/src/test/ui/const-generics/defaults/complex-unord-param.rs
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs
@@ -1,11 +1,13 @@
-// run-pass
+// [full] run-pass
+// revisions: full min
 // Checks a complicated usage of unordered params
-
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![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> {
+  //[min]~^ ERROR type parameters must be declared prior to const parameters
   args: &'a [&'a [T; M]; N],
   specifier: A,
 }
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
index 0f6d7f1065a..9cc3e9c0da6 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
@@ -1,11 +1,11 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/intermixed-lifetime.rs:6:28
+  --> $DIR/intermixed-lifetime.rs:7: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>`
 
 error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/intermixed-lifetime.rs:9:37
+  --> $DIR/intermixed-lifetime.rs:11: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>`
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
new file mode 100644
index 00000000000..4d80fdb5bcb
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
@@ -0,0 +1,26 @@
+error: lifetime parameters must be declared prior to const parameters
+  --> $DIR/intermixed-lifetime.rs:7: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>`
+
+error: type parameters must be declared prior to const parameters
+  --> $DIR/intermixed-lifetime.rs:7: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>`
+
+error: lifetime parameters must be declared prior to const parameters
+  --> $DIR/intermixed-lifetime.rs:11: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>`
+
+error: type parameters must be declared prior to const parameters
+  --> $DIR/intermixed-lifetime.rs:11: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>`
+
+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 ea3a8c14b98..cc0d1c6c0c9 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
@@ -1,12 +1,16 @@
+// revisions: full min
 // Checks that lifetimes cannot be interspersed between consts and types.
-
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![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
+//[min]~^^ Error type parameters must be declared prior to const parameters
 
 struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-//~^ Error lifetime parameters must be declared prior to type parameters
+//[full]~^ Error lifetime parameters must be declared prior to type parameters
+//[min]~^^ Error type parameters must be declared prior to const parameters
+//[min]~| Error lifetime parameters must be declared prior to const parameters
 
 fn main() {}
diff --git a/src/test/ui/const-generics/defaults/simple-defaults.min.stderr b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
new file mode 100644
index 00000000000..59cc6f28af8
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
@@ -0,0 +1,8 @@
+error: type parameters must be declared prior to const parameters
+  --> $DIR/simple-defaults.rs:9:40
+   |
+LL | struct FixedOutput<'a, const N: usize, T=u32> {
+   |                   ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, 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 b282dfd37cc..78abe351998 100644
--- a/src/test/ui/const-generics/defaults/simple-defaults.rs
+++ b/src/test/ui/const-generics/defaults/simple-defaults.rs
@@ -1,10 +1,13 @@
-// run-pass
+// [full] run-pass
+// revisions: min full
 // Checks some basic test cases for defaults.
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![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> {
+  //[min]~^ ERROR type parameters must be declared prior to const parameters
   out: &'a [T; N],
 }
 
diff --git a/src/test/ui/const-generics/invalid-enum.rs b/src/test/ui/const-generics/invalid-enum.rs
new file mode 100644
index 00000000000..ceb188a0d3d
--- /dev/null
+++ b/src/test/ui/const-generics/invalid-enum.rs
@@ -0,0 +1,39 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+#[derive(PartialEq, Eq)]
+enum CompileFlag {
+  A,
+  B,
+}
+
+pub fn test_1<const CF: CompileFlag>() {}
+pub fn test_2<T, const CF: CompileFlag>(x: T) {}
+pub struct Example<const CF: CompileFlag, T=u32>{
+  x: T,
+}
+
+impl<const CF: CompileFlag, T> Example<CF, T> {
+  const ASSOC_FLAG: CompileFlag = CompileFlag::A;
+}
+
+pub fn main() {
+  test_1::<CompileFlag::A>();
+  //~^ ERROR: expected type, found variant
+  //~| ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
+
+  test_2::<_, CompileFlag::A>(0);
+  //~^ ERROR: expected type, found variant
+  //~| ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
+
+  let _: Example<CompileFlag::A, _> = Example { x: 0 };
+  //~^ ERROR: expected type, found variant
+  //~| ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
+
+  let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+  //~^ ERROR: wrong number of const arguments
+  //~| ERROR: wrong number of type arguments
+}
diff --git a/src/test/ui/const-generics/invalid-enum.stderr b/src/test/ui/const-generics/invalid-enum.stderr
new file mode 100644
index 00000000000..965abbc9cb7
--- /dev/null
+++ b/src/test/ui/const-generics/invalid-enum.stderr
@@ -0,0 +1,99 @@
+error[E0573]: expected type, found variant `CompileFlag::A`
+  --> $DIR/invalid-enum.rs:21:12
+   |
+LL |   test_1::<CompileFlag::A>();
+   |            ^^^^^^^^^^^^^^
+   |            |
+   |            not a type
+   |            help: try using the variant's enum: `CompileFlag`
+
+error[E0573]: expected type, found variant `CompileFlag::A`
+  --> $DIR/invalid-enum.rs:26:15
+   |
+LL |   test_2::<_, CompileFlag::A>(0);
+   |               ^^^^^^^^^^^^^^
+   |               |
+   |               not a type
+   |               help: try using the variant's enum: `CompileFlag`
+
+error[E0573]: expected type, found variant `CompileFlag::A`
+  --> $DIR/invalid-enum.rs:31:18
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |                  ^^^^^^^^^^^^^^
+   |                  |
+   |                  not a type
+   |                  help: try using the variant's enum: `CompileFlag`
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:31:10
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/invalid-enum.rs:31:10
+   |
+LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
+   |                  ^                ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:36:10
+   |
+LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/invalid-enum.rs:36:10
+   |
+LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
+   |                  ^                     ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:21:3
+   |
+LL |   test_1::<CompileFlag::A>();
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/invalid-enum.rs:21:12
+   |
+LL |   test_1::<CompileFlag::A>();
+   |            ^^^^^^^^^^^^^^ unexpected type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   test_1::<{ CompileFlag::A }>();
+   |            ^                ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/invalid-enum.rs:26:3
+   |
+LL |   test_2::<_, CompileFlag::A>(0);
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected 1, found 2
+  --> $DIR/invalid-enum.rs:26:15
+   |
+LL |   test_2::<_, CompileFlag::A>(0);
+   |               ^^^^^^^^^^^^^^ unexpected type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL |   test_2::<_, { CompileFlag::A }>(0);
+   |               ^                ^
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0107, E0573.
+For more information about an error, try `rustc --explain E0107`.
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 59a4d345cbc..7ea8d936d61 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,4 +1,6 @@
-#![feature(const_generics)]
+#![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-61935.full.stderr b/src/test/ui/const-generics/issues/issue-61935.full.stderr
new file mode 100644
index 00000000000..b805bc0db7e
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-61935.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-61935.rs:10:14
+   |
+LL |         Self:FooImpl<{N==0}>
+   |              ^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-61935.min.stderr b/src/test/ui/const-generics/issues/issue-61935.min.stderr
new file mode 100644
index 00000000000..e5715ec658c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-61935.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-61935.rs:10:23
+   |
+LL |         Self:FooImpl<{N==0}>
+   |                       ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-61935.rs b/src/test/ui/const-generics/issues/issue-61935.rs
index 0d42ff1895c..64257da0309 100644
--- a/src/test/ui/const-generics/issues/issue-61935.rs
+++ b/src/test/ui/const-generics/issues/issue-61935.rs
@@ -1,12 +1,15 @@
-#![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))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo {}
 
 impl<const N: usize> Foo for [(); N]
     where
         Self:FooImpl<{N==0}>
-//~^ERROR constant expression depends on a generic parameter
+//[full]~^ERROR constant expression depends on a generic parameter
+//[min]~^^ERROR generic parameters must not be used inside of non trivial constant values
 {}
 
 trait FooImpl<const IS_ZERO: bool>{}
diff --git a/src/test/ui/const-generics/issues/issue-61935.stderr b/src/test/ui/const-generics/issues/issue-61935.stderr
deleted file mode 100644
index a785af5f008..00000000000
--- a/src/test/ui/const-generics/issues/issue-61935.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/issue-61935.rs:1: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
-
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-61935.rs:8:14
-   |
-LL |         Self:FooImpl<{N==0}>
-   |              ^^^^^^^^^^^^^^^
-   |
-   = note: this may fail depending on what value the parameter takes
-
-error: aborting due to previous error; 1 warning emitted
-
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 2f3b5c5dc5b..a8fa3780356 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
@@ -1,7 +1,9 @@
 // run-pass
 
-#![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))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait BitLen: Sized {
     const BIT_LEN: usize;
@@ -12,5 +14,5 @@ impl<const L: usize> BitLen for [u8; L] {
 }
 
 fn main() {
-    let foo = <[u8; 2]>::BIT_LEN; //~ WARN unused variable
+    let _foo = <[u8; 2]>::BIT_LEN;
 }
diff --git a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.stderr b/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.stderr
deleted file mode 100644
index a9abb877c09..00000000000
--- a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.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/issue-62187-encountered-polymorphic-const.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
-
-warning: unused variable: `foo`
-  --> $DIR/issue-62187-encountered-polymorphic-const.rs:15:9
-   |
-LL |     let foo = <[u8; 2]>::BIT_LEN;
-   |         ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
-   |
-   = note: `#[warn(unused_variables)]` on by default
-
-warning: 2 warnings emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62220.stderr b/src/test/ui/const-generics/issues/issue-62220.full.stderr
index d91d2bb326f..120aa8e4af5 100644
--- a/src/test/ui/const-generics/issues/issue-62220.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:10:27
+  --> $DIR/issue-62220.rs:13: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
new file mode 100644
index 00000000000..943b689bf61
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62220.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-62220.rs:8:59
+   |
+LL | pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
+   |                                                           ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62220.rs b/src/test/ui/const-generics/issues/issue-62220.rs
index 5c4a0d31a89..acb13ad1170 100644
--- a/src/test/ui/const-generics/issues/issue-62220.rs
+++ b/src/test/ui/const-generics/issues/issue-62220.rs
@@ -1,14 +1,17 @@
-#![allow(incomplete_features)]
-#![feature(const_generics)]
+// 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]);
 
 pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
+//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
 
 impl<T, const N: usize> Vector<T, { N }> {
     /// Drop the last component and return the vector with one fewer dimension.
     pub fn trunc(self) -> (TruncatedVector<T, { N }>, T) {
-        //~^ ERROR constant expression depends on a generic parameter
+        //[full]~^ ERROR constant expression depends on a generic parameter
         unimplemented!()
     }
 }
diff --git a/src/test/ui/const-generics/issues/issue-62456.full.stderr b/src/test/ui/const-generics/issues/issue-62456.full.stderr
new file mode 100644
index 00000000000..a8d44074db9
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62456.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-62456.rs:7:20
+   |
+LL |     let _ = [0u64; N + 1];
+   |                    ^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62456.min.stderr b/src/test/ui/const-generics/issues/issue-62456.min.stderr
new file mode 100644
index 00000000000..335f0ead278
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62456.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-62456.rs:7:20
+   |
+LL |     let _ = [0u64; N + 1];
+   |                    ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62456.rs b/src/test/ui/const-generics/issues/issue-62456.rs
index 37947ad1b33..c96868c00a3 100644
--- a/src/test/ui/const-generics/issues/issue-62456.rs
+++ b/src/test/ui/const-generics/issues/issue-62456.rs
@@ -1,9 +1,12 @@
-#![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))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const N: usize>() {
     let _ = [0u64; N + 1];
-    //~^ ERROR constant expression depends on a generic parameter
+    //[full]~^ ERROR constant expression depends on a generic parameter
+    //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-62456.stderr b/src/test/ui/const-generics/issues/issue-62456.stderr
deleted file mode 100644
index 0454fed6705..00000000000
--- a/src/test/ui/const-generics/issues/issue-62456.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/issue-62456.rs:1: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
-
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-62456.rs:5:20
-   |
-LL |     let _ = [0u64; N + 1];
-   |                    ^^^^^
-   |
-   = note: this may fail depending on what value the parameter takes
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62504.stderr b/src/test/ui/const-generics/issues/issue-62504.full.stderr
index f09af76325e..9c84f06ce9f 100644
--- a/src/test/ui/const-generics/issues/issue-62504.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:18:25
+  --> $DIR/issue-62504.rs:19: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
new file mode 100644
index 00000000000..752df17aad6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62504.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-62504.rs:19:25
+   |
+LL |         ArrayHolder([0; Self::SIZE])
+   |                         ^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
+   |
+   = help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs
index 4e05aadd393..b520dbe4e80 100644
--- a/src/test/ui/const-generics/issues/issue-62504.rs
+++ b/src/test/ui/const-generics/issues/issue-62504.rs
@@ -1,7 +1,8 @@
-// Regression test for #62504
-
-#![feature(const_generics)]
+// revisions: full min
 #![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;
@@ -16,7 +17,8 @@ struct ArrayHolder<const X: usize>([u32; X]);
 impl<const X: usize> ArrayHolder<X> {
     pub const fn new() -> Self {
         ArrayHolder([0; Self::SIZE])
-        //~^ ERROR constant expression depends on a generic parameter
+        //[full]~^ ERROR constant expression depends on a generic parameter
+        //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
     }
 }
 
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
new file mode 100644
index 00000000000..6903b20fad6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr
@@ -0,0 +1,11 @@
+error: `NoMatch` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-62579-no-match.rs:10:17
+   |
+LL | fn foo<const T: NoMatch>() -> bool {
+   |                 ^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
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 7eaf5eea078..c9853aa9162 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
@@ -1,12 +1,14 @@
-// run-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// [full] run-pass
+// 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;
 
 fn foo<const T: NoMatch>() -> bool {
+    //[min]~^ ERROR `NoMatch` is forbidden as the type of a const generic parameter
     true
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.stderr b/src/test/ui/const-generics/issues/issue-62579-no-match.stderr
deleted file mode 100644
index 9fb9b5b13d8..00000000000
--- a/src/test/ui/const-generics/issues/issue-62579-no-match.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-62579-no-match.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
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62878.stderr b/src/test/ui/const-generics/issues/issue-62878.full.stderr
index fe0990d8241..c8b9db89410 100644
--- a/src/test/ui/const-generics/issues/issue-62878.stderr
+++ b/src/test/ui/const-generics/issues/issue-62878.full.stderr
@@ -1,37 +1,28 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-62878.rs:3:38
+  --> $DIR/issue-62878.rs:6:38
    |
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                      ^ the type must not depend on the parameter `N`
 
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-62878.rs:1: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
-
 error[E0107]: wrong number of const arguments: expected 2, found 1
-  --> $DIR/issue-62878.rs:7:5
+  --> $DIR/issue-62878.rs:11:5
    |
 LL |     foo::<_, {[1]}>();
    |     ^^^^^^^^^^^^^^^ expected 2 const arguments
 
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/issue-62878.rs:7:11
+  --> $DIR/issue-62878.rs:11:11
    |
 LL |     foo::<_, {[1]}>();
    |           ^ unexpected type argument
 
 error[E0308]: mismatched types
-  --> $DIR/issue-62878.rs:7:15
+  --> $DIR/issue-62878.rs:11:15
    |
 LL |     foo::<_, {[1]}>();
    |               ^^^ expected `usize`, found array `[{integer}; 1]`
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0107, E0308, E0770.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/const-generics/issues/issue-62878.min.stderr b/src/test/ui/const-generics/issues/issue-62878.min.stderr
new file mode 100644
index 00000000000..34edd09b515
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62878.min.stderr
@@ -0,0 +1,18 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/issue-62878.rs:6: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
+   |
+LL | fn foo<const N: usize, const A: [u8; N]>() {}
+   |                                 ^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs
index ccc05fdf100..0487dda2fe8 100644
--- a/src/test/ui/const-generics/issues/issue-62878.rs
+++ b/src/test/ui/const-generics/issues/issue-62878.rs
@@ -1,11 +1,15 @@
-#![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))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const N: usize, const A: [u8; N]>() {}
 //~^ ERROR the type of const parameters must not
+//[min]~| ERROR `[u8; _]` is forbidden as the type of a const generic parameter
 
 fn main() {
     foo::<_, {[1]}>();
-    //~^ ERROR wrong number of const arguments
-    //~| ERROR wrong number of type arguments
-    //~| ERROR mismatched types
+    //[full]~^ ERROR wrong number of const arguments
+    //[full]~| ERROR wrong number of type arguments
+    //[full]~| ERROR mismatched types
 }
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.stderr b/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
index 7d947a907a0..78c7ebff059 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.stderr
+++ b/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
@@ -1,14 +1,5 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/issue-67185-2.rs:1: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
-
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:15:1
+  --> $DIR/issue-67185-2.rs:17:1
    |
 LL | / trait Foo
 LL | |
@@ -26,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:15:1
+  --> $DIR/issue-67185-2.rs:17:1
    |
 LL | / trait Foo
 LL | |
@@ -44,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:25:6
+  --> $DIR/issue-67185-2.rs:27:6
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -60,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:25:6
+  --> $DIR/issue-67185-2.rs:27:6
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -76,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:29:14
+  --> $DIR/issue-67185-2.rs:31:14
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -92,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:29:14
+  --> $DIR/issue-67185-2.rs:31:14
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -107,6 +98,6 @@ LL | fn f(_: impl Foo) {}
              <[[u16; 3]; 3] as Bar>
              <[u16; 4] as Bar>
 
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
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
new file mode 100644
index 00000000000..78c7ebff059
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-67185-2.min.stderr
@@ -0,0 +1,103 @@
+error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
+  --> $DIR/issue-67185-2.rs:17:1
+   |
+LL | / trait Foo
+LL | |
+LL | |     where
+LL | |         [<u8 as Baz>::Quaks; 2]: Bar,
+LL | |         <u8 as Baz>::Quaks: Bar,
+LL | | {
+LL | | }
+   | |_^ the trait `Bar` is not implemented for `[u16; 3]`
+   |
+   = help: the following implementations were found:
+             <[[u16; 3]; 3] as Bar>
+             <[u16; 4] as Bar>
+   = help: see issue #48214
+   = 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
+   |
+LL | / trait Foo
+LL | |
+LL | |     where
+LL | |         [<u8 as Baz>::Quaks; 2]: Bar,
+LL | |         <u8 as Baz>::Quaks: Bar,
+LL | | {
+LL | | }
+   | |_^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
+   |
+   = help: the following implementations were found:
+             <[[u16; 3]; 3] as Bar>
+             <[u16; 4] as Bar>
+   = help: see issue #48214
+   = 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
+   |
+LL | trait Foo
+   |       --- required by a bound in this
+...
+LL |         <u8 as Baz>::Quaks: Bar,
+   |                             --- required by this bound in `Foo`
+...
+LL | impl Foo for FooImpl {}
+   |      ^^^ the trait `Bar` is not implemented for `[u16; 3]`
+   |
+   = help: the following implementations were found:
+             <[[u16; 3]; 3] as Bar>
+             <[u16; 4] as Bar>
+
+error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
+  --> $DIR/issue-67185-2.rs:27:6
+   |
+LL | trait Foo
+   |       --- required by a bound in this
+...
+LL |         [<u8 as Baz>::Quaks; 2]: Bar,
+   |                                  --- required by this bound in `Foo`
+...
+LL | impl Foo for FooImpl {}
+   |      ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
+   |
+   = help: the following implementations were found:
+             <[[u16; 3]; 3] as Bar>
+             <[u16; 4] as Bar>
+
+error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
+  --> $DIR/issue-67185-2.rs:31:14
+   |
+LL | trait Foo
+   |       --- required by a bound in this
+...
+LL |         [<u8 as Baz>::Quaks; 2]: Bar,
+   |                                  --- required by this bound in `Foo`
+...
+LL | fn f(_: impl Foo) {}
+   |              ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
+   |
+   = help: the following implementations were found:
+             <[[u16; 3]; 3] as Bar>
+             <[u16; 4] as Bar>
+
+error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
+  --> $DIR/issue-67185-2.rs:31:14
+   |
+LL | trait Foo
+   |       --- required by a bound in this
+...
+LL |         <u8 as Baz>::Quaks: Bar,
+   |                             --- required by this bound in `Foo`
+...
+LL | fn f(_: impl Foo) {}
+   |              ^^^ the trait `Bar` is not implemented for `[u16; 3]`
+   |
+   = help: the following implementations were found:
+             <[[u16; 3]; 3] as Bar>
+             <[u16; 4] as Bar>
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
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 111b718dd5e..1176d0c6904 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.rs
+++ b/src/test/ui/const-generics/issues/issue-67185-2.rs
@@ -1,5 +1,7 @@
-#![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))]
+#![cfg_attr(min, feature(min_const_generics))]
 
 trait Baz {
     type Quaks;
diff --git a/src/test/ui/const-generics/issues/issue-67739.stderr b/src/test/ui/const-generics/issues/issue-67739.full.stderr
index 27a56b8eb02..27a56b8eb02 100644
--- a/src/test/ui/const-generics/issues/issue-67739.stderr
+++ b/src/test/ui/const-generics/issues/issue-67739.full.stderr
diff --git a/src/test/ui/const-generics/issues/issue-67739.min.stderr b/src/test/ui/const-generics/issues/issue-67739.min.stderr
new file mode 100644
index 00000000000..1254ee7239d
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-67739.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-67739.rs:12:30
+   |
+LL |         [0u8; mem::size_of::<Self::Associated>()];
+   |                              ^^^^^^^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
+   |
+   = help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs
index c8ee1821239..72bf3ee9602 100644
--- a/src/test/ui/const-generics/issues/issue-67739.rs
+++ b/src/test/ui/const-generics/issues/issue-67739.rs
@@ -1,7 +1,7 @@
-// Regression test for #67739
-
-#![allow(incomplete_features)]
-#![feature(const_generics)]
+// 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;
 
@@ -10,7 +10,8 @@ pub trait Trait {
 
     fn associated_size(&self) -> usize {
         [0u8; mem::size_of::<Self::Associated>()];
-        //~^ ERROR constant expression depends on a generic parameter
+        //[full]~^ ERROR constant expression depends on a generic parameter
+        //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
         0
     }
 }
diff --git a/src/test/ui/const-generics/issues/issue-68366.full.stderr b/src/test/ui/const-generics/issues/issue-68366.full.stderr
new file mode 100644
index 00000000000..ac774f50c74
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68366.full.stderr
@@ -0,0 +1,21 @@
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-68366.rs:12:13
+   |
+LL | impl <const N: usize> Collatz<{Some(N)}> {}
+   |             ^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-68366.rs:18:12
+   |
+LL | impl<const N: usize> Foo {}
+   |            ^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/const-generics/issues/issue-68366.min.stderr b/src/test/ui/const-generics/issues/issue-68366.min.stderr
new file mode 100644
index 00000000000..8d34bdc6ea0
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68366.min.stderr
@@ -0,0 +1,29 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-68366.rs:12:37
+   |
+LL | impl <const N: usize> Collatz<{Some(N)}> {}
+   |                                     ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-68366.rs:12:13
+   |
+LL | impl <const N: usize> Collatz<{Some(N)}> {}
+   |             ^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-68366.rs:18:12
+   |
+LL | impl<const N: usize> Foo {}
+   |            ^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/const-generics/issues/issue-68366.rs b/src/test/ui/const-generics/issues/issue-68366.rs
new file mode 100644
index 00000000000..819fcaffea1
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68366.rs
@@ -0,0 +1,21 @@
+// Checks that const expressions have a useful note explaining why they can't be evaluated.
+// The note should relate to the fact that it cannot be shown forall N that it maps 1-1 to a new
+// type.
+
+// 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>>;
+
+impl <const N: usize> Collatz<{Some(N)}> {}
+//~^ ERROR the const parameter
+//[min]~^^ generic parameters must not be used inside of non trivial constant values
+
+struct Foo;
+
+impl<const N: usize> Foo {}
+//~^ ERROR the const parameter
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-72787.stderr b/src/test/ui/const-generics/issues/issue-72787.full.stderr
index ed892e46bbb..b4c79d4171b 100644
--- a/src/test/ui/const-generics/issues/issue-72787.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:9:32
+  --> $DIR/issue-72787.rs:11: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:20:42
+  --> $DIR/issue-72787.rs:26: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:20:42
+  --> $DIR/issue-72787.rs:26: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:20:42
+  --> $DIR/issue-72787.rs:26: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:20:42
+  --> $DIR/issue-72787.rs:26: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
new file mode 100644
index 00000000000..d3e9887fe20
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72787.min.stderr
@@ -0,0 +1,57 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-72787.rs:11:17
+   |
+LL |     Condition<{ LHS <= RHS }>: True
+   |                 ^^^ non-trivial anonymous constants must not depend on the parameter `LHS`
+   |
+   = help: it is currently only allowed to use either `LHS` or `{ LHS }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-72787.rs:11:24
+   |
+LL |     Condition<{ LHS <= RHS }>: True
+   |                        ^^^ non-trivial anonymous constants must not depend on the parameter `RHS`
+   |
+   = help: it is currently only allowed to use either `RHS` or `{ RHS }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-72787.rs:26:25
+   |
+LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+   |                         ^ non-trivial anonymous constants must not depend on the parameter `I`
+   |
+   = help: it is currently only allowed to use either `I` or `{ I }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-72787.rs:26:36
+   |
+LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+   |                                    ^ non-trivial anonymous constants must not depend on the parameter `J`
+   |
+   = help: it is currently only allowed to use either `J` or `{ J }` as generic constants
+
+error[E0283]: type annotations needed
+  --> $DIR/issue-72787.rs:22:26
+   |
+LL | pub trait True {}
+   | -------------- required by this bound in `True`
+...
+LL |     IsLessOrEqual<I, 8>: True,
+   |                          ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
+   |
+   = note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
+
+error[E0283]: type annotations needed
+  --> $DIR/issue-72787.rs:22:26
+   |
+LL | pub trait True {}
+   | -------------- required by this bound in `True`
+...
+LL |     IsLessOrEqual<I, 8>: True,
+   |                          ^^^^ cannot infer type for struct `IsLessOrEqual<I, 8_u32>`
+   |
+   = note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/const-generics/issues/issue-72787.rs b/src/test/ui/const-generics/issues/issue-72787.rs
index a368c226ec3..45c20191c88 100644
--- a/src/test/ui/const-generics/issues/issue-72787.rs
+++ b/src/test/ui/const-generics/issues/issue-72787.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// 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>;
@@ -7,7 +9,9 @@ pub trait True {}
 
 impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
     Condition<{ LHS <= RHS }>: True
-//~^ Error constant expression depends on a generic parameter
+//[full]~^ Error constant expression depends on a generic parameter
+//[min]~^^ Error generic parameters must not be used inside of non trivial constant values
+//[min]~| Error generic parameters must not be used inside of non trivial constant values
 {
 }
 impl True for Condition<true> {}
@@ -16,12 +20,16 @@ struct S<const I: u32, const J: u32>;
 impl<const I: u32, const J: u32> S<I, J>
 where
     IsLessOrEqual<I, 8>: True,
+//[min]~^ Error type annotations needed [E0283]
+//[min]~| Error type annotations needed [E0283]
     IsLessOrEqual<J, 8>: True,
     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
-//~^ Error constant expression depends on a generic parameter
-//~| Error constant expression depends on a generic parameter
-//~| Error constant expression depends on a generic parameter
-//~| Error constant expression depends on a generic parameter
+//[full]~^ constant expression depends on a generic parameter
+//[full]~| constant expression depends on a generic parameter
+//[full]~| constant expression depends on a generic parameter
+//[full]~| constant expression depends on a generic parameter
+//[min]~^^^^^ Error generic parameters must not be used inside of non trivial constant values
+//[min]~| Error generic parameters must not be used inside of non trivial constant values
     // Condition<{ 8 - I <= 8 - J }>: True,
 {
     fn print() {
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
index a9f664d0ac8..e4105a3df1c 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.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:7:47
+  --> $DIR/issue-72819-generic-in-const-eval.rs:9:47
    |
 LL | where Assert::<{N < usize::max_value() / 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
new file mode 100644
index 00000000000..48a1f0bd19c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+  --> $DIR/issue-72819-generic-in-const-eval.rs:9:17
+   |
+LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
+   |                 ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
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 225593c3178..b653b91d99d 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
@@ -1,11 +1,14 @@
 // Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type
 // bounds.
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
 
-#![feature(const_generics)]
-#![allow(incomplete_features)]
 struct Arr<const N: usize>
 where Assert::<{N < usize::max_value() / 2}>: IsTrue,
-//~^ ERROR constant expression depends on a generic parameter
+//[full]~^ ERROR constant expression depends on a generic parameter
+//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
 {
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-73120.rs b/src/test/ui/const-generics/issues/issue-73120.rs
index aea4de39f79..c153a93cdef 100644
--- a/src/test/ui/const-generics/issues/issue-73120.rs
+++ b/src/test/ui/const-generics/issues/issue-73120.rs
@@ -1,3 +1,4 @@
+// revisions: full min
 // check-pass
 // aux-build:const_generic_issues_lib.rs
 extern crate const_generic_issues_lib as lib2;
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
new file mode 100644
index 00000000000..2365adc3a86
--- /dev/null
+++ b/src/test/ui/const-generics/min-and-full-same-time.rs
@@ -0,0 +1,7 @@
+#![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
new file mode 100644
index 00000000000..907fec9bbe1
--- /dev/null
+++ b/src/test/ui/const-generics/min-and-full-same-time.stderr
@@ -0,0 +1,13 @@
+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/type-dependent/auxiliary/type_dependent_lib.rs b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs
index c8db91b62b5..aa85376bf0d 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,5 +1,6 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![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_evaluatable/associated-const.rs b/src/test/ui/const_evaluatable/associated-const.rs
new file mode 100644
index 00000000000..a6777632254
--- /dev/null
+++ b/src/test/ui/const_evaluatable/associated-const.rs
@@ -0,0 +1,11 @@
+// check-pass
+struct Foo<T>(T);
+impl<T> Foo<T> {
+    const VALUE: usize = std::mem::size_of::<T>();
+}
+
+fn test<T>() {
+    let _ = [0; Foo::<u8>::VALUE];
+}
+
+fn main() {}
diff --git a/src/test/ui/const_evaluatable/function-call.rs b/src/test/ui/const_evaluatable/function-call.rs
new file mode 100644
index 00000000000..b5de66621c5
--- /dev/null
+++ b/src/test/ui/const_evaluatable/function-call.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+const fn foo<T>() -> usize {
+    // We might instead branch on `std::mem::size_of::<*mut T>() < 8` here,
+    // which would cause this function to fail on 32 bit systems.
+    if false {
+        std::mem::size_of::<T>()
+    } else {
+        8
+    }
+}
+
+fn test<T>() {
+    let _ = [0; foo::<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
+}
+
+fn main() {}
diff --git a/src/test/ui/const_evaluatable/function-call.stderr b/src/test/ui/const_evaluatable/function-call.stderr
new file mode 100644
index 00000000000..0d8463714e8
--- /dev/null
+++ b/src/test/ui/const_evaluatable/function-call.stderr
@@ -0,0 +1,12 @@
+warning: cannot use constants which depend on generic parameters in types
+  --> $DIR/function-call.rs:14:17
+   |
+LL |     let _ = [0; foo::<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>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/consts/const-nonzero.rs b/src/test/ui/consts/const-nonzero.rs
deleted file mode 100644
index cf6f8c8d69a..00000000000
--- a/src/test/ui/consts/const-nonzero.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// run-pass
-
-use std::num::NonZeroU8;
-
-const X: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(5) };
-const Y: u8 = X.get();
-
-const ZERO: Option<NonZeroU8> = NonZeroU8::new(0);
-const ONE: Option<NonZeroU8> = NonZeroU8::new(1);
-
-fn main() {
-    assert_eq!(Y, 5);
-
-    assert!(ZERO.is_none());
-    assert_eq!(ONE.unwrap().get(), 1);
-}
diff --git a/src/test/ui/consts/cow-is-borrowed.rs b/src/test/ui/consts/cow-is-borrowed.rs
deleted file mode 100644
index adebe20f5a2..00000000000
--- a/src/test/ui/consts/cow-is-borrowed.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-#![feature(cow_is_borrowed)]
-
-use std::borrow::Cow;
-
-fn main() {
-    const COW: Cow<str> = Cow::Borrowed("moo");
-
-    const IS_BORROWED: bool = COW.is_borrowed();
-    assert!(IS_BORROWED);
-
-    const IS_OWNED: bool = COW.is_owned();
-    assert!(!IS_OWNED);
-}
diff --git a/src/test/ui/consts/duration-consts-2.rs b/src/test/ui/consts/duration-consts-2.rs
index c8b39399331..bc0969e4f1f 100644
--- a/src/test/ui/consts/duration-consts-2.rs
+++ b/src/test/ui/consts/duration-consts-2.rs
@@ -3,6 +3,7 @@
 #![feature(const_panic)]
 #![feature(duration_consts_2)]
 #![feature(div_duration)]
+#![feature(duration_saturating_ops)]
 
 use std::time::Duration;
 
@@ -15,29 +16,29 @@ fn duration() {
 
     const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1);
 
-    const MAX_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
-    assert_eq!(MAX_ADD_ZERO, Some(MAX));
+    const MAX_CHECKED_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
+    assert_eq!(MAX_CHECKED_ADD_ZERO, Some(MAX));
 
-    const MAX_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
-    assert_eq!(MAX_ADD_ONE, None);
+    const MAX_CHECKED_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
+    assert_eq!(MAX_CHECKED_ADD_ONE, None);
 
-    const ONE_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
-    assert_eq!(ONE_SUB_ONE, Some(ZERO));
+    const ONE_CHECKED_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
+    assert_eq!(ONE_CHECKED_SUB_ONE, Some(ZERO));
 
-    const ZERO_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
-    assert_eq!(ZERO_SUB_ONE, None);
+    const ZERO_CHECKED_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
+    assert_eq!(ZERO_CHECKED_SUB_ONE, None);
 
-    const ONE_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
-    assert_eq!(ONE_MUL_ONE, Some(ONE));
+    const ONE_CHECKED_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
+    assert_eq!(ONE_CHECKED_MUL_ONE, Some(ONE));
 
-    const MAX_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
-    assert_eq!(MAX_MUL_TWO, None);
+    const MAX_CHECKED_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
+    assert_eq!(MAX_CHECKED_MUL_TWO, None);
 
-    const ONE_DIV_ONE : Option<Duration> = ONE.checked_div(1);
-    assert_eq!(ONE_DIV_ONE, Some(ONE));
+    const ONE_CHECKED_DIV_ONE : Option<Duration> = ONE.checked_div(1);
+    assert_eq!(ONE_CHECKED_DIV_ONE, Some(ONE));
 
-    const ONE_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
-    assert_eq!(ONE_DIV_ZERO, None);
+    const ONE_CHECKED_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
+    assert_eq!(ONE_CHECKED_DIV_ZERO, None);
 
     const MAX_AS_F32 : f32 = MAX.as_secs_f32();
     assert_eq!(MAX_AS_F32, 18446744000000000000.0_f32);
@@ -50,6 +51,15 @@ fn duration() {
 
     const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE);
     assert_eq!(ONE_AS_F64, 1.0_f64);
+
+    const MAX_SATURATING_ADD_ONE : Duration = MAX.saturating_add(ONE);
+    assert_eq!(MAX_SATURATING_ADD_ONE, MAX);
+
+    const ZERO_SATURATING_SUB_ONE : Duration = ZERO.saturating_sub(ONE);
+    assert_eq!(ZERO_SATURATING_SUB_ONE, ZERO);
+
+    const MAX_SATURATING_MUL_TWO : Duration = MAX.saturating_mul(2);
+    assert_eq!(MAX_SATURATING_MUL_TWO, MAX);
 }
 
 fn main() {
diff --git a/src/test/ui/consts/is_ascii.rs b/src/test/ui/consts/is_ascii.rs
deleted file mode 100644
index d8424549f93..00000000000
--- a/src/test/ui/consts/is_ascii.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-
-static X: bool = 'a'.is_ascii();
-static Y: bool = 'ä'.is_ascii();
-
-static BX: bool = b'a'.is_ascii();
-static BY: bool = 192u8.is_ascii();
-
-fn main() {
-    assert!(X);
-    assert!(!Y);
-
-    assert!(BX);
-    assert!(!BY);
-}
diff --git a/src/test/ui/consts/promote-no-mut.rs b/src/test/ui/consts/promote-no-mut.rs
new file mode 100644
index 00000000000..fb57c8bb934
--- /dev/null
+++ b/src/test/ui/consts/promote-no-mut.rs
@@ -0,0 +1,10 @@
+// ignore-tidy-linelength
+// We do not promote mutable references.
+static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]); //~ ERROR temporary value dropped while borrowed
+
+static mut TEST2: &'static mut [i32] = {
+    let x = &mut [1,2,3]; //~ ERROR temporary value dropped while borrowed
+    x
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/promote-no-mut.stderr b/src/test/ui/consts/promote-no-mut.stderr
new file mode 100644
index 00000000000..49d96546ada
--- /dev/null
+++ b/src/test/ui/consts/promote-no-mut.stderr
@@ -0,0 +1,23 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/promote-no-mut.rs:3:50
+   |
+LL | static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]);
+   |                                        ----------^^^^^^^^^-
+   |                                        |         |        |
+   |                                        |         |        temporary value is freed at the end of this statement
+   |                                        |         creates a temporary which is freed while still in use
+   |                                        using this value as a static requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/promote-no-mut.rs:6:18
+   |
+LL |     let x = &mut [1,2,3];
+   |                  ^^^^^^^ creates a temporary which is freed while still in use
+LL |     x
+   |     - using this value as a static requires that borrow lasts for `'static`
+LL | };
+   | - temporary value is freed at the end of this statement
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/consts/promotion-mutable-ref.rs b/src/test/ui/consts/promotion-mutable-ref.rs
new file mode 100644
index 00000000000..d103c5a9d23
--- /dev/null
+++ b/src/test/ui/consts/promotion-mutable-ref.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(const_mut_refs)]
+
+static mut TEST: i32 = {
+    // We must not promote this, as CTFE needs to be able to mutate it later.
+    let x = &mut [1,2,3];
+    x[0] += 1;
+    x[0]
+};
+
+// This still works -- it's not done via promotion.
+#[allow(unused)]
+static mut TEST2: &'static mut [i32] = &mut [0,1,2];
+
+fn main() {
+    assert_eq!(unsafe { TEST }, 2);
+}
diff --git a/src/test/ui/consts/std/net/ipv4.rs b/src/test/ui/consts/std/net/ipv4.rs
deleted file mode 100644
index 8c676999ae7..00000000000
--- a/src/test/ui/consts/std/net/ipv4.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// run-pass
-
-#![feature(ip)]
-#![feature(const_ipv4)]
-
-use std::net::{Ipv4Addr, Ipv6Addr};
-
-fn main() {
-    const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
-    assert_eq!(IP_ADDRESS, Ipv4Addr::LOCALHOST);
-
-    const OCTETS: [u8; 4] = IP_ADDRESS.octets();
-    assert_eq!(OCTETS, [127, 0, 0, 1]);
-
-    const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified();
-    assert!(!IS_UNSPECIFIED);
-
-    const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback();
-    assert!(IS_LOOPBACK);
-
-    const IS_PRIVATE : bool = IP_ADDRESS.is_private();
-    assert!(!IS_PRIVATE);
-
-    const IS_LINK_LOCAL : bool = IP_ADDRESS.is_link_local();
-    assert!(!IS_LINK_LOCAL);
-
-    const IS_GLOBAL : bool = IP_ADDRESS.is_global();
-    assert!(!IS_GLOBAL);
-
-    const IS_SHARED : bool = IP_ADDRESS.is_shared();
-    assert!(!IS_SHARED);
-
-    const IS_IETF_PROTOCOL_ASSIGNMENT : bool = IP_ADDRESS.is_ietf_protocol_assignment();
-    assert!(!IS_IETF_PROTOCOL_ASSIGNMENT);
-
-    const IS_BENCHMARKING : bool = IP_ADDRESS.is_benchmarking();
-    assert!(!IS_BENCHMARKING);
-
-    const IS_RESERVED : bool = IP_ADDRESS.is_reserved();
-    assert!(!IS_RESERVED);
-
-    const IS_MULTICAST : bool = IP_ADDRESS.is_multicast();
-    assert!(!IS_MULTICAST);
-
-    const IS_BROADCAST : bool = IP_ADDRESS.is_broadcast();
-    assert!(!IS_BROADCAST);
-
-    const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation();
-    assert!(!IS_DOCUMENTATION);
-
-    const IP_V6_COMPATIBLE : Ipv6Addr = IP_ADDRESS.to_ipv6_compatible();
-    assert_eq!(IP_V6_COMPATIBLE,
-        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1]));
-
-    const IP_V6_MAPPED : Ipv6Addr = IP_ADDRESS.to_ipv6_mapped();
-    assert_eq!(IP_V6_MAPPED,
-        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1]));
-}
diff --git a/src/test/ui/consts/std/net/ipv6.rs b/src/test/ui/consts/std/net/ipv6.rs
deleted file mode 100644
index e3841c38c22..00000000000
--- a/src/test/ui/consts/std/net/ipv6.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-// run-pass
-
-#![feature(ip)]
-#![feature(const_ipv6)]
-
-use std::net::{Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
-
-fn main() {
-    const IP_ADDRESS : Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
-    assert_eq!(IP_ADDRESS, Ipv6Addr::LOCALHOST);
-
-    const SEGMENTS : [u16; 8] = IP_ADDRESS.segments();
-    assert_eq!(SEGMENTS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 1]);
-
-    const OCTETS : [u8; 16] = IP_ADDRESS.octets();
-    assert_eq!(OCTETS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 0 ,0 ,0 ,0 ,0 ,0 ,0, 0, 1]);
-
-    const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified();
-    assert!(!IS_UNSPECIFIED);
-
-    const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback();
-    assert!(IS_LOOPBACK);
-
-    const IS_GLOBAL : bool = IP_ADDRESS.is_global();
-    assert!(!IS_GLOBAL);
-
-    const IS_UNIQUE_LOCAL : bool = IP_ADDRESS.is_unique_local();
-    assert!(!IS_UNIQUE_LOCAL);
-
-    const IS_UNICAST_LINK_LOCAL_STRICT : bool = IP_ADDRESS.is_unicast_link_local_strict();
-    assert!(!IS_UNICAST_LINK_LOCAL_STRICT);
-
-    const IS_UNICAST_LINK_LOCAL : bool = IP_ADDRESS.is_unicast_link_local();
-    assert!(!IS_UNICAST_LINK_LOCAL);
-
-    const IS_UNICAST_SITE_LOCAL : bool = IP_ADDRESS.is_unicast_site_local();
-    assert!(!IS_UNICAST_SITE_LOCAL);
-
-    const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation();
-    assert!(!IS_DOCUMENTATION);
-
-    const IS_UNICAST_GLOBAL : bool = IP_ADDRESS.is_unicast_global();
-    assert!(!IS_UNICAST_GLOBAL);
-
-    const MULTICAST_SCOPE : Option<Ipv6MulticastScope> = IP_ADDRESS.multicast_scope();
-    assert_eq!(MULTICAST_SCOPE, None);
-
-    const IS_MULTICAST : bool = IP_ADDRESS.is_multicast();
-    assert!(!IS_MULTICAST);
-
-    const IP_V4 : Option<Ipv4Addr> = IP_ADDRESS.to_ipv4();
-    assert_eq!(IP_V4.unwrap(), Ipv4Addr::new(0, 0, 0, 1));
-}
diff --git a/src/test/ui/derived-errors/issue-31997-1.stderr b/src/test/ui/derived-errors/issue-31997-1.stderr
index 229c5c9e80f..6d177666ed0 100644
--- a/src/test/ui/derived-errors/issue-31997-1.stderr
+++ b/src/test/ui/derived-errors/issue-31997-1.stderr
@@ -1,4 +1,4 @@
-error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
+error[E0433]: failed to resolve: use of undeclared type `HashMap`
   --> $DIR/issue-31997-1.rs:20:19
    |
 LL |     let mut map = HashMap::new();
diff --git a/src/test/ui/derives/derive-on-trait-item-or-impl-item.stderr b/src/test/ui/derives/derive-on-trait-item-or-impl-item.stderr
index b3aa886cd49..e892d3f0863 100644
--- a/src/test/ui/derives/derive-on-trait-item-or-impl-item.stderr
+++ b/src/test/ui/derives/derive-on-trait-item-or-impl-item.stderr
@@ -1,10 +1,10 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/derive-on-trait-item-or-impl-item.rs:2:5
    |
 LL |     #[derive(Clone)]
    |     ^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/derive-on-trait-item-or-impl-item.rs:10:5
    |
 LL |     #[derive(Clone)]
@@ -12,3 +12,4 @@ LL |     #[derive(Clone)]
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/derives/deriving-non-type.stderr b/src/test/ui/derives/deriving-non-type.stderr
index 563e76dc609..8c9daf4d4b3 100644
--- a/src/test/ui/derives/deriving-non-type.stderr
+++ b/src/test/ui/derives/deriving-non-type.stderr
@@ -1,52 +1,52 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:5:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:8:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:11:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:14:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:17:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:20:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:23:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:26:1
    |
 LL | #[derive(PartialEq)]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/deriving-non-type.rs:29:1
    |
 LL | #[derive(PartialEq)]
@@ -54,3 +54,4 @@ LL | #[derive(PartialEq)]
 
 error: aborting due to 9 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/dyn-trait-compatibility.rs b/src/test/ui/dyn-trait-compatibility.rs
index 2a1cea6c348..d2b02cc2af5 100644
--- a/src/test/ui/dyn-trait-compatibility.rs
+++ b/src/test/ui/dyn-trait-compatibility.rs
@@ -1,7 +1,7 @@
 type A0 = dyn;
 //~^ ERROR cannot find type `dyn` in this scope
 type A1 = dyn::dyn;
-//~^ ERROR use of undeclared type or module `dyn`
+//~^ ERROR use of undeclared crate or module `dyn`
 type A2 = dyn<dyn, dyn>;
 //~^ ERROR cannot find type `dyn` in this scope
 //~| ERROR cannot find type `dyn` in this scope
@@ -9,6 +9,6 @@ type A2 = dyn<dyn, dyn>;
 type A3 = dyn<<dyn as dyn>::dyn>;
 //~^ ERROR cannot find type `dyn` in this scope
 //~| ERROR cannot find type `dyn` in this scope
-//~| ERROR use of undeclared type or module `dyn`
+//~| ERROR use of undeclared crate or module `dyn`
 
 fn main() {}
diff --git a/src/test/ui/dyn-trait-compatibility.stderr b/src/test/ui/dyn-trait-compatibility.stderr
index 8fe8ceb4d0a..9218ae9d5da 100644
--- a/src/test/ui/dyn-trait-compatibility.stderr
+++ b/src/test/ui/dyn-trait-compatibility.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve: use of undeclared type or module `dyn`
+error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
   --> $DIR/dyn-trait-compatibility.rs:3:11
    |
 LL | type A1 = dyn::dyn;
-   |           ^^^ use of undeclared type or module `dyn`
+   |           ^^^ use of undeclared crate or module `dyn`
 
-error[E0433]: failed to resolve: use of undeclared type or module `dyn`
+error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
   --> $DIR/dyn-trait-compatibility.rs:9:23
    |
 LL | type A3 = dyn<<dyn as dyn>::dyn>;
-   |                       ^^^ use of undeclared type or module `dyn`
+   |                       ^^^ use of undeclared crate or module `dyn`
 
 error[E0412]: cannot find type `dyn` in this scope
   --> $DIR/dyn-trait-compatibility.rs:1:11
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 5a528379b04..cdc1db4c0b4 100644
--- a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
+++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
@@ -1,5 +1,4 @@
 // run-pass
-
 #![feature(arbitrary_enum_discriminant, core_intrinsics)]
 
 extern crate core;
@@ -9,6 +8,8 @@ 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
 }
 
 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
new file mode 100644
index 00000000000..906927e705e
--- /dev/null
+++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
@@ -0,0 +1,12 @@
+warning: cannot use constants which depend on generic parameters in types
+  --> $DIR/issue-70453-polymorphic-ctfe.rs:10:15
+   |
+LL |     Some(T) = core::mem::size_of::<*mut 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>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs
index 818dec1207b..54d3cc54a84 100644
--- a/src/test/ui/error-codes/E0017.rs
+++ b/src/test/ui/error-codes/E0017.rs
@@ -3,9 +3,11 @@ const C: i32 = 2;
 static mut M: i32 = 3;
 
 const CR: &'static mut i32 = &mut C; //~ ERROR E0764
+                                     //~| WARN taking a mutable
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0764
                                               //~| ERROR E0019
                                               //~| ERROR cannot borrow
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764
+                                              //~| WARN taking a mutable
 static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR E0764
 fn main() {}
diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr
index c1d96de1dca..40ef6bd97b3 100644
--- a/src/test/ui/error-codes/E0017.stderr
+++ b/src/test/ui/error-codes/E0017.stderr
@@ -1,3 +1,18 @@
+warning: taking a mutable reference to a `const` item
+  --> $DIR/E0017.rs:5:30
+   |
+LL | const CR: &'static mut i32 = &mut C;
+   |                              ^^^^^^
+   |
+   = note: `#[warn(const_item_mutation)]` on by default
+   = 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: `const` item defined here
+  --> $DIR/E0017.rs:2:1
+   |
+LL | const C: i32 = 2;
+   | ^^^^^^^^^^^^^^^^^
+
 error[E0764]: mutable references are not allowed in constants
   --> $DIR/E0017.rs:5:30
    |
@@ -5,7 +20,7 @@ LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^ `&mut` is only allowed in `const fn`
 
 error[E0019]: static contains unimplemented expression type
-  --> $DIR/E0017.rs:6:39
+  --> $DIR/E0017.rs:7:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^
@@ -13,30 +28,44 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0764]: mutable references are not allowed in statics
-  --> $DIR/E0017.rs:6:39
+  --> $DIR/E0017.rs:7:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ `&mut` is only allowed in `const fn`
 
 error[E0596]: cannot borrow immutable static item `X` as mutable
-  --> $DIR/E0017.rs:6:39
+  --> $DIR/E0017.rs:7:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ cannot borrow as mutable
 
+warning: taking a mutable reference to a `const` item
+  --> $DIR/E0017.rs:10:38
+   |
+LL | static CONST_REF: &'static mut i32 = &mut C;
+   |                                      ^^^^^^
+   |
+   = 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: `const` item defined here
+  --> $DIR/E0017.rs:2:1
+   |
+LL | const C: i32 = 2;
+   | ^^^^^^^^^^^^^^^^^
+
 error[E0764]: mutable references are not allowed in statics
-  --> $DIR/E0017.rs:9:38
+  --> $DIR/E0017.rs:10:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^ `&mut` is only allowed in `const fn`
 
 error[E0764]: mutable references are not allowed in statics
-  --> $DIR/E0017.rs:10:52
+  --> $DIR/E0017.rs:12:52
    |
 LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M };
    |                                                    ^^^^^^ `&mut` is only allowed in `const fn`
 
-error: aborting due to 6 previous errors
+error: aborting due to 6 previous errors; 2 warnings emitted
 
 Some errors have detailed explanations: E0019, E0596, E0764.
 For more information about an error, try `rustc --explain E0019`.
diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs
index 13131017c2e..8ad586bb30f 100644
--- a/src/test/ui/error-codes/E0388.rs
+++ b/src/test/ui/error-codes/E0388.rs
@@ -2,9 +2,11 @@ static X: i32 = 1;
 const C: i32 = 2;
 
 const CR: &'static mut i32 = &mut C; //~ ERROR E0764
+                                     //~| WARN taking a mutable
 static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0019
                                               //~| ERROR cannot borrow
                                               //~| ERROR E0764
 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764
+                                             //~| WARN taking a mutable
 
 fn main() {}
diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr
index f09100bac43..39bc717ceec 100644
--- a/src/test/ui/error-codes/E0388.stderr
+++ b/src/test/ui/error-codes/E0388.stderr
@@ -1,3 +1,18 @@
+warning: taking a mutable reference to a `const` item
+  --> $DIR/E0388.rs:4:30
+   |
+LL | const CR: &'static mut i32 = &mut C;
+   |                              ^^^^^^
+   |
+   = note: `#[warn(const_item_mutation)]` on by default
+   = 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: `const` item defined here
+  --> $DIR/E0388.rs:2:1
+   |
+LL | const C: i32 = 2;
+   | ^^^^^^^^^^^^^^^^^
+
 error[E0764]: mutable references are not allowed in constants
   --> $DIR/E0388.rs:4:30
    |
@@ -5,7 +20,7 @@ LL | const CR: &'static mut i32 = &mut C;
    |                              ^^^^^^ `&mut` is only allowed in `const fn`
 
 error[E0019]: static contains unimplemented expression type
-  --> $DIR/E0388.rs:5:39
+  --> $DIR/E0388.rs:6:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^
@@ -13,24 +28,38 @@ LL | static STATIC_REF: &'static mut i32 = &mut X;
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
 error[E0764]: mutable references are not allowed in statics
-  --> $DIR/E0388.rs:5:39
+  --> $DIR/E0388.rs:6:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ `&mut` is only allowed in `const fn`
 
 error[E0596]: cannot borrow immutable static item `X` as mutable
-  --> $DIR/E0388.rs:5:39
+  --> $DIR/E0388.rs:6:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X;
    |                                       ^^^^^^ cannot borrow as mutable
 
+warning: taking a mutable reference to a `const` item
+  --> $DIR/E0388.rs:9:38
+   |
+LL | static CONST_REF: &'static mut i32 = &mut C;
+   |                                      ^^^^^^
+   |
+   = 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: `const` item defined here
+  --> $DIR/E0388.rs:2:1
+   |
+LL | const C: i32 = 2;
+   | ^^^^^^^^^^^^^^^^^
+
 error[E0764]: mutable references are not allowed in statics
-  --> $DIR/E0388.rs:8:38
+  --> $DIR/E0388.rs:9:38
    |
 LL | static CONST_REF: &'static mut i32 = &mut C;
    |                                      ^^^^^^ `&mut` is only allowed in `const fn`
 
-error: aborting due to 5 previous errors
+error: aborting due to 5 previous errors; 2 warnings emitted
 
 Some errors have detailed explanations: E0019, E0596, E0764.
 For more information about an error, try `rustc --explain E0019`.
diff --git a/src/test/ui/error-codes/E0433.stderr b/src/test/ui/error-codes/E0433.stderr
index d9555e1fcf7..265d8885c8d 100644
--- a/src/test/ui/error-codes/E0433.stderr
+++ b/src/test/ui/error-codes/E0433.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `NonExistingMap`
+error[E0433]: failed to resolve: use of undeclared type `NonExistingMap`
   --> $DIR/E0433.rs:2:15
    |
 LL |     let map = NonExistingMap::new();
-   |               ^^^^^^^^^^^^^^ use of undeclared type or module `NonExistingMap`
+   |               ^^^^^^^^^^^^^^ use of undeclared type `NonExistingMap`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/export-fully-qualified.rs b/src/test/ui/export-fully-qualified.rs
index 99cb558908c..40f26c7095f 100644
--- a/src/test/ui/export-fully-qualified.rs
+++ b/src/test/ui/export-fully-qualified.rs
@@ -1,9 +1,11 @@
+// ignore-tidy-linelength
+
 // In this test baz isn't resolved when called as foo.baz even though
 // it's called from inside foo. This is somewhat surprising and may
 // want to change eventually.
 
 mod foo {
-    pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared type or module `foo`
+    pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared crate or module `foo`
 
     fn baz() { }
 }
diff --git a/src/test/ui/export-fully-qualified.stderr b/src/test/ui/export-fully-qualified.stderr
index c2ec1600868..a8af0c7c9b8 100644
--- a/src/test/ui/export-fully-qualified.stderr
+++ b/src/test/ui/export-fully-qualified.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `foo`
-  --> $DIR/export-fully-qualified.rs:6:20
+error[E0433]: failed to resolve: use of undeclared crate or module `foo`
+  --> $DIR/export-fully-qualified.rs:8:20
    |
 LL |     pub fn bar() { foo::baz(); }
-   |                    ^^^ use of undeclared type or module `foo`
+   |                    ^^^ use of undeclared crate or module `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/export2.rs b/src/test/ui/export2.rs
index 811d96f26d0..64ebeddffa8 100644
--- a/src/test/ui/export2.rs
+++ b/src/test/ui/export2.rs
@@ -1,5 +1,5 @@
 mod foo {
-    pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared type or module `bar`
+    pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared crate or module `bar`
 }
 
 mod bar {
diff --git a/src/test/ui/export2.stderr b/src/test/ui/export2.stderr
index e0cd4404d37..7cf47d0764b 100644
--- a/src/test/ui/export2.stderr
+++ b/src/test/ui/export2.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `bar`
+error[E0433]: failed to resolve: use of undeclared crate or module `bar`
   --> $DIR/export2.rs:2:18
    |
 LL |     pub fn x() { bar::x(); }
-   |                  ^^^ use of undeclared type or module `bar`
+   |                  ^^^ use of undeclared crate or module `bar`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/extern-flag/multiple-opts.stderr b/src/test/ui/extern-flag/multiple-opts.stderr
index 3bf73d11cfd..5088fb1c4d2 100644
--- a/src/test/ui/extern-flag/multiple-opts.stderr
+++ b/src/test/ui/extern-flag/multiple-opts.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `somedep`
+error[E0433]: failed to resolve: use of undeclared crate or module `somedep`
   --> $DIR/multiple-opts.rs:19:5
    |
 LL |     somedep::somefun();
-   |     ^^^^^^^ use of undeclared type or module `somedep`
+   |     ^^^^^^^ use of undeclared crate or module `somedep`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/extern-flag/noprelude.stderr b/src/test/ui/extern-flag/noprelude.stderr
index beb9200ddda..57878721683 100644
--- a/src/test/ui/extern-flag/noprelude.stderr
+++ b/src/test/ui/extern-flag/noprelude.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `somedep`
+error[E0433]: failed to resolve: use of undeclared crate or module `somedep`
   --> $DIR/noprelude.rs:6:5
    |
 LL |     somedep::somefun();
-   |     ^^^^^^^ use of undeclared type or module `somedep`
+   |     ^^^^^^^ use of undeclared crate or module `somedep`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr
index db29a2bddd3..ffec76f409e 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr
@@ -1,28 +1,28 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43106-gating-of-derive.rs:4:1
    |
 LL | #[derive(Debug)]
    | ^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43106-gating-of-derive.rs:7:17
    |
 LL |     mod inner { #![derive(Debug)] }
    |                 ^^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Debug)]`
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43106-gating-of-derive.rs:10:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43106-gating-of-derive.rs:23:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43106-gating-of-derive.rs:27:5
    |
 LL |     #[derive(Debug)]
@@ -30,3 +30,4 @@ LL |     #[derive(Debug)]
 
 error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/generator/static-generators.rs b/src/test/ui/generator/static-generators.rs
index 3980766c428..d098bf1e688 100644
--- a/src/test/ui/generator/static-generators.rs
+++ b/src/test/ui/generator/static-generators.rs
@@ -12,7 +12,7 @@ fn main() {
         yield;
         assert_eq!(b as *const _, &a as *const _);
     };
-    // Safety: We shadow the original generator variable so have no safe API to
+    // SAFETY: We shadow the original generator variable so have no safe API to
     // move it after this point.
     let mut generator = unsafe { Pin::new_unchecked(&mut generator) };
     assert_eq!(generator.as_mut().resume(()), GeneratorState::Yielded(()));
diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs
index 06d62656e95..571017df4d7 100644
--- a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs
+++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.rs
@@ -9,7 +9,7 @@ macro a() {
     mod u {
         // Late resolution.
         fn f() { my_core::mem::drop(0); }
-        //~^ ERROR failed to resolve: use of undeclared type or module `my_core`
+        //~^ ERROR failed to resolve: use of undeclared crate or module `my_core`
     }
 }
 
@@ -22,7 +22,7 @@ mod v {
 mod u {
     // Late resolution.
     fn f() { my_core::mem::drop(0); }
-    //~^ ERROR failed to resolve: use of undeclared type or module `my_core`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `my_core`
 }
 
 fn main() {}
diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr
index b9e05c84a8a..d3e6021a1ed 100644
--- a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr
+++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr
@@ -18,22 +18,22 @@ LL | a!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0433]: failed to resolve: use of undeclared type or module `my_core`
+error[E0433]: failed to resolve: use of undeclared crate or module `my_core`
   --> $DIR/extern-prelude-from-opaque-fail.rs:11:18
    |
 LL |         fn f() { my_core::mem::drop(0); }
-   |                  ^^^^^^^ use of undeclared type or module `my_core`
+   |                  ^^^^^^^ use of undeclared crate or module `my_core`
 ...
 LL | a!();
    | ----- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0433]: failed to resolve: use of undeclared type or module `my_core`
+error[E0433]: failed to resolve: use of undeclared crate or module `my_core`
   --> $DIR/extern-prelude-from-opaque-fail.rs:24:14
    |
 LL |     fn f() { my_core::mem::drop(0); }
-   |              ^^^^^^^ use of undeclared type or module `my_core`
+   |              ^^^^^^^ use of undeclared crate or module `my_core`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 990210ffb6b..3c0c0450774 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -6,7 +6,7 @@ LL |         assert_eq!(0, 0);
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0433]: failed to resolve: use of undeclared type or module `Vec`
+error[E0433]: failed to resolve: use of undeclared type `Vec`
   --> $DIR/no_implicit_prelude.rs:11:9
    |
 LL |     fn f() { ::bar::m!(); }
diff --git a/src/test/ui/impl-trait/issue-56445.rs b/src/test/ui/impl-trait/issue-56445.rs
index a34d7bae3a6..6dd1648c9b8 100644
--- a/src/test/ui/impl-trait/issue-56445.rs
+++ b/src/test/ui/impl-trait/issue-56445.rs
@@ -5,8 +5,7 @@
 
 use std::marker::PhantomData;
 
-pub struct S<'a>
-{
+pub struct S<'a> {
     pub m1: PhantomData<&'a u8>,
     pub m2: [u8; S::size()],
 }
diff --git a/src/test/ui/impl-trait/issue-72911.stderr b/src/test/ui/impl-trait/issue-72911.stderr
index 55fd38f7c0d..17748ae4277 100644
--- a/src/test/ui/impl-trait/issue-72911.stderr
+++ b/src/test/ui/impl-trait/issue-72911.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve: use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared crate or module `foo`
   --> $DIR/issue-72911.rs:12:33
    |
 LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint> {
-   |                                 ^^^ use of undeclared type or module `foo`
+   |                                 ^^^ use of undeclared crate or module `foo`
 
-error[E0433]: failed to resolve: use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared crate or module `foo`
   --> $DIR/issue-72911.rs:17:41
    |
 LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
-   |                                         ^^^ use of undeclared type or module `foo`
+   |                                         ^^^ use of undeclared crate or module `foo`
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/issue-72911.rs:7:24
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.rs b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs
index 6b70efe0c44..4a0c6120201 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-fail.rs
+++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
 // aux-build:two_macros.rs
 // compile-flags:--extern non_existent
 
@@ -7,7 +9,7 @@ mod n {
 
 mod m {
     fn check() {
-        two_macros::m!(); //~ ERROR failed to resolve: use of undeclared type or module `two_macros`
+        two_macros::m!(); //~ ERROR failed to resolve: use of undeclared crate or module `two_macros`
     }
 }
 
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr
index f7544306d34..2d7a1bf468e 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr
+++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr
@@ -1,5 +1,5 @@
 error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
-  --> $DIR/extern-prelude-extern-crate-fail.rs:16:9
+  --> $DIR/extern-prelude-extern-crate-fail.rs:18:9
    |
 LL |         extern crate std as non_existent;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,11 +9,11 @@ LL | define_std_as_non_existent!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0433]: failed to resolve: use of undeclared type or module `two_macros`
-  --> $DIR/extern-prelude-extern-crate-fail.rs:10:9
+error[E0433]: failed to resolve: use of undeclared crate or module `two_macros`
+  --> $DIR/extern-prelude-extern-crate-fail.rs:12:9
    |
 LL |         two_macros::m!();
-   |         ^^^^^^^^^^ use of undeclared type or module `two_macros`
+   |         ^^^^^^^^^^ use of undeclared crate or module `two_macros`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/auxiliary/issue-75907.rs b/src/test/ui/issues/auxiliary/issue-75907.rs
new file mode 100644
index 00000000000..0b70452a24d
--- /dev/null
+++ b/src/test/ui/issues/auxiliary/issue-75907.rs
@@ -0,0 +1,5 @@
+pub struct Bar(pub u8, u8, u8);
+
+pub fn make_bar() -> Bar {
+    Bar(1, 12, 10)
+}
diff --git a/src/test/ui/issues/issue-33293.rs b/src/test/ui/issues/issue-33293.rs
index d3670374284..a6ef007d51f 100644
--- a/src/test/ui/issues/issue-33293.rs
+++ b/src/test/ui/issues/issue-33293.rs
@@ -1,6 +1,6 @@
 fn main() {
     match 0 {
         aaa::bbb(_) => ()
-        //~^ ERROR failed to resolve: use of undeclared type or module `aaa`
+        //~^ ERROR failed to resolve: use of undeclared crate or module `aaa`
     };
 }
diff --git a/src/test/ui/issues/issue-33293.stderr b/src/test/ui/issues/issue-33293.stderr
index 6b7333f22fe..c8450f40042 100644
--- a/src/test/ui/issues/issue-33293.stderr
+++ b/src/test/ui/issues/issue-33293.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `aaa`
+error[E0433]: failed to resolve: use of undeclared crate or module `aaa`
   --> $DIR/issue-33293.rs:3:9
    |
 LL |         aaa::bbb(_) => ()
-   |         ^^^ use of undeclared type or module `aaa`
+   |         ^^^ use of undeclared crate or module `aaa`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-36617.stderr b/src/test/ui/issues/issue-36617.stderr
index 98b41b07ea9..586dcf2cea6 100644
--- a/src/test/ui/issues/issue-36617.stderr
+++ b/src/test/ui/issues/issue-36617.stderr
@@ -1,4 +1,4 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-36617.rs:1:1
    |
 LL | #![derive(Copy)]
@@ -22,3 +22,4 @@ LL | #![derive(Copy)]
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/issues/issue-43023.stderr b/src/test/ui/issues/issue-43023.stderr
index 206a51645fe..f5f51cdcd48 100644
--- a/src/test/ui/issues/issue-43023.stderr
+++ b/src/test/ui/issues/issue-43023.stderr
@@ -1,16 +1,16 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43023.rs:4:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43023.rs:11:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43023.rs:16:5
    |
 LL |     #[derive(Debug)]
@@ -18,3 +18,4 @@ LL |     #[derive(Debug)]
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/issues/issue-49934-errors.stderr b/src/test/ui/issues/issue-49934-errors.stderr
index 8778d88d0eb..3befb38a208 100644
--- a/src/test/ui/issues/issue-49934-errors.stderr
+++ b/src/test/ui/issues/issue-49934-errors.stderr
@@ -1,4 +1,4 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-49934-errors.rs:1:8
    |
 LL | fn foo<#[derive(Debug)] T>() {
@@ -10,7 +10,7 @@ error: expected an inert attribute, found a derive macro
 LL | fn foo<#[derive(Debug)] T>() {
    |                 ^^^^^
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-49934-errors.rs:5:9
    |
 LL |         #[derive(Debug)]
@@ -24,3 +24,4 @@ LL |         #[derive(Debug)]
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/issues/issue-75907.rs b/src/test/ui/issues/issue-75907.rs
new file mode 100644
index 00000000000..8c155d9be35
--- /dev/null
+++ b/src/test/ui/issues/issue-75907.rs
@@ -0,0 +1,18 @@
+// Test for for diagnostic improvement issue #75907
+
+mod foo {
+    pub(crate) struct Foo(u8);
+    pub(crate) struct Bar(pub u8, u8, Foo);
+
+    pub(crate) fn make_bar() -> Bar {
+        Bar(1, 12, Foo(10))
+    }
+}
+
+use foo::{make_bar, Bar, Foo};
+
+fn main() {
+    let Bar(x, y, Foo(z)) = make_bar();
+    //~^ ERROR expected tuple struct
+    //~| ERROR expected tuple struct
+}
diff --git a/src/test/ui/issues/issue-75907.stderr b/src/test/ui/issues/issue-75907.stderr
new file mode 100644
index 00000000000..65b9a51e01d
--- /dev/null
+++ b/src/test/ui/issues/issue-75907.stderr
@@ -0,0 +1,29 @@
+error[E0532]: expected tuple struct or tuple variant, found struct `Bar`
+  --> $DIR/issue-75907.rs:15:9
+   |
+LL |     let Bar(x, y, Foo(z)) = make_bar();
+   |         ^^^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/issue-75907.rs:15:16
+   |
+LL |     let Bar(x, y, Foo(z)) = make_bar();
+   |                ^  ^^^^^^ private field
+   |                |
+   |                private field
+
+error[E0532]: expected tuple struct or tuple variant, found struct `Foo`
+  --> $DIR/issue-75907.rs:15:19
+   |
+LL |     let Bar(x, y, Foo(z)) = make_bar();
+   |                   ^^^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/issue-75907.rs:15:23
+   |
+LL |     let Bar(x, y, Foo(z)) = make_bar();
+   |                       ^ private field
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0532`.
diff --git a/src/test/ui/issues/issue-75907_b.rs b/src/test/ui/issues/issue-75907_b.rs
new file mode 100644
index 00000000000..fdd3bc6d724
--- /dev/null
+++ b/src/test/ui/issues/issue-75907_b.rs
@@ -0,0 +1,11 @@
+// Test for for diagnostic improvement issue #75907, extern crate
+// aux-build:issue-75907.rs
+
+extern crate issue_75907 as a;
+
+use a::{make_bar, Bar};
+
+fn main() {
+    let Bar(x, y, z) = make_bar();
+    //~^ ERROR expected tuple struct
+}
diff --git a/src/test/ui/issues/issue-75907_b.stderr b/src/test/ui/issues/issue-75907_b.stderr
new file mode 100644
index 00000000000..cdd21de6c33
--- /dev/null
+++ b/src/test/ui/issues/issue-75907_b.stderr
@@ -0,0 +1,9 @@
+error[E0532]: expected tuple struct or tuple variant, found struct `Bar`
+  --> $DIR/issue-75907_b.rs:9:9
+   |
+LL |     let Bar(x, y, z) = make_bar();
+   |         ^^^ constructor is not visible here due to private fields
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0532`.
diff --git a/src/test/ui/issues/issue-76077-1.fixed b/src/test/ui/issues/issue-76077-1.fixed
new file mode 100644
index 00000000000..8103a7ca47d
--- /dev/null
+++ b/src/test/ui/issues/issue-76077-1.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+pub mod foo {
+    #[derive(Default)]
+    pub struct Foo { invisible: bool, }
+
+    #[derive(Default)]
+    pub struct Bar { pub visible: bool, invisible: bool, }
+}
+
+fn main() {
+    let foo::Foo { .. } = foo::Foo::default();
+    //~^ ERROR pattern requires `..` due to inaccessible fields
+
+    let foo::Bar { visible, .. } = foo::Bar::default();
+    //~^ ERROR pattern requires `..` due to inaccessible fields
+}
diff --git a/src/test/ui/issues/issue-76077-1.rs b/src/test/ui/issues/issue-76077-1.rs
new file mode 100644
index 00000000000..730332853c1
--- /dev/null
+++ b/src/test/ui/issues/issue-76077-1.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+pub mod foo {
+    #[derive(Default)]
+    pub struct Foo { invisible: bool, }
+
+    #[derive(Default)]
+    pub struct Bar { pub visible: bool, invisible: bool, }
+}
+
+fn main() {
+    let foo::Foo {} = foo::Foo::default();
+    //~^ ERROR pattern requires `..` due to inaccessible fields
+
+    let foo::Bar { visible } = foo::Bar::default();
+    //~^ ERROR pattern requires `..` due to inaccessible fields
+}
diff --git a/src/test/ui/issues/issue-76077-1.stderr b/src/test/ui/issues/issue-76077-1.stderr
new file mode 100644
index 00000000000..4557595529f
--- /dev/null
+++ b/src/test/ui/issues/issue-76077-1.stderr
@@ -0,0 +1,24 @@
+error: pattern requires `..` due to inaccessible fields
+  --> $DIR/issue-76077-1.rs:13:9
+   |
+LL |     let foo::Foo {} = foo::Foo::default();
+   |         ^^^^^^^^^^^
+   |
+help: ignore the inaccessible and unused fields
+   |
+LL |     let foo::Foo { .. } = foo::Foo::default();
+   |                  ^^^^^^
+
+error: pattern requires `..` due to inaccessible fields
+  --> $DIR/issue-76077-1.rs:16:9
+   |
+LL |     let foo::Bar { visible } = foo::Bar::default();
+   |         ^^^^^^^^^^^^^^^^^^^^
+   |
+help: ignore the inaccessible and unused fields
+   |
+LL |     let foo::Bar { visible, .. } = foo::Bar::default();
+   |                           ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issues/issue-76077.rs b/src/test/ui/issues/issue-76077.rs
new file mode 100644
index 00000000000..1ecd37de2e1
--- /dev/null
+++ b/src/test/ui/issues/issue-76077.rs
@@ -0,0 +1,10 @@
+pub mod foo {
+    pub struct Foo {
+        you_cant_use_this_field: bool,
+    }
+}
+
+fn main() {
+    foo::Foo {};
+    //~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields
+}
diff --git a/src/test/ui/issues/issue-76077.stderr b/src/test/ui/issues/issue-76077.stderr
new file mode 100644
index 00000000000..d834ec5e0ed
--- /dev/null
+++ b/src/test/ui/issues/issue-76077.stderr
@@ -0,0 +1,8 @@
+error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
+  --> $DIR/issue-76077.rs:8:5
+   |
+LL |     foo::Foo {};
+   |     ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lazy_normalization_consts/issue-73980.rs b/src/test/ui/lazy_normalization_consts/issue-73980.rs
index 339b22c0b42..e10040652c7 100644
--- a/src/test/ui/lazy_normalization_consts/issue-73980.rs
+++ b/src/test/ui/lazy_normalization_consts/issue-73980.rs
@@ -10,5 +10,7 @@ impl<T: ?Sized> L<T> {
 }
 
 impl<T> X<T, [u8; L::<T>::S]> {}
+//~^ WARN cannot use constants which depend on generic parameters
+//~| WARN this was previously accepted by the compiler but is being phased out
 
 fn main() {}
diff --git a/src/test/ui/lazy_normalization_consts/issue-73980.stderr b/src/test/ui/lazy_normalization_consts/issue-73980.stderr
new file mode 100644
index 00000000000..5ed1ca362f4
--- /dev/null
+++ b/src/test/ui/lazy_normalization_consts/issue-73980.stderr
@@ -0,0 +1,12 @@
+warning: cannot use constants which depend on generic parameters in types
+  --> $DIR/issue-73980.rs:12:9
+   |
+LL | impl<T> X<T, [u8; L::<T>::S]> {}
+   |         ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/lint/lint-const-item-mutation.rs b/src/test/ui/lint/lint-const-item-mutation.rs
new file mode 100644
index 00000000000..92d29a7dae4
--- /dev/null
+++ b/src/test/ui/lint/lint-const-item-mutation.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+struct MyStruct {
+    field: bool,
+    inner_array: [char; 1],
+}
+impl MyStruct {
+    fn use_mut(&mut self) {}
+}
+
+const ARRAY: [u8; 1] = [25];
+const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
+
+fn main() {
+    ARRAY[0] = 5; //~ WARN attempting to modify
+    MY_STRUCT.field = false; //~ WARN attempting to modify
+    MY_STRUCT.inner_array[0] = 'b'; //~ WARN attempting to modify
+    MY_STRUCT.use_mut(); //~ WARN taking
+    &mut MY_STRUCT; //~ WARN taking
+    (&mut MY_STRUCT).use_mut(); //~ WARN taking
+}
diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr
new file mode 100644
index 00000000000..2d8f2c49744
--- /dev/null
+++ b/src/test/ui/lint/lint-const-item-mutation.stderr
@@ -0,0 +1,89 @@
+warning: attempting to modify a `const` item
+  --> $DIR/lint-const-item-mutation.rs:15:5
+   |
+LL |     ARRAY[0] = 5;
+   |     ^^^^^^^^^^^^
+   |
+   = note: `#[warn(const_item_mutation)]` on by default
+   = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
+note: `const` item defined here
+  --> $DIR/lint-const-item-mutation.rs:11:1
+   |
+LL | const ARRAY: [u8; 1] = [25];
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: attempting to modify a `const` item
+  --> $DIR/lint-const-item-mutation.rs:16:5
+   |
+LL |     MY_STRUCT.field = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
+note: `const` item defined here
+  --> $DIR/lint-const-item-mutation.rs:12:1
+   |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: attempting to modify a `const` item
+  --> $DIR/lint-const-item-mutation.rs:17:5
+   |
+LL |     MY_STRUCT.inner_array[0] = 'b';
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified
+note: `const` item defined here
+  --> $DIR/lint-const-item-mutation.rs:12:1
+   |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+  --> $DIR/lint-const-item-mutation.rs:18:5
+   |
+LL |     MY_STRUCT.use_mut();
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+   = 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
+  --> $DIR/lint-const-item-mutation.rs:8:5
+   |
+LL |     fn use_mut(&mut self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^
+note: `const` item defined here
+  --> $DIR/lint-const-item-mutation.rs:12:1
+   |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+  --> $DIR/lint-const-item-mutation.rs:19:5
+   |
+LL |     &mut MY_STRUCT;
+   |     ^^^^^^^^^^^^^^
+   |
+   = 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: `const` item defined here
+  --> $DIR/lint-const-item-mutation.rs:12:1
+   |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: taking a mutable reference to a `const` item
+  --> $DIR/lint-const-item-mutation.rs:20:5
+   |
+LL |     (&mut MY_STRUCT).use_mut();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = 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: `const` item defined here
+  --> $DIR/lint-const-item-mutation.rs:12:1
+   |
+LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'] };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 6 warnings emitted
+
diff --git a/src/test/ui/macros/builtin-prelude-no-accidents.rs b/src/test/ui/macros/builtin-prelude-no-accidents.rs
index ac82f343acc..01691a82dd7 100644
--- a/src/test/ui/macros/builtin-prelude-no-accidents.rs
+++ b/src/test/ui/macros/builtin-prelude-no-accidents.rs
@@ -2,7 +2,7 @@
 // because macros with the same names are in prelude.
 
 fn main() {
-    env::current_dir; //~ ERROR use of undeclared type or module `env`
-    type A = panic::PanicInfo; //~ ERROR use of undeclared type or module `panic`
-    type B = vec::Vec<u8>; //~ ERROR use of undeclared type or module `vec`
+    env::current_dir; //~ ERROR use of undeclared crate or module `env`
+    type A = panic::PanicInfo; //~ ERROR use of undeclared crate or module `panic`
+    type B = vec::Vec<u8>; //~ ERROR use of undeclared crate or module `vec`
 }
diff --git a/src/test/ui/macros/builtin-prelude-no-accidents.stderr b/src/test/ui/macros/builtin-prelude-no-accidents.stderr
index 914e906df58..56af618d484 100644
--- a/src/test/ui/macros/builtin-prelude-no-accidents.stderr
+++ b/src/test/ui/macros/builtin-prelude-no-accidents.stderr
@@ -1,20 +1,20 @@
-error[E0433]: failed to resolve: use of undeclared type or module `env`
+error[E0433]: failed to resolve: use of undeclared crate or module `env`
   --> $DIR/builtin-prelude-no-accidents.rs:5:5
    |
 LL |     env::current_dir;
-   |     ^^^ use of undeclared type or module `env`
+   |     ^^^ use of undeclared crate or module `env`
 
-error[E0433]: failed to resolve: use of undeclared type or module `panic`
+error[E0433]: failed to resolve: use of undeclared crate or module `panic`
   --> $DIR/builtin-prelude-no-accidents.rs:6:14
    |
 LL |     type A = panic::PanicInfo;
-   |              ^^^^^ use of undeclared type or module `panic`
+   |              ^^^^^ use of undeclared crate or module `panic`
 
-error[E0433]: failed to resolve: use of undeclared type or module `vec`
+error[E0433]: failed to resolve: use of undeclared crate or module `vec`
   --> $DIR/builtin-prelude-no-accidents.rs:7:14
    |
 LL |     type B = vec::Vec<u8>;
-   |              ^^^ use of undeclared type or module `vec`
+   |              ^^^ use of undeclared crate or module `vec`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/macros/macro-inner-attributes.rs b/src/test/ui/macros/macro-inner-attributes.rs
index 56a90231566..a8cda23075b 100644
--- a/src/test/ui/macros/macro-inner-attributes.rs
+++ b/src/test/ui/macros/macro-inner-attributes.rs
@@ -15,6 +15,6 @@ test!(b,
 #[rustc_dummy]
 fn main() {
     a::bar();
-    //~^ ERROR failed to resolve: use of undeclared type or module `a`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `a`
     b::bar();
 }
diff --git a/src/test/ui/macros/macro-inner-attributes.stderr b/src/test/ui/macros/macro-inner-attributes.stderr
index 5e20f106a95..8223220d9a4 100644
--- a/src/test/ui/macros/macro-inner-attributes.stderr
+++ b/src/test/ui/macros/macro-inner-attributes.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `a`
+error[E0433]: failed to resolve: use of undeclared crate or module `a`
   --> $DIR/macro-inner-attributes.rs:17:5
    |
 LL |     a::bar();
-   |     ^ use of undeclared type or module `a`
+   |     ^ use of undeclared crate or module `a`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr
index 48c33575ad2..00d954d24f3 100644
--- a/src/test/ui/macros/macro_path_as_generic_bound.stderr
+++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `m`
+error[E0433]: failed to resolve: use of undeclared crate or module `m`
   --> $DIR/macro_path_as_generic_bound.rs:7:6
    |
 LL | foo!(m::m2::A);
-   |      ^ use of undeclared type or module `m`
+   |      ^ use of undeclared crate or module `m`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr
index aec9d1ab191..cecc942f470 100644
--- a/src/test/ui/macros/trace_faulty_macros.stderr
+++ b/src/test/ui/macros/trace_faulty_macros.stderr
@@ -60,7 +60,7 @@ LL |     let a = pat_macro!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/trace_faulty_macros.rs:42:1
    |
 LL | #[derive(Debug)]
@@ -79,3 +79,4 @@ LL |     let a = pat_macro!();
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr b/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr
index e8f96178d10..c4532a375a7 100644
--- a/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr
+++ b/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr
@@ -4,7 +4,7 @@ error: traits in `#[derive(...)]` don't accept arguments
 LL |     #[derive(parse())]
    |                   ^^ help: remove the arguments
 
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-69341-malformed-derive-inert.rs:8:5
    |
 LL |     path: (),
@@ -24,3 +24,4 @@ LL |     #[derive(parse())]
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/mir/issue-76248.rs b/src/test/ui/mir/issue-76248.rs
new file mode 100644
index 00000000000..b01a9727852
--- /dev/null
+++ b/src/test/ui/mir/issue-76248.rs
@@ -0,0 +1,29 @@
+// This used to ICE during codegen after MIR inlining of g into f.
+// The root cause was a missing fold of length constant in Rvalue::Repeat.
+// Regression test for #76248.
+//
+// build-pass
+// compile-flags: -Zmir-opt-level=2
+
+const N: usize = 1;
+
+pub struct Elem<M> {
+    pub x: [usize; N],
+    pub m: M,
+}
+
+pub fn f() -> Elem<()> {
+    g(())
+}
+
+#[inline]
+pub fn g<M>(m: M) -> Elem<M> {
+    Elem {
+        x: [0; N],
+        m,
+    }
+}
+
+pub fn main() {
+    f();
+}
diff --git a/src/test/ui/mod/mod_file_disambig.rs b/src/test/ui/mod/mod_file_disambig.rs
index 7b182421d34..e5958af173b 100644
--- a/src/test/ui/mod/mod_file_disambig.rs
+++ b/src/test/ui/mod/mod_file_disambig.rs
@@ -2,5 +2,5 @@ mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` fou
 
 fn main() {
     assert_eq!(mod_file_aux::bar(), 10);
-    //~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux`
 }
diff --git a/src/test/ui/mod/mod_file_disambig.stderr b/src/test/ui/mod/mod_file_disambig.stderr
index 2cb99b75142..3a3d2e2dddd 100644
--- a/src/test/ui/mod/mod_file_disambig.stderr
+++ b/src/test/ui/mod/mod_file_disambig.stderr
@@ -6,11 +6,11 @@ LL | mod mod_file_disambig_aux;
    |
    = help: delete or rename one of them to remove the ambiguity
 
-error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
+error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux`
   --> $DIR/mod_file_disambig.rs:4:16
    |
 LL |     assert_eq!(mod_file_aux::bar(), 10);
-   |                ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
+   |                ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/mod_file_not_exist.rs b/src/test/ui/parser/mod_file_not_exist.rs
index f4a27b52ec5..7b079eb02dc 100644
--- a/src/test/ui/parser/mod_file_not_exist.rs
+++ b/src/test/ui/parser/mod_file_not_exist.rs
@@ -5,5 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
 
 fn main() {
     assert_eq!(mod_file_aux::bar(), 10);
-    //~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux`
 }
diff --git a/src/test/ui/parser/mod_file_not_exist.stderr b/src/test/ui/parser/mod_file_not_exist.stderr
index 087ae9fe3e0..4e08125625f 100644
--- a/src/test/ui/parser/mod_file_not_exist.stderr
+++ b/src/test/ui/parser/mod_file_not_exist.stderr
@@ -6,11 +6,11 @@ LL | mod not_a_real_file;
    |
    = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
 
-error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
+error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux`
   --> $DIR/mod_file_not_exist.rs:7:16
    |
 LL |     assert_eq!(mod_file_aux::bar(), 10);
-   |                ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
+   |                ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/mod_file_not_exist_windows.rs b/src/test/ui/parser/mod_file_not_exist_windows.rs
index 4b7d7a02bbe..5db21e2bbc7 100644
--- a/src/test/ui/parser/mod_file_not_exist_windows.rs
+++ b/src/test/ui/parser/mod_file_not_exist_windows.rs
@@ -5,5 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
 
 fn main() {
     assert_eq!(mod_file_aux::bar(), 10);
-    //~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux`
 }
diff --git a/src/test/ui/parser/mod_file_not_exist_windows.stderr b/src/test/ui/parser/mod_file_not_exist_windows.stderr
index d67205cfdf1..73cdf098b00 100644
--- a/src/test/ui/parser/mod_file_not_exist_windows.stderr
+++ b/src/test/ui/parser/mod_file_not_exist_windows.stderr
@@ -6,11 +6,11 @@ LL | mod not_a_real_file;
    |
    = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
 
-error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
+error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux`
   --> $DIR/mod_file_not_exist_windows.rs:7:16
    |
 LL |     assert_eq!(mod_file_aux::bar(), 10);
-   |                ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
+   |                ^^^^^^^^^^^^ use of undeclared crate or module `mod_file_aux`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/unsafe-foreign-mod.rs b/src/test/ui/parser/unsafe-foreign-mod.rs
new file mode 100644
index 00000000000..872af95bd22
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod.rs
@@ -0,0 +1,9 @@
+unsafe extern {
+    //~^ ERROR extern block cannot be declared unsafe
+}
+
+unsafe extern "C" {
+    //~^ ERROR extern block cannot be declared unsafe
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-foreign-mod.stderr b/src/test/ui/parser/unsafe-foreign-mod.stderr
new file mode 100644
index 00000000000..5e10988051e
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod.stderr
@@ -0,0 +1,14 @@
+error: extern block cannot be declared unsafe
+  --> $DIR/unsafe-foreign-mod.rs:1:1
+   |
+LL | unsafe extern {
+   | ^^^^^^
+
+error: extern block cannot be declared unsafe
+  --> $DIR/unsafe-foreign-mod.rs:5:1
+   |
+LL | unsafe extern "C" {
+   | ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/unsafe-mod.rs b/src/test/ui/parser/unsafe-mod.rs
new file mode 100644
index 00000000000..7916d878ea5
--- /dev/null
+++ b/src/test/ui/parser/unsafe-mod.rs
@@ -0,0 +1,9 @@
+unsafe mod m {
+    //~^ ERROR module cannot be declared unsafe
+}
+
+unsafe mod n;
+//~^ ERROR module cannot be declared unsafe
+//~^^ ERROR file not found for module `n`
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-mod.stderr b/src/test/ui/parser/unsafe-mod.stderr
new file mode 100644
index 00000000000..259b2c1d61e
--- /dev/null
+++ b/src/test/ui/parser/unsafe-mod.stderr
@@ -0,0 +1,23 @@
+error[E0583]: file not found for module `n`
+  --> $DIR/unsafe-mod.rs:5:1
+   |
+LL | unsafe mod n;
+   | ^^^^^^^^^^^^^
+   |
+   = help: to create the module `n`, create file "$DIR/n.rs"
+
+error: module cannot be declared unsafe
+  --> $DIR/unsafe-mod.rs:1:1
+   |
+LL | unsafe mod m {
+   | ^^^^^^
+
+error: module cannot be declared unsafe
+  --> $DIR/unsafe-mod.rs:5:1
+   |
+LL | unsafe mod n;
+   | ^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/pattern/pattern-error-continue.rs b/src/test/ui/pattern/pattern-error-continue.rs
index 8635622ab37..0702a9986fc 100644
--- a/src/test/ui/pattern/pattern-error-continue.rs
+++ b/src/test/ui/pattern/pattern-error-continue.rs
@@ -30,6 +30,6 @@ fn main() {
     //~| expected `char`, found `bool`
 
     match () {
-        E::V => {} //~ ERROR failed to resolve: use of undeclared type or module `E`
+        E::V => {} //~ ERROR failed to resolve: use of undeclared type `E`
     }
 }
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index 60f76796c03..497c93b2949 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `E`
+error[E0433]: failed to resolve: use of undeclared type `E`
   --> $DIR/pattern-error-continue.rs:33:9
    |
 LL |         E::V => {}
-   |         ^ use of undeclared type or module `E`
+   |         ^ use of undeclared type `E`
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `A::D`
   --> $DIR/pattern-error-continue.rs:18:9
diff --git a/src/test/ui/proc-macro/attributes-on-modules-fail.stderr b/src/test/ui/proc-macro/attributes-on-modules-fail.stderr
index 97b2f22e161..7141a1b50b5 100644
--- a/src/test/ui/proc-macro/attributes-on-modules-fail.stderr
+++ b/src/test/ui/proc-macro/attributes-on-modules-fail.stderr
@@ -1,4 +1,4 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/attributes-on-modules-fail.rs:16:1
    |
 LL | #[derive(Copy)]
@@ -64,5 +64,5 @@ LL | use m::X;
 
 error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0412, E0658.
+Some errors have detailed explanations: E0412, E0658, E0774.
 For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs b/src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs
new file mode 100644
index 00000000000..c72306c3d50
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs
@@ -0,0 +1,89 @@
+// force-host
+// no-prefer-dynamic
+
+// These are tests for syntax that is accepted by the Rust parser but
+// unconditionally rejected semantically after macro expansion. Attribute macros
+// are permitted to accept such syntax as long as they replace it with something
+// that makes sense to Rust.
+//
+// We also inspect some of the spans to verify the syntax is not triggering the
+// lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081).
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro_span)]
+
+extern crate proc_macro;
+use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree};
+use std::path::Component;
+
+// unsafe mod m {
+//     pub unsafe mod inner;
+// }
+#[proc_macro_attribute]
+pub fn expect_unsafe_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
+    let tokens = &mut input.into_iter();
+    expect(tokens, "unsafe");
+    expect(tokens, "mod");
+    expect(tokens, "m");
+    let tokens = &mut expect_brace(tokens);
+    expect(tokens, "pub");
+    expect(tokens, "unsafe");
+    expect(tokens, "mod");
+    let ident = expect(tokens, "inner");
+    expect(tokens, ";");
+    check_useful_span(ident, "unsafe-mod.rs");
+    TokenStream::new()
+}
+
+// unsafe extern {
+//     type T;
+// }
+#[proc_macro_attribute]
+pub fn expect_unsafe_foreign_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
+    let tokens = &mut input.into_iter();
+    expect(tokens, "unsafe");
+    expect(tokens, "extern");
+    let tokens = &mut expect_brace(tokens);
+    expect(tokens, "type");
+    let ident = expect(tokens, "T");
+    expect(tokens, ";");
+    check_useful_span(ident, "unsafe-foreign-mod.rs");
+    TokenStream::new()
+}
+
+// unsafe extern "C++" {}
+#[proc_macro_attribute]
+pub fn expect_unsafe_extern_cpp_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
+    let tokens = &mut input.into_iter();
+    expect(tokens, "unsafe");
+    expect(tokens, "extern");
+    let abi = expect(tokens, "\"C++\"");
+    expect_brace(tokens);
+    check_useful_span(abi, "unsafe-foreign-mod.rs");
+    TokenStream::new()
+}
+
+fn expect(tokens: &mut token_stream::IntoIter, expected: &str) -> TokenTree {
+    match tokens.next() {
+        Some(token) if token.to_string() == expected => token,
+        wrong => panic!("unexpected token: {:?}, expected `{}`", wrong, expected),
+    }
+}
+
+fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {
+    match tokens.next() {
+        Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Brace => {
+            group.stream().into_iter()
+        }
+        wrong => panic!("unexpected token: {:?}, expected `{{`", wrong),
+    }
+}
+
+fn check_useful_span(token: TokenTree, expected_filename: &str) {
+    let span = token.span();
+    assert!(span.start().column < span.end().column);
+
+    let source_path = span.source_file().path();
+    let filename = source_path.components().last().unwrap();
+    assert_eq!(filename, Component::Normal(expected_filename.as_ref()));
+}
diff --git a/src/test/ui/proc-macro/capture-macro-rules-invoke.rs b/src/test/ui/proc-macro/capture-macro-rules-invoke.rs
index 2ff6ad6d68f..de008a3708a 100644
--- a/src/test/ui/proc-macro/capture-macro-rules-invoke.rs
+++ b/src/test/ui/proc-macro/capture-macro-rules-invoke.rs
@@ -1,10 +1,20 @@
 // aux-build:test-macros.rs
 // check-pass
 // compile-flags: -Z span-debug
-// normalize-stdout-test "#\d+" -> "#CTXT"
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
 
 extern crate test_macros;
-use test_macros::print_bang;
+use test_macros::{print_bang, print_bang_consume};
+
+macro_rules! test_matchers {
+    ($expr:expr, $block:block, $stmt:stmt, $ty:ty, $ident:ident, $lifetime:lifetime,
+     $meta:meta, $path:path, $vis:vis, $tt:tt, $lit:literal) => {
+        print_bang_consume!($expr, $block, $stmt, $ty, $ident,
+                            $lifetime, $meta, $path, $vis, $tt, $lit)
+    }
+}
 
 macro_rules! use_expr {
     ($expr:expr) => {
@@ -24,10 +34,23 @@ impl Foo {
     #[allow(dead_code)]
     fn use_self(self) {
         drop(use_expr!(self));
+        test_matchers!(
+            1 + 1,
+            { "a" },
+            let a = 1,
+            String,
+            my_name,
+            'a,
+            my_val = 30,
+            std::option::Option,
+            pub(in some::path),
+            [ a b c ],
+            -30
+        );
     }
 
     fn with_pat(use_pat!((a, b)): (u32, u32)) {
-        println!("Args: {} {}", a, b);
+        let _ = (a, b);
     }
 }
 
diff --git a/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout b/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
index 28812e20548..652bf6b6b22 100644
--- a/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
+++ b/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout
@@ -5,10 +5,299 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
         stream: TokenStream [
             Ident {
                 ident: "self",
-                span: $DIR/capture-macro-rules-invoke.rs:26:24: 26:28 (#CTXT),
+                span: $DIR/capture-macro-rules-invoke.rs:36:24: 36:28 (#0),
             },
         ],
-        span: $DIR/capture-macro-rules-invoke.rs:11:21: 11:26 (#CTXT),
+        span: $DIR/capture-macro-rules-invoke.rs:21:21: 21:26 (#3),
+    },
+]
+PRINT-BANG INPUT (DISPLAY): 1 + 1, { "a" }, let a = 1;, String, my_name, 'a, my_val = 30,
+std::option::Option, pub(in some::path) , [a b c], -30
+PRINT-BANG RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30,
+std :: option :: Option, pub(in some :: path), [a b c], - 30
+PRINT-BANG INPUT (DEBUG): TokenStream [
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Literal {
+                kind: Integer,
+                symbol: "1",
+                suffix: None,
+                span: $DIR/capture-macro-rules-invoke.rs:38:13: 38:14 (#0),
+            },
+            Punct {
+                ch: '+',
+                spacing: Alone,
+                span: $DIR/capture-macro-rules-invoke.rs:38:15: 38:16 (#0),
+            },
+            Literal {
+                kind: Integer,
+                symbol: "1",
+                suffix: None,
+                span: $DIR/capture-macro-rules-invoke.rs:38:17: 38:18 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:14:29: 14:34 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:14:34: 14:35 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Group {
+                delimiter: Brace,
+                stream: TokenStream [
+                    Literal {
+                        kind: Str,
+                        symbol: "a",
+                        suffix: None,
+                        span: $DIR/capture-macro-rules-invoke.rs:39:15: 39:18 (#0),
+                    },
+                ],
+                span: $DIR/capture-macro-rules-invoke.rs:39:13: 39:20 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:14:36: 14:42 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:14:42: 14:43 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "let",
+                span: $DIR/capture-macro-rules-invoke.rs:40:13: 40:16 (#0),
+            },
+            Ident {
+                ident: "a",
+                span: $DIR/capture-macro-rules-invoke.rs:40:17: 40:18 (#0),
+            },
+            Punct {
+                ch: '=',
+                spacing: Alone,
+                span: $DIR/capture-macro-rules-invoke.rs:40:19: 40:20 (#0),
+            },
+            Literal {
+                kind: Integer,
+                symbol: "1",
+                suffix: None,
+                span: $DIR/capture-macro-rules-invoke.rs:40:21: 40:22 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:14:44: 14:49 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:14:49: 14:50 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "String",
+                span: $DIR/capture-macro-rules-invoke.rs:41:13: 41:19 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:14:51: 14:54 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:14:54: 14:55 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "my_name",
+                span: $DIR/capture-macro-rules-invoke.rs:42:13: 42:20 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:14:56: 14:62 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:14:62: 14:63 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Punct {
+                ch: '\'',
+                spacing: Joint,
+                span: $DIR/capture-macro-rules-invoke.rs:43:13: 43:15 (#0),
+            },
+            Ident {
+                ident: "a",
+                span: $DIR/capture-macro-rules-invoke.rs:43:13: 43:15 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:15:29: 15:38 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:15:38: 15:39 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "my_val",
+                span: $DIR/capture-macro-rules-invoke.rs:44:13: 44:19 (#0),
+            },
+            Punct {
+                ch: '=',
+                spacing: Alone,
+                span: $DIR/capture-macro-rules-invoke.rs:44:20: 44:21 (#0),
+            },
+            Literal {
+                kind: Integer,
+                symbol: "30",
+                suffix: None,
+                span: $DIR/capture-macro-rules-invoke.rs:44:22: 44:24 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:15:40: 15:45 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:15:45: 15:46 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "std",
+                span: $DIR/capture-macro-rules-invoke.rs:45:13: 45:16 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Joint,
+                span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:18 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:18 (#0),
+            },
+            Ident {
+                ident: "option",
+                span: $DIR/capture-macro-rules-invoke.rs:45:18: 45:24 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Joint,
+                span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:26 (#0),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:26 (#0),
+            },
+            Ident {
+                ident: "Option",
+                span: $DIR/capture-macro-rules-invoke.rs:45:26: 45:32 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:15:47: 15:52 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:15:52: 15:53 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "pub",
+                span: $DIR/capture-macro-rules-invoke.rs:46:13: 46:16 (#0),
+            },
+            Group {
+                delimiter: Parenthesis,
+                stream: TokenStream [
+                    Ident {
+                        ident: "in",
+                        span: $DIR/capture-macro-rules-invoke.rs:46:17: 46:19 (#0),
+                    },
+                    Ident {
+                        ident: "some",
+                        span: $DIR/capture-macro-rules-invoke.rs:46:20: 46:24 (#0),
+                    },
+                    Punct {
+                        ch: ':',
+                        spacing: Joint,
+                        span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:26 (#0),
+                    },
+                    Punct {
+                        ch: ':',
+                        spacing: Alone,
+                        span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:26 (#0),
+                    },
+                    Ident {
+                        ident: "path",
+                        span: $DIR/capture-macro-rules-invoke.rs:46:26: 46:30 (#0),
+                    },
+                ],
+                span: $DIR/capture-macro-rules-invoke.rs:46:16: 46:31 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:15:54: 15:58 (#7),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:15:58: 15:59 (#7),
+    },
+    Group {
+        delimiter: Bracket,
+        stream: TokenStream [
+            Ident {
+                ident: "a",
+                span: $DIR/capture-macro-rules-invoke.rs:47:15: 47:16 (#0),
+            },
+            Ident {
+                ident: "b",
+                span: $DIR/capture-macro-rules-invoke.rs:47:17: 47:18 (#0),
+            },
+            Ident {
+                ident: "c",
+                span: $DIR/capture-macro-rules-invoke.rs:47:19: 47:20 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:47:13: 47:22 (#0),
+    },
+    Punct {
+        ch: ',',
+        spacing: Alone,
+        span: $DIR/capture-macro-rules-invoke.rs:15:63: 15:64 (#7),
+    },
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Punct {
+                ch: '-',
+                spacing: Alone,
+                span: $DIR/capture-macro-rules-invoke.rs:48:13: 48:14 (#0),
+            },
+            Literal {
+                kind: Integer,
+                symbol: "30",
+                suffix: None,
+                span: $DIR/capture-macro-rules-invoke.rs:48:14: 48:16 (#0),
+            },
+        ],
+        span: $DIR/capture-macro-rules-invoke.rs:15:65: 15:69 (#7),
     },
 ]
 PRINT-BANG INPUT (DISPLAY): (a, b)
@@ -21,21 +310,21 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
                 stream: TokenStream [
                     Ident {
                         ident: "a",
-                        span: $DIR/capture-macro-rules-invoke.rs:29:27: 29:28 (#CTXT),
+                        span: $DIR/capture-macro-rules-invoke.rs:52:27: 52:28 (#0),
                     },
                     Punct {
                         ch: ',',
                         spacing: Alone,
-                        span: $DIR/capture-macro-rules-invoke.rs:29:28: 29:29 (#CTXT),
+                        span: $DIR/capture-macro-rules-invoke.rs:52:28: 52:29 (#0),
                     },
                     Ident {
                         ident: "b",
-                        span: $DIR/capture-macro-rules-invoke.rs:29:30: 29:31 (#CTXT),
+                        span: $DIR/capture-macro-rules-invoke.rs:52:30: 52:31 (#0),
                     },
                 ],
-                span: $DIR/capture-macro-rules-invoke.rs:29:26: 29:32 (#CTXT),
+                span: $DIR/capture-macro-rules-invoke.rs:52:26: 52:32 (#0),
             },
         ],
-        span: $DIR/capture-macro-rules-invoke.rs:17:21: 17:25 (#CTXT),
+        span: $DIR/capture-macro-rules-invoke.rs:27:21: 27:25 (#11),
     },
 ]
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
index 35c101587de..bc82a2ff196 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
@@ -13,18 +13,37 @@ extern crate std;
 // place of a `None`-delimited group. This allows us to maintain
 // backwards compatibility for older versions of these crates.
 
-include!("js-sys/src/lib.rs");
-include!("time-macros-impl/src/lib.rs");
+mod no_version {
+    include!("js-sys/src/lib.rs");
+    include!("time-macros-impl/src/lib.rs");
 
-macro_rules! other {
-    ($name:ident) => {
-        #[my_macro] struct Three($name);
+    macro_rules! other {
+        ($name:ident) => {
+            #[my_macro] struct Three($name);
+        }
     }
+
+    struct Foo;
+    impl_macros!(Foo);
+    arrays!(Foo);
+    other!(Foo);
 }
 
-fn main() {
+mod with_version {
+    include!("js-sys-0.3.17/src/lib.rs");
+    include!("time-macros-impl-0.1.0/src/lib.rs");
+
+    macro_rules! other {
+        ($name:ident) => {
+            #[my_macro] struct Three($name);
+        }
+    }
+
     struct Foo;
     impl_macros!(Foo);
     arrays!(Foo);
     other!(Foo);
 }
+
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
index d519daab1f2..e7645280a75 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
@@ -1,3 +1,6 @@
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl/src/lib.rs:5:21: 5:27 (#5) }, Ident { ident: "One", span: $DIR/time-macros-impl/src/lib.rs:5:28: 5:31 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:27:18: 27:21 (#0) }], span: $DIR/time-macros-impl/src/lib.rs:5:31: 5:38 (#5) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl/src/lib.rs:5:38: 5:39 (#5) }]
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#9) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#9) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:28:13: 28:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#9) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#9) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:21:21: 21:27 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:21:28: 21:33 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:21:34: 21:39 (#13) }], span: $DIR/group-compat-hack.rs:21:33: 21:40 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:21:40: 21:41 (#13) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:22:25: 22:31 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:22:32: 22:37 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:22:38: 22:43 (#13) }], span: $DIR/group-compat-hack.rs:22:37: 22:44 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:22:44: 22:45 (#13) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#19) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#19) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:43:18: 43:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#19) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#19) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#23) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#23) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:13: 44:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#23) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#23) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:38:25: 38:31 (#27) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:38:32: 38:37 (#27) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:45:12: 45:15 (#0) }], span: $DIR/group-compat-hack.rs:38:38: 38:43 (#27) }], span: $DIR/group-compat-hack.rs:38:37: 38:44 (#27) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:38:44: 38:45 (#27) }]
diff --git a/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs
new file mode 100644
index 00000000000..d1a66940ebf
--- /dev/null
+++ b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs
@@ -0,0 +1,7 @@
+// ignore-test this is not a test
+
+macro_rules! arrays {
+    ($name:ident) => {
+        #[my_macro] struct Two($name);
+    }
+}
diff --git a/src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs b/src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs
new file mode 100644
index 00000000000..c94c3579209
--- /dev/null
+++ b/src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs
@@ -0,0 +1,7 @@
+// ignore-test this is not a test
+
+macro_rules! impl_macros {
+    ($name:ident) => {
+        #[my_macro] struct One($name);
+    }
+}
diff --git a/src/test/ui/proc-macro/macros-in-extern-derive.stderr b/src/test/ui/proc-macro/macros-in-extern-derive.stderr
index e2afb7d34c1..6b737449209 100644
--- a/src/test/ui/proc-macro/macros-in-extern-derive.stderr
+++ b/src/test/ui/proc-macro/macros-in-extern-derive.stderr
@@ -1,4 +1,4 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/macros-in-extern-derive.rs:2:5
    |
 LL |     #[derive(Copy)]
@@ -6,3 +6,4 @@ LL |     #[derive(Copy)]
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/proc-macro/unsafe-foreign-mod.rs b/src/test/ui/proc-macro/unsafe-foreign-mod.rs
new file mode 100644
index 00000000000..7bdfa93c21f
--- /dev/null
+++ b/src/test/ui/proc-macro/unsafe-foreign-mod.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:macro-only-syntax.rs
+
+extern crate macro_only_syntax;
+
+#[macro_only_syntax::expect_unsafe_foreign_mod]
+unsafe extern {
+    type T;
+}
+
+#[macro_only_syntax::expect_unsafe_extern_cpp_mod]
+unsafe extern "C++" {}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/unsafe-mod.rs b/src/test/ui/proc-macro/unsafe-mod.rs
new file mode 100644
index 00000000000..8ff6e352c53
--- /dev/null
+++ b/src/test/ui/proc-macro/unsafe-mod.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:macro-only-syntax.rs
+
+#![feature(proc_macro_hygiene)]
+
+extern crate macro_only_syntax;
+
+#[macro_only_syntax::expect_unsafe_mod]
+unsafe mod m {
+    pub unsafe mod inner;
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/use_suggestion.stderr b/src/test/ui/resolve/use_suggestion.stderr
index 72dda940729..4fff179b1fe 100644
--- a/src/test/ui/resolve/use_suggestion.stderr
+++ b/src/test/ui/resolve/use_suggestion.stderr
@@ -1,10 +1,10 @@
-error[E0433]: failed to resolve: use of undeclared type or module `GooMap`
+error[E0433]: failed to resolve: use of undeclared type `GooMap`
   --> $DIR/use_suggestion.rs:3:14
    |
 LL |     let x2 = GooMap::new();
-   |              ^^^^^^ use of undeclared type or module `GooMap`
+   |              ^^^^^^ use of undeclared type `GooMap`
 
-error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
+error[E0433]: failed to resolve: use of undeclared type `HashMap`
   --> $DIR/use_suggestion.rs:2:14
    |
 LL |     let x1 = HashMap::new();
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr
index 64b920e9aa7..81891572179 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `xcrate`
   --> $DIR/non-existent-1.rs:3:5
    |
 LL | use xcrate::S;
-   |     ^^^^^^ use of undeclared type or module `xcrate`
+   |     ^^^^^^ use of undeclared crate or module `xcrate`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.stderr b/src/test/ui/span/issue-43927-non-ADT-derive.stderr
index b68681c5297..b160a4e5877 100644
--- a/src/test/ui/span/issue-43927-non-ADT-derive.stderr
+++ b/src/test/ui/span/issue-43927-non-ADT-derive.stderr
@@ -1,4 +1,4 @@
-error: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43927-non-ADT-derive.rs:3:1
    |
 LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
@@ -54,3 +54,4 @@ LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
 
 error: aborting due to 7 previous errors
 
+For more information about this error, try `rustc --explain E0774`.
diff --git a/src/test/ui/str-concat.rs b/src/test/ui/str-concat.rs
deleted file mode 100644
index fa2fc97d7b8..00000000000
--- a/src/test/ui/str-concat.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-
-pub fn main() {
-    let a: String = "hello".to_string();
-    let b: String = "world".to_string();
-    let s: String = format!("{}{}", a, b);
-    println!("{}", s.clone());
-    assert_eq!(s.as_bytes()[9], 'd' as u8);
-}
diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr
index ef7ce735868..f323ba03c01 100644
--- a/src/test/ui/str/str-idx.stderr
+++ b/src/test/ui/str/str-idx.stderr
@@ -6,7 +6,7 @@ LL |     let _: u8 = s[4];
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
-           see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+           for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
    = note: required because of the requirements on the impl of `Index<{integer}>` for `str`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -17,7 +17,7 @@ LL |     let _ = s.get(4);
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
-           see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+           for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-idx.rs:5:29
@@ -27,7 +27,7 @@ LL |     let _ = s.get_unchecked(4);
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
-           see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+           for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
 
 error[E0277]: the type `str` cannot be indexed by `char`
   --> $DIR/str-idx.rs:6:17
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index abb9b09cf38..405542820a3 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -39,7 +39,7 @@ LL |     s.get_mut(1);
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
-           see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+           for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
   --> $DIR/str-mut-idx.rs:11:25
@@ -49,7 +49,7 @@ LL |     s.get_unchecked_mut(1);
    |
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
-           see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+           for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
 
 error[E0277]: the type `str` cannot be indexed by `char`
   --> $DIR/str-mut-idx.rs:13:5
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.rs b/src/test/ui/suggestions/type-ascription-instead-of-path.rs
index e92087e2947..ce40b55f1ee 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-path.rs
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path.rs
@@ -1,5 +1,5 @@
 fn main() {
     std:io::stdin();
-    //~^ ERROR failed to resolve: use of undeclared type or module `io`
+    //~^ ERROR failed to resolve: use of undeclared crate or module `io`
     //~| ERROR expected value, found crate
 }
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr
index fd2fedc7640..518660cfa16 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `io`
+error[E0433]: failed to resolve: use of undeclared crate or module `io`
   --> $DIR/type-ascription-instead-of-path.rs:2:9
    |
 LL |     std:io::stdin();
-   |         ^^ use of undeclared type or module `io`
+   |         ^^ use of undeclared crate or module `io`
 
 error[E0423]: expected value, found crate `std`
   --> $DIR/type-ascription-instead-of-path.rs:2:5
diff --git a/src/test/ui/try-block/try-block-in-return.rs b/src/test/ui/try-block/try-block-in-return.rs
new file mode 100644
index 00000000000..a15bfeef1c1
--- /dev/null
+++ b/src/test/ui/try-block/try-block-in-return.rs
@@ -0,0 +1,12 @@
+// run-pass
+// compile-flags: --edition 2018
+
+#![feature(try_blocks)]
+
+fn issue_76271() -> Option<i32> {
+    return try { 4 }
+}
+
+fn main() {
+    assert_eq!(issue_76271(), Some(4));
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs
new file mode 100644
index 00000000000..e643a8cab5b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-72793.rs
@@ -0,0 +1,27 @@
+// build-pass
+
+// Regression test for #72793.
+// FIXME: This still shows ICE with `-Zmir-opt-level=2`.
+
+#![feature(type_alias_impl_trait)]
+
+trait T { type Item; }
+
+type Alias<'a> = impl T<Item = &'a ()>;
+
+struct S;
+impl<'a> T for &'a S {
+    type Item = &'a ();
+}
+
+fn filter_positive<'a>() -> Alias<'a> {
+    &S
+}
+
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+    fun(filter_positive());
+}
+
+fn main() {
+    with_positive(|_| ());
+}
diff --git a/src/test/ui/type-alias/issue-62263-self-in-atb.rs b/src/test/ui/type-alias/issue-62263-self-in-atb.rs
index 5e812db4d23..1f64b4cfe5c 100644
--- a/src/test/ui/type-alias/issue-62263-self-in-atb.rs
+++ b/src/test/ui/type-alias/issue-62263-self-in-atb.rs
@@ -3,6 +3,6 @@ pub trait Trait {
 }
 
 pub type Alias = dyn Trait<A = Self::A>;
-//~^ ERROR failed to resolve: use of undeclared type or module `Self` [E0433]
+//~^ ERROR failed to resolve: use of undeclared type `Self` [E0433]
 
 fn main() {}
diff --git a/src/test/ui/type-alias/issue-62263-self-in-atb.stderr b/src/test/ui/type-alias/issue-62263-self-in-atb.stderr
index a642d029f93..d34b6ed5038 100644
--- a/src/test/ui/type-alias/issue-62263-self-in-atb.stderr
+++ b/src/test/ui/type-alias/issue-62263-self-in-atb.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `Self`
+error[E0433]: failed to resolve: use of undeclared type `Self`
   --> $DIR/issue-62263-self-in-atb.rs:5:32
    |
 LL | pub type Alias = dyn Trait<A = Self::A>;
-   |                                ^^^^ use of undeclared type or module `Self`
+   |                                ^^^^ use of undeclared type `Self`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs b/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs
index 0b95ddeb19e..999902fb18b 100644
--- a/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs
+++ b/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs
@@ -1,4 +1,4 @@
 type Alias = Self::Target;
-//~^ ERROR failed to resolve: use of undeclared type or module `Self` [E0433]
+//~^ ERROR failed to resolve: use of undeclared type `Self` [E0433]
 
 fn main() {}
diff --git a/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr b/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr
index 6eb445e9dbc..823a5fa50fc 100644
--- a/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr
+++ b/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `Self`
+error[E0433]: failed to resolve: use of undeclared type `Self`
   --> $DIR/issue-62305-self-assoc-ty.rs:1:14
    |
 LL | type Alias = Self::Target;
-   |              ^^^^ use of undeclared type or module `Self`
+   |              ^^^^ use of undeclared type `Self`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-path-err-node-types.rs b/src/test/ui/type/type-path-err-node-types.rs
index 15adfebb334..b3795772e6f 100644
--- a/src/test/ui/type/type-path-err-node-types.rs
+++ b/src/test/ui/type/type-path-err-node-types.rs
@@ -12,7 +12,7 @@ fn ufcs_trait() {
 }
 
 fn ufcs_item() {
-    NonExistent::Assoc::<u8>; //~ ERROR undeclared type or module `NonExistent`
+    NonExistent::Assoc::<u8>; //~ ERROR undeclared type `NonExistent`
 }
 
 fn method() {
diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr
index ea9cca2bfaa..baf218243c4 100644
--- a/src/test/ui/type/type-path-err-node-types.stderr
+++ b/src/test/ui/type/type-path-err-node-types.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `NonExistent`
+error[E0433]: failed to resolve: use of undeclared type `NonExistent`
   --> $DIR/type-path-err-node-types.rs:15:5
    |
 LL |     NonExistent::Assoc::<u8>;
-   |     ^^^^^^^^^^^ use of undeclared type or module `NonExistent`
+   |     ^^^^^^^^^^^ use of undeclared type `NonExistent`
 
 error[E0412]: cannot find type `Nonexistent` in this scope
   --> $DIR/type-path-err-node-types.rs:7:12
diff --git a/src/test/ui/union/union-deref.rs b/src/test/ui/union/union-deref.rs
new file mode 100644
index 00000000000..df598eea9ef
--- /dev/null
+++ b/src/test/ui/union/union-deref.rs
@@ -0,0 +1,28 @@
+// ignore-tidy-linelength
+//! Test the part of RFC 2514 that is about not applying `DerefMut` coercions
+//! of union fields.
+#![feature(untagged_unions)]
+
+use std::mem::ManuallyDrop;
+
+union U1<T> { x:(), f: ManuallyDrop<(T,)> }
+
+union U2<T> { x:(), f: (ManuallyDrop<(T,)>,) }
+
+fn main() {
+    let mut u : U1<Vec<i32>> = U1 { x: () };
+    unsafe { (*u.f).0 = Vec::new() }; // explicit deref, this compiles
+    unsafe { u.f.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
+    unsafe { &mut (*u.f).0 }; // explicit deref, this compiles
+    unsafe { &mut u.f.0 }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
+    unsafe { (*u.f).0.push(0) }; // explicit deref, this compiles
+    unsafe { u.f.0.push(0) }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
+
+    let mut u : U2<Vec<i32>> = U2 { x: () };
+    unsafe { (*u.f.0).0 = Vec::new() }; // explicit deref, this compiles
+    unsafe { u.f.0.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
+    unsafe { &mut (*u.f.0).0 }; // explicit deref, this compiles
+    unsafe { &mut u.f.0.0 }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
+    unsafe { (*u.f.0).0.push(0) }; // explicit deref, this compiles
+    unsafe { u.f.0.0.push(0) }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
+}
diff --git a/src/test/ui/union/union-deref.stderr b/src/test/ui/union/union-deref.stderr
new file mode 100644
index 00000000000..fb16649767f
--- /dev/null
+++ b/src/test/ui/union/union-deref.stderr
@@ -0,0 +1,56 @@
+error: not automatically applying `DerefMut` on `ManuallyDrop` union field
+  --> $DIR/union-deref.rs:15:14
+   |
+LL |     unsafe { u.f.0 = Vec::new() };
+   |              ^^^
+   |
+   = help: writing to this reference calls the destructor for the old value
+   = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
+
+error: not automatically applying `DerefMut` on `ManuallyDrop` union field
+  --> $DIR/union-deref.rs:17:19
+   |
+LL |     unsafe { &mut u.f.0 };
+   |                   ^^^
+   |
+   = help: writing to this reference calls the destructor for the old value
+   = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
+
+error: not automatically applying `DerefMut` on `ManuallyDrop` union field
+  --> $DIR/union-deref.rs:19:14
+   |
+LL |     unsafe { u.f.0.push(0) };
+   |              ^^^
+   |
+   = help: writing to this reference calls the destructor for the old value
+   = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
+
+error: not automatically applying `DerefMut` on `ManuallyDrop` union field
+  --> $DIR/union-deref.rs:23:14
+   |
+LL |     unsafe { u.f.0.0 = Vec::new() };
+   |              ^^^^^^^
+   |
+   = help: writing to this reference calls the destructor for the old value
+   = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
+
+error: not automatically applying `DerefMut` on `ManuallyDrop` union field
+  --> $DIR/union-deref.rs:25:19
+   |
+LL |     unsafe { &mut u.f.0.0 };
+   |                   ^^^^^^^
+   |
+   = help: writing to this reference calls the destructor for the old value
+   = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
+
+error: not automatically applying `DerefMut` on `ManuallyDrop` union field
+  --> $DIR/union-deref.rs:27:14
+   |
+LL |     unsafe { u.f.0.0.push(0) };
+   |              ^^^^^^^
+   |
+   = help: writing to this reference calls the destructor for the old value
+   = help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/unknown-tool-name.rs b/src/test/ui/unknown-tool-name.rs
index 05f99ced687..73fca61c65d 100644
--- a/src/test/ui/unknown-tool-name.rs
+++ b/src/test/ui/unknown-tool-name.rs
@@ -1,2 +1,2 @@
-#[foo::bar] //~ ERROR failed to resolve: use of undeclared type or module `foo`
+#[foo::bar] //~ ERROR failed to resolve: use of undeclared crate or module `foo`
 fn main() {}
diff --git a/src/test/ui/unknown-tool-name.stderr b/src/test/ui/unknown-tool-name.stderr
index 7a6ed57bda6..4a1370ba80a 100644
--- a/src/test/ui/unknown-tool-name.stderr
+++ b/src/test/ui/unknown-tool-name.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared crate or module `foo`
   --> $DIR/unknown-tool-name.rs:1:3
    |
 LL | #[foo::bar]
-   |   ^^^ use of undeclared type or module `foo`
+   |   ^^^ use of undeclared crate or module `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/use/use-self-type.rs b/src/test/ui/use/use-self-type.rs
index 3e5c7bf3cca..370593b2eb2 100644
--- a/src/test/ui/use/use-self-type.rs
+++ b/src/test/ui/use/use-self-type.rs
@@ -4,7 +4,7 @@ impl S {
     fn f() {}
     fn g() {
         use Self::f; //~ ERROR unresolved import
-        pub(in Self::f) struct Z; //~ ERROR use of undeclared type or module `Self`
+        pub(in Self::f) struct Z; //~ ERROR use of undeclared type `Self`
     }
 }
 
diff --git a/src/test/ui/use/use-self-type.stderr b/src/test/ui/use/use-self-type.stderr
index 0dd0e04267c..d1469fb3490 100644
--- a/src/test/ui/use/use-self-type.stderr
+++ b/src/test/ui/use/use-self-type.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve: use of undeclared type or module `Self`
+error[E0433]: failed to resolve: use of undeclared type `Self`
   --> $DIR/use-self-type.rs:7:16
    |
 LL |         pub(in Self::f) struct Z;
-   |                ^^^^ use of undeclared type or module `Self`
+   |                ^^^^ use of undeclared type `Self`
 
 error[E0432]: unresolved import `Self`
   --> $DIR/use-self-type.rs:6:13
    |
 LL |         use Self::f;
-   |             ^^^^ use of undeclared type or module `Self`
+   |             ^^^^ use of undeclared type `Self`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 126907a7cfccbe93778530e6a6bbaa3adb6c515
+Subproject 875e0123259b0b6299903fe4aea0a12ecde9324
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 137b561028a..64f9379b303 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,113 @@ document.
 
 ## Unreleased / In Rust Nightly
 
-[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...master)
+[09bd400...master](https://github.com/rust-lang/rust-clippy/compare/09bd400...master)
+
+## Rust 1.47
+
+Current beta, release 2020-10-08
+
+[c2c07fa...09bd400](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...09bd400)
+
+### New lints
+
+* [`derive_ord_xor_partial_ord`] [#5848](https://github.com/rust-lang/rust-clippy/pull/5848)
+* [`trait_duplication_in_bounds`] [#5852](https://github.com/rust-lang/rust-clippy/pull/5852)
+* [`map_identity`] [#5694](https://github.com/rust-lang/rust-clippy/pull/5694)
+* [`unit_return_expecting_ord`] [#5737](https://github.com/rust-lang/rust-clippy/pull/5737)
+* [`pattern_type_mismatch`] [#4841](https://github.com/rust-lang/rust-clippy/pull/4841)
+* [`repeat_once`] [#5773](https://github.com/rust-lang/rust-clippy/pull/5773)
+* [`same_item_push`] [#5825](https://github.com/rust-lang/rust-clippy/pull/5825)
+* [`needless_arbitrary_self_type`] [#5869](https://github.com/rust-lang/rust-clippy/pull/5869)
+* [`match_like_matches_macro`] [#5769](https://github.com/rust-lang/rust-clippy/pull/5769)
+* [`stable_sort_primitive`] [#5809](https://github.com/rust-lang/rust-clippy/pull/5809)
+* [`blanket_clippy_restriction_lints`] [#5750](https://github.com/rust-lang/rust-clippy/pull/5750)
+* [`option_if_let_else`] [#5301](https://github.com/rust-lang/rust-clippy/pull/5301)
+
+### Moves and Deprecations
+
+* Deprecate [`regex_macro`] lint
+  [#5760](https://github.com/rust-lang/rust-clippy/pull/5760)
+* Move [`range_minus_one`] to `pedantic`
+  [#5752](https://github.com/rust-lang/rust-clippy/pull/5752)
+
+### Enhancements
+
+* Improve [`needless_collect`] by catching `collect` calls followed by `iter` or `into_iter` calls
+  [#5837](https://github.com/rust-lang/rust-clippy/pull/5837)
+* [`panic`], [`todo`], [`unimplemented`] and [`unreachable`] now detect calls with formatting
+  [#5811](https://github.com/rust-lang/rust-clippy/pull/5811)
+* Detect more cases of [`suboptimal_flops`] and [`imprecise_flops`]
+  [#5443](https://github.com/rust-lang/rust-clippy/pull/5443)
+* Handle asymmetrical implementations of `PartialEq` in [`cmp_owned`]
+  [#5701](https://github.com/rust-lang/rust-clippy/pull/5701)
+* Make it possible to allow [`unsafe_derive_deserialize`]
+  [#5870](https://github.com/rust-lang/rust-clippy/pull/5870)
+* Catch `ord.min(a).max(b)` where a < b in [`min_max`]
+  [#5871](https://github.com/rust-lang/rust-clippy/pull/5871)
+* Make [`clone_on_copy`] suggestion machine applicable
+  [#5745](https://github.com/rust-lang/rust-clippy/pull/5745)
+* Enable [`len_zero`] on ranges now that `is_empty` is stable on them
+  [#5961](https://github.com/rust-lang/rust-clippy/pull/5961)
+
+### False Positive Fixes
+
+* Avoid triggering [`or_fun_call`] with const fns that take no arguments
+  [#5889](https://github.com/rust-lang/rust-clippy/pull/5889)
+* Fix [`redundant_closure_call`] false positive for closures that have multiple calls
+  [#5800](https://github.com/rust-lang/rust-clippy/pull/5800)
+* Don't lint cases involving `ManuallyDrop` in [`redundant_clone`]
+  [#5824](https://github.com/rust-lang/rust-clippy/pull/5824)
+* Treat a single expression the same as a single statement in the 2nd arm of a match in [`single_match_else`]
+  [#5771](https://github.com/rust-lang/rust-clippy/pull/5771)
+* Don't trigger [`unnested_or_patterns`] if the feature `or_patterns` is not enabled
+  [#5758](https://github.com/rust-lang/rust-clippy/pull/5758)
+* Avoid linting if key borrows in [`unnecessary_sort_by`]
+  [#5756](https://github.com/rust-lang/rust-clippy/pull/5756)
+* Consider `Try` impl for `Poll` when generating suggestions in [`try_err`]
+  [#5857](https://github.com/rust-lang/rust-clippy/pull/5857)
+* Take input lifetimes into account in `manual_async_fn`
+  [#5859](https://github.com/rust-lang/rust-clippy/pull/5859)
+* Fix multiple false positives in [`type_repetition_in_bounds`] and add a configuration option
+  [#5761](https://github.com/rust-lang/rust-clippy/pull/5761)
+* Limit the [`suspicious_arithmetic_impl`] lint to one binary operation
+  [#5820](https://github.com/rust-lang/rust-clippy/pull/5820)
+
+### Suggestion Fixes/Improvements
+
+* Improve readability of [`shadow_unrelated`] suggestion by truncating the RHS snippet
+  [#5788](https://github.com/rust-lang/rust-clippy/pull/5788)
+* Suggest `filter_map` instead of `flat_map` when mapping to `Option` in [`map_flatten`]
+  [#5846](https://github.com/rust-lang/rust-clippy/pull/5846)
+* Ensure suggestion is shown correctly for long method call chains in [`iter_nth_zero`]
+  [#5793](https://github.com/rust-lang/rust-clippy/pull/5793)
+* Drop borrow operator in suggestions of [`redundant_pattern_matching`]
+  [#5815](https://github.com/rust-lang/rust-clippy/pull/5815)
+* Add suggestion for [`iter_skip_next`]
+  [#5843](https://github.com/rust-lang/rust-clippy/pull/5843)
+* Improve [`collapsible_if`] fix suggestion
+  [#5732](https://github.com/rust-lang/rust-clippy/pull/5732)
+
+### ICE Fixes
+
+* Fix ICE caused by [`needless_collect`]
+  [#5877](https://github.com/rust-lang/rust-clippy/pull/5877)
+* Fix ICE caused by [`unnested_or_patterns`]
+  [#5784](https://github.com/rust-lang/rust-clippy/pull/5784)
+
+### Documentation Improvements
+
+* Fix grammar of [`await_holding_lock`] documentation
+  [#5748](https://github.com/rust-lang/rust-clippy/pull/5748)
+
+### Others
+
+* Make lints adhere to the rustc dev guide
+  [#5888](https://github.com/rust-lang/rust-clippy/pull/5888)
 
 ## Rust 1.46
 
-Current beta, release 2020-08-27
+Current stable, released 2020-08-27
 
 [7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...c2c07fa)
 
@@ -72,7 +174,7 @@ Current beta, release 2020-08-27
 
 ## Rust 1.45
 
-Current stable, released 2020-07-16
+Released 2020-07-16
 
 [891e1a8...7ea7cd1](https://github.com/rust-lang/rust-clippy/compare/891e1a8...7ea7cd1)
 
@@ -1410,6 +1512,7 @@ Released 2018-09-13
 [`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
 [`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
 [`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
+[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
 [`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
 [`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
 [`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map
@@ -1444,6 +1547,7 @@ Released 2018-09-13
 [`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
 [`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
 [`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
+[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
 [`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
 [`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro
 [`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call
diff --git a/src/tools/clippy/clippy_lints/src/async_yields_async.rs b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
new file mode 100644
index 00000000000..88d9d3b5a26
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
@@ -0,0 +1,86 @@
+use crate::utils::{implements_trait, snippet, span_lint_and_then};
+use rustc_errors::Applicability;
+use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for async blocks that yield values of types
+    /// that can themselves be awaited.
+    ///
+    /// **Why is this bad?** An await is likely missing.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// async fn foo() {}
+    ///
+    /// fn bar() {
+    ///   let x = async {
+    ///     foo()
+    ///   };
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// async fn foo() {}
+    ///
+    /// fn bar() {
+    ///   let x = async {
+    ///     foo().await
+    ///   };
+    /// }
+    /// ```
+    pub ASYNC_YIELDS_ASYNC,
+    correctness,
+    "async blocks that return a type that can be awaited"
+}
+
+declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
+
+impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
+    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
+        use AsyncGeneratorKind::{Block, Closure};
+        // For functions, with explicitly defined types, don't warn.
+        // XXXkhuey maybe we should?
+        if let Some(GeneratorKind::Async(Block | Closure)) = body.generator_kind {
+            if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
+                let body_id = BodyId {
+                    hir_id: body.value.hir_id,
+                };
+                let def_id = cx.tcx.hir().body_owner_def_id(body_id);
+                let typeck_results = cx.tcx.typeck(def_id);
+                let expr_ty = typeck_results.expr_ty(&body.value);
+
+                if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
+                    let return_expr_span = match &body.value.kind {
+                        // XXXkhuey there has to be a better way.
+                        ExprKind::Block(block, _) => block.expr.map(|e| e.span),
+                        ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
+                        _ => None,
+                    };
+                    if let Some(return_expr_span) = return_expr_span {
+                        span_lint_and_then(
+                            cx,
+                            ASYNC_YIELDS_ASYNC,
+                            return_expr_span,
+                            "an async construct yields a type which is itself awaitable",
+                            |db| {
+                                db.span_label(body.value.span, "outer async construct");
+                                db.span_label(return_expr_span, "awaitable value not awaited");
+                                db.span_suggestion(
+                                    return_expr_span,
+                                    "consider awaiting this value",
+                                    format!("{}.await", snippet(cx, return_expr_span, "..")),
+                                    Applicability::MaybeIncorrect,
+                                );
+                            },
+                        );
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index cfcc1b3c5f3..c8f153e7201 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -71,8 +71,9 @@ declare_clippy_lint! {
     /// **What it does:** Checks for `extern crate` and `use` items annotated with
     /// lint attributes.
     ///
-    /// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]` and
-    /// `#[allow(unreachable_pub)]` on `use` items and `#[allow(unused_imports)]` on
+    /// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
+    /// `#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and
+    /// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
     /// `extern crate` items with a `#[macro_use]` attribute.
     ///
     /// **Why is this bad?** Lint attributes have no effect on crate imports. Most
@@ -318,7 +319,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
                         if let Some(ident) = attr.ident() {
                             match &*ident.as_str() {
                                 "allow" | "warn" | "deny" | "forbid" => {
-                                    // permit `unused_imports`, `deprecated` and `unreachable_pub` for `use` items
+                                    // permit `unused_imports`, `deprecated`, `unreachable_pub`,
+                                    // `clippy::wildcard_imports`, and `clippy::enum_glob_use` for `use` items
                                     // and `unused_imports` for `extern crate` items with `macro_use`
                                     for lint in lint_list {
                                         match item.kind {
@@ -327,6 +329,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
                                                     || is_word(lint, sym!(deprecated))
                                                     || is_word(lint, sym!(unreachable_pub))
                                                     || is_word(lint, sym!(unused))
+                                                    || extract_clippy_lint(lint)
+                                                        .map_or(false, |s| s == "wildcard_imports")
+                                                    || extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use")
                                                 {
                                                     return;
                                                 }
@@ -387,24 +392,25 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
     }
 }
 
-fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
-    fn extract_name(lint: &NestedMetaItem) -> Option<SymbolStr> {
-        if_chain! {
-            if let Some(meta_item) = lint.meta_item();
-            if meta_item.path.segments.len() > 1;
-            if let tool_name = meta_item.path.segments[0].ident;
-            if tool_name.as_str() == "clippy";
-            let lint_name = meta_item.path.segments.last().unwrap().ident.name;
-            then {
-                return Some(lint_name.as_str());
-            }
+/// Returns the lint name if it is clippy lint.
+fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
+    if_chain! {
+        if let Some(meta_item) = lint.meta_item();
+        if meta_item.path.segments.len() > 1;
+        if let tool_name = meta_item.path.segments[0].ident;
+        if tool_name.as_str() == "clippy";
+        let lint_name = meta_item.path.segments.last().unwrap().ident.name;
+        then {
+            return Some(lint_name.as_str());
         }
-        None
     }
+    None
+}
 
+fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
     let lint_store = cx.lints();
     for lint in items {
-        if let Some(lint_name) = extract_name(lint) {
+        if let Some(lint_name) = extract_clippy_lint(lint) {
             if let CheckLintNameResult::Tool(Err((None, _))) =
                 lint_store.check_lint_name(&lint_name, Some(sym!(clippy)))
             {
diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs
new file mode 100644
index 00000000000..4002fb655a5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/create_dir.rs
@@ -0,0 +1,51 @@
+use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+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`.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// std::fs::create_dir("foo");
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// std::fs::create_dir_all("foo");
+    /// ```
+    pub CREATE_DIR,
+    restriction,
+    "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
+}
+
+declare_lint_pass!(CreateDir => [CREATE_DIR]);
+
+impl LateLintPass<'_> for CreateDir {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        if_chain! {
+            if let ExprKind::Call(ref func, ref args) = expr.kind;
+            if let ExprKind::Path(ref path) = func.kind;
+            if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
+            if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
+            then {
+                span_lint_and_sugg(
+                    cx,
+                    CREATE_DIR,
+                    expr.span,
+                    "calling `std::fs::create_dir` where there may be a better way",
+                    "consider calling `std::fs::create_dir_all` instead",
+                    format!("create_dir_all({})", snippet(cx, args[0].span, "..")),
+                    Applicability::MaybeIncorrect,
+                )
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/default_trait_access.rs b/src/tools/clippy/clippy_lints/src/default_trait_access.rs
index 1654df56a9a..3048436d9a7 100644
--- a/src/tools/clippy/clippy_lints/src/default_trait_access.rs
+++ b/src/tools/clippy/clippy_lints/src/default_trait_access.rs
@@ -38,37 +38,23 @@ impl<'tcx> LateLintPass<'tcx> for DefaultTraitAccess {
             if let ExprKind::Path(ref qpath) = path.kind;
             if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
             if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
+            // Detect and ignore <Foo as Default>::default() because these calls do explicitly name the type.
+            if let QPath::Resolved(None, _path) = qpath;
             then {
-                match qpath {
-                    QPath::Resolved(..) => {
-                        if_chain! {
-                            // Detect and ignore <Foo as Default>::default() because these calls do
-                            // explicitly name the type.
-                            if let ExprKind::Call(ref method, ref _args) = expr.kind;
-                            if let ExprKind::Path(ref p) = method.kind;
-                            if let QPath::Resolved(Some(_ty), _path) = p;
-                            then {
-                                return;
-                            }
-                        }
-
-                        // TODO: Work out a way to put "whatever the imported way of referencing
-                        // this type in this file" rather than a fully-qualified type.
-                        let expr_ty = cx.typeck_results().expr_ty(expr);
-                        if let ty::Adt(..) = expr_ty.kind() {
-                            let replacement = format!("{}::default()", expr_ty);
-                            span_lint_and_sugg(
-                                cx,
-                                DEFAULT_TRAIT_ACCESS,
-                                expr.span,
-                                &format!("calling `{}` is more clear than this expression", replacement),
-                                "try",
-                                replacement,
-                                Applicability::Unspecified, // First resolve the TODO above
-                            );
-                         }
-                    },
-                    QPath::TypeRelative(..) | QPath::LangItem(..) => {},
+                let expr_ty = cx.typeck_results().expr_ty(expr);
+                if let ty::Adt(def, ..) = expr_ty.kind() {
+                    // TODO: Work out a way to put "whatever the imported way of referencing
+                    // this type in this file" rather than a fully-qualified type.
+                    let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did));
+                    span_lint_and_sugg(
+                        cx,
+                        DEFAULT_TRAIT_ACCESS,
+                        expr.span,
+                        &format!("calling `{}` is more clear than this expression", replacement),
+                        "try",
+                        replacement,
+                        Applicability::Unspecified, // First resolve the TODO above
+                    );
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs
index a9294a87f15..67a46353856 100644
--- a/src/tools/clippy/clippy_lints/src/enum_variants.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs
@@ -285,7 +285,7 @@ impl EarlyLintPass for EnumVariantNames {
                             );
                         }
                     }
-                    if item.vis.node.is_pub() {
+                    if item.vis.kind.is_pub() {
                         let matching = partial_match(mod_camel, &item_camel);
                         let rmatching = partial_rmatch(mod_camel, &item_camel);
                         let nchars = mod_camel.chars().count();
@@ -316,7 +316,7 @@ impl EarlyLintPass for EnumVariantNames {
             }
         }
         if let ItemKind::Enum(ref def, _) = item.kind {
-            let lint = match item.vis.node {
+            let lint = match item.vis.kind {
                 VisibilityKind::Public => PUB_ENUM_VARIANT_NAMES,
                 _ => ENUM_VARIANT_NAMES,
             };
diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs
index 89fde1d509d..50b39cf4ea7 100644
--- a/src/tools/clippy/clippy_lints/src/functions.rs
+++ b/src/tools/clippy/clippy_lints/src/functions.rs
@@ -374,7 +374,12 @@ impl<'tcx> Functions {
         }
 
         if line_count > self.max_lines {
-            span_lint(cx, TOO_MANY_LINES, span, "this function has a large number of lines")
+            span_lint(
+                cx,
+                TOO_MANY_LINES,
+                span,
+                &format!("this function has too many lines ({}/{})", line_count, self.max_lines),
+            )
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 577ce6523b4..2020ef78509 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -154,6 +154,7 @@ mod arithmetic;
 mod as_conversions;
 mod assertions_on_constants;
 mod assign_ops;
+mod async_yields_async;
 mod atomic_ordering;
 mod attrs;
 mod await_holding_lock;
@@ -169,6 +170,7 @@ mod collapsible_if;
 mod comparison_chain;
 mod copies;
 mod copy_iterator;
+mod create_dir;
 mod dbg_macro;
 mod default_trait_access;
 mod dereference;
@@ -483,6 +485,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
         &assign_ops::ASSIGN_OP_PATTERN,
         &assign_ops::MISREFACTORED_ASSIGN_OP,
+        &async_yields_async::ASYNC_YIELDS_ASYNC,
         &atomic_ordering::INVALID_ATOMIC_ORDERING,
         &attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
         &attrs::DEPRECATED_CFG_ATTR,
@@ -511,6 +514,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &copies::MATCH_SAME_ARMS,
         &copies::SAME_FUNCTIONS_IN_IF_CONDITION,
         &copy_iterator::COPY_ITERATOR,
+        &create_dir::CREATE_DIR,
         &dbg_macro::DBG_MACRO,
         &default_trait_access::DEFAULT_TRAIT_ACCESS,
         &dereference::EXPLICIT_DEREF_METHODS,
@@ -1042,6 +1046,7 @@ 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_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);
@@ -1099,11 +1104,13 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box unwrap_in_result::UnwrapInResult);
     store.register_late_pass(|| box self_assignment::SelfAssignment);
     store.register_late_pass(|| box float_equality_without_abs::FloatEqualityWithoutAbs);
+    store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
 
     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
         LintId::of(&arithmetic::FLOAT_ARITHMETIC),
         LintId::of(&arithmetic::INTEGER_ARITHMETIC),
         LintId::of(&as_conversions::AS_CONVERSIONS),
+        LintId::of(&create_dir::CREATE_DIR),
         LintId::of(&dbg_macro::DBG_MACRO),
         LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
         LintId::of(&exit::EXIT),
@@ -1232,6 +1239,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
         LintId::of(&assign_ops::ASSIGN_OP_PATTERN),
         LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP),
+        LintId::of(&async_yields_async::ASYNC_YIELDS_ASYNC),
         LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
         LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
         LintId::of(&attrs::DEPRECATED_CFG_ATTR),
@@ -1675,6 +1683,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
 
     store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
         LintId::of(&approx_const::APPROX_CONSTANT),
+        LintId::of(&async_yields_async::ASYNC_YIELDS_ASYNC),
         LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
         LintId::of(&attrs::DEPRECATED_SEMVER),
         LintId::of(&attrs::MISMATCHED_TARGET_OS),
diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs
index 604a97e3c08..6c54c07869a 100644
--- a/src/tools/clippy/clippy_lints/src/loops.rs
+++ b/src/tools/clippy/clippy_lints/src/loops.rs
@@ -1131,6 +1131,27 @@ fn detect_same_item_push<'tcx>(
     body: &'tcx Expr<'_>,
     _: &'tcx Expr<'_>,
 ) {
+    fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>) {
+        let vec_str = snippet_with_macro_callsite(cx, vec.span, "");
+        let item_str = snippet_with_macro_callsite(cx, pushed_item.span, "");
+
+        span_lint_and_help(
+            cx,
+            SAME_ITEM_PUSH,
+            vec.span,
+            "it looks like the same item is being pushed into this Vec",
+            None,
+            &format!(
+                "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})",
+                item_str, vec_str, item_str
+            ),
+        )
+    }
+
+    if !matches!(pat.kind, PatKind::Wild) {
+        return;
+    }
+
     // Determine whether it is safe to lint the body
     let mut same_item_push_visitor = SameItemPushVisitor {
         should_lint: true,
@@ -1140,43 +1161,50 @@ fn detect_same_item_push<'tcx>(
     walk_expr(&mut same_item_push_visitor, body);
     if same_item_push_visitor.should_lint {
         if let Some((vec, pushed_item)) = same_item_push_visitor.vec_push {
-            // Make sure that the push does not involve possibly mutating values
-            if let PatKind::Wild = pat.kind {
-                let vec_str = snippet_with_macro_callsite(cx, vec.span, "");
-                let item_str = snippet_with_macro_callsite(cx, pushed_item.span, "");
-                if let ExprKind::Path(ref qpath) = pushed_item.kind {
-                    if_chain! {
-                        if let Res::Local(hir_id) = qpath_res(cx, qpath, pushed_item.hir_id);
-                        let node = cx.tcx.hir().get(hir_id);
-                        if let Node::Binding(pat) = node;
-                        if let PatKind::Binding(bind_ann, ..) = pat.kind;
-                        if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable);
-                        then {
-                            span_lint_and_help(
-                                cx,
-                                SAME_ITEM_PUSH,
-                                vec.span,
-                                "it looks like the same item is being pushed into this Vec",
-                                None,
-                                &format!(
-                                    "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})",
-                                    item_str, vec_str, item_str
-                                ),
-                            )
+            let vec_ty = cx.typeck_results().expr_ty(vec);
+            let ty = vec_ty.walk().nth(1).unwrap().expect_ty();
+            if cx
+                .tcx
+                .lang_items()
+                .clone_trait()
+                .map_or(false, |id| implements_trait(cx, ty, id, &[]))
+            {
+                // Make sure that the push does not involve possibly mutating values
+                match pushed_item.kind {
+                    ExprKind::Path(ref qpath) => {
+                        match qpath_res(cx, qpath, pushed_item.hir_id) {
+                            // immutable bindings that are initialized with literal or constant
+                            Res::Local(hir_id) => {
+                                if_chain! {
+                                    let node = cx.tcx.hir().get(hir_id);
+                                    if let Node::Binding(pat) = node;
+                                    if let PatKind::Binding(bind_ann, ..) = pat.kind;
+                                    if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable);
+                                    let parent_node = cx.tcx.hir().get_parent_node(hir_id);
+                                    if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node);
+                                    if let Some(init) = parent_let_expr.init;
+                                    then {
+                                        match init.kind {
+                                            // immutable bindings that are initialized with literal
+                                            ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item),
+                                            // immutable bindings that are initialized with constant
+                                            ExprKind::Path(ref path) => {
+                                                if let Res::Def(DefKind::Const, ..) = qpath_res(cx, path, init.hir_id) {
+                                                    emit_lint(cx, vec, pushed_item);
+                                                }
+                                            }
+                                            _ => {},
+                                        }
+                                    }
+                                }
+                            },
+                            // constant
+                            Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item),
+                            _ => {},
                         }
-                    }
-                } else if mutated_variables(pushed_item, cx).map_or(false, |mutvars| mutvars.is_empty()) {
-                    span_lint_and_help(
-                        cx,
-                        SAME_ITEM_PUSH,
-                        vec.span,
-                        "it looks like the same item is being pushed into this Vec",
-                        None,
-                        &format!(
-                            "try using vec![{};SIZE] or {}.resize(NEW_SIZE, {})",
-                            item_str, vec_str, item_str
-                        ),
-                    )
+                    },
+                    ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item),
+                    _ => {},
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 4e49bdbdd21..9c623821fdd 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -122,7 +122,7 @@ fn check_manual_non_exhaustive_enum(cx: &EarlyContext<'_>, item: &Item, variants
 
 fn check_manual_non_exhaustive_struct(cx: &EarlyContext<'_>, item: &Item, data: &VariantData) {
     fn is_private(field: &StructField) -> bool {
-        matches!(field.vis.node, VisibilityKind::Inherited)
+        matches!(field.vis.kind, VisibilityKind::Inherited)
     }
 
     fn is_non_exhaustive_marker(field: &StructField) -> bool {
@@ -141,7 +141,7 @@ fn check_manual_non_exhaustive_struct(cx: &EarlyContext<'_>, item: &Item, data:
 
     let fields = data.fields();
     let private_fields = fields.iter().filter(|f| is_private(f)).count();
-    let public_fields = fields.iter().filter(|f| f.vis.node.is_pub()).count();
+    let public_fields = fields.iter().filter(|f| f.vis.kind.is_pub()).count();
 
     if_chain! {
         if private_fields == 1 && public_fields >= 1 && public_fields == fields.len() - 1;
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index 1f9ae8c931a..076ef235b8b 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -9,7 +9,7 @@ use rustc_span::source_map::Span;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for usage of `option.map(f)` where f is a function
-    /// or closure that returns the unit type.
+    /// or closure that returns the unit type `()`.
     ///
     /// **Why is this bad?** Readability, this can be written more clearly with
     /// an if let statement
@@ -51,7 +51,7 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// **What it does:** Checks for usage of `result.map(f)` where f is a function
-    /// or closure that returns the unit type.
+    /// or closure that returns the unit type `()`.
     ///
     /// **Why is this bad?** Readability, this can be written more clearly with
     /// an if let statement
@@ -197,7 +197,7 @@ fn let_binding_name(cx: &LateContext<'_>, var_arg: &hir::Expr<'_>) -> String {
 #[must_use]
 fn suggestion_msg(function_type: &str, map_type: &str) -> String {
     format!(
-        "called `map(f)` on an `{0}` value where `f` is a {1} that returns the unit type",
+        "called `map(f)` on an `{0}` value where `f` is a {1} that returns the unit type `()`",
         map_type, function_type
     )
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index a7a3d675156..ba69c8266b1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -1324,20 +1324,20 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
-    /// **What it does:** Warns when using push_str with a single-character string literal,
-    /// and push with a char would work fine.
+    /// **What it does:** Warns when using `push_str` with a single-character string literal,
+    /// and `push` with a `char` would work fine.
     ///
-    /// **Why is this bad?** It's less clear that we are pushing a single character
+    /// **Why is this bad?** It's less clear that we are pushing a single character.
     ///
     /// **Known problems:** None
     ///
     /// **Example:**
-    /// ```
+    /// ```rust
     /// let mut string = String::new();
     /// string.push_str("R");
     /// ```
     /// Could be written as
-    /// ```
+    /// ```rust
     /// let mut string = String::new();
     /// string.push('R');
     /// ```
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index 4773731e327..57a45e628db 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -14,7 +14,6 @@ use rustc_middle::mir::{
     visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor as _},
 };
 use rustc_middle::ty::{self, fold::TypeVisitor, Ty};
-use rustc_mir::dataflow::BottomValue;
 use rustc_mir::dataflow::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
@@ -411,14 +410,15 @@ impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor {
 struct MaybeStorageLive;
 
 impl<'tcx> AnalysisDomain<'tcx> for MaybeStorageLive {
-    type Idx = mir::Local;
+    type Domain = BitSet<mir::Local>;
     const NAME: &'static str = "maybe_storage_live";
 
-    fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize {
-        body.local_decls.len()
+    fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
+        // bottom = dead
+        BitSet::new_empty(body.local_decls.len())
     }
 
-    fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
+    fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain) {
         for arg in body.args_iter() {
             state.insert(arg);
         }
@@ -426,6 +426,8 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeStorageLive {
 }
 
 impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
+    type Idx = mir::Local;
+
     fn statement_effect(&self, trans: &mut impl GenKill<Self::Idx>, stmt: &mir::Statement<'tcx>, _: mir::Location) {
         match stmt.kind {
             mir::StatementKind::StorageLive(l) => trans.gen(l),
@@ -454,11 +456,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
     }
 }
 
-impl BottomValue for MaybeStorageLive {
-    /// bottom = dead
-    const BOTTOM_VALUE: bool = false;
-}
-
 /// Collects the possible borrowers of each local.
 /// For example, `b = &a; c = &a;` will make `b` and (transitively) `c`
 /// possible borrowers of `a`.
diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
index 58bfd0bc553..35b38eca14d 100644
--- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
@@ -41,7 +41,7 @@ impl EarlyLintPass for SingleComponentPathImports {
         if_chain! {
             if !in_macro(item.span);
             if cx.sess.opts.edition == Edition::Edition2018;
-            if !item.vis.node.is_pub();
+            if !item.vis.kind.is_pub();
             if let ItemKind::Use(use_tree) = &item.kind;
             if let segments = &use_tree.prefix.segments;
             if segments.len() == 1;
diff --git a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs
index 1aeff1baa36..fb891866364 100644
--- a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs
+++ b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs
@@ -1,5 +1,4 @@
 use crate::utils::{is_adjusted, span_lint};
-use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -22,12 +21,8 @@ declare_clippy_lint! {
     "assignments to temporaries"
 }
 
-fn is_temporary(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    match &expr.kind {
-        ExprKind::Struct(..) | ExprKind::Tup(..) => true,
-        ExprKind::Path(qpath) => matches!(cx.qpath_res(qpath, expr.hir_id), Res::Def(DefKind::Const, ..)),
-        _ => false,
-    }
+fn is_temporary(expr: &Expr<'_>) -> bool {
+    matches!(&expr.kind, ExprKind::Struct(..) | ExprKind::Tup(..))
 }
 
 declare_lint_pass!(TemporaryAssignment => [TEMPORARY_ASSIGNMENT]);
@@ -39,7 +34,7 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment {
             while let ExprKind::Field(f, _) | ExprKind::Index(f, _) = &base.kind {
                 base = f;
             }
-            if is_temporary(cx, base) && !is_adjusted(cx, base) {
+            if is_temporary(base) && !is_adjusted(cx, base) {
                 span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, "assignment to temporary");
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/transmute.rs b/src/tools/clippy/clippy_lints/src/transmute.rs
index 87c5408c785..c75adb62f25 100644
--- a/src/tools/clippy/clippy_lints/src/transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute.rs
@@ -331,8 +331,9 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
             if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
             if match_def_path(cx, def_id, &paths::TRANSMUTE);
             then {
-                // Avoid suggesting from/to bits in const contexts.
+                // Avoid suggesting from/to bits and dereferencing raw pointers in const contexts.
                 // See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
+                // And see https://github.com/rust-lang/rust/issues/51911 for dereferencing raw pointers.
                 let const_context = in_constant(cx, e.hir_id);
 
                 let from_ty = cx.typeck_results().expr_ty(&args[0]);
@@ -486,7 +487,8 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                                     Applicability::Unspecified,
                                 );
                             } else {
-                                if cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty) {
+                                if (cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty))
+                                    && !const_context {
                                     span_lint_and_then(
                                         cx,
                                         TRANSMUTE_PTR_TO_PTR,
diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs
index c82deaa43b2..6c6188d61ad 100644
--- a/src/tools/clippy/clippy_lints/src/types.rs
+++ b/src/tools/clippy/clippy_lints/src/types.rs
@@ -11,8 +11,8 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
 use rustc_hir::{
     BinOpKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericParamKind, HirId, ImplItem,
-    ImplItemKind, Item, ItemKind, Lifetime, Local, MatchSource, MutTy, Mutability, QPath, Stmt, StmtKind, TraitFn,
-    TraitItem, TraitItemKind, TyKind, UnOp,
+    ImplItemKind, Item, ItemKind, Lifetime, Local, MatchSource, MutTy, Mutability, Node, QPath, Stmt, StmtKind,
+    TraitFn, TraitItem, TraitItemKind, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
@@ -31,12 +31,13 @@ use crate::utils::paths;
 use crate::utils::{
     clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of, int_bits, is_type_diagnostic_item,
     last_path_segment, match_def_path, match_path, method_chain_args, multispan_sugg, numeric_literal::NumericLiteral,
-    qpath_res, sext, snippet, snippet_block_with_applicability, snippet_opt, snippet_with_applicability,
-    snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
+    qpath_res, reindent_multiline, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite,
+    span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
 };
 
 declare_clippy_lint! {
     /// **What it does:** Checks for use of `Box<Vec<_>>` anywhere in the code.
+    /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
     ///
     /// **Why is this bad?** `Vec` already keeps its contents in a separate area on
     /// the heap. So if you `Box` it, you just add another level of indirection
@@ -65,6 +66,7 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// **What it does:** Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.
+    /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
     ///
     /// **Why is this bad?** `Vec` already keeps its contents in a separate area on
     /// the heap. So if you `Box` its contents, you just add another level of indirection.
@@ -167,6 +169,7 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// **What it does:** Checks for use of `&Box<T>` anywhere in the code.
+    /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
     ///
     /// **Why is this bad?** Any `&Box<T>` can also be a `&T`, which is more
     /// general.
@@ -802,6 +805,45 @@ impl<'tcx> LateLintPass<'tcx> for UnitArg {
     }
 }
 
+fn fmt_stmts_and_call(
+    cx: &LateContext<'_>,
+    call_expr: &Expr<'_>,
+    call_snippet: &str,
+    args_snippets: &[impl AsRef<str>],
+    non_empty_block_args_snippets: &[impl AsRef<str>],
+) -> String {
+    let call_expr_indent = indent_of(cx, call_expr.span).unwrap_or(0);
+    let call_snippet_with_replacements = args_snippets
+        .iter()
+        .fold(call_snippet.to_owned(), |acc, arg| acc.replacen(arg.as_ref(), "()", 1));
+
+    let mut stmts_and_call = non_empty_block_args_snippets
+        .iter()
+        .map(|it| it.as_ref().to_owned())
+        .collect::<Vec<_>>();
+    stmts_and_call.push(call_snippet_with_replacements);
+    stmts_and_call = stmts_and_call
+        .into_iter()
+        .map(|v| reindent_multiline(v.into(), true, Some(call_expr_indent)).into_owned())
+        .collect();
+
+    let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent)));
+    // expr is not in a block statement or result expression position, wrap in a block
+    let parent_node = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(call_expr.hir_id));
+    if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) {
+        let block_indent = call_expr_indent + 4;
+        stmts_and_call_snippet =
+            reindent_multiline(stmts_and_call_snippet.into(), true, Some(block_indent)).into_owned();
+        stmts_and_call_snippet = format!(
+            "{{\n{}{}\n{}}}",
+            " ".repeat(block_indent),
+            &stmts_and_call_snippet,
+            " ".repeat(call_expr_indent)
+        );
+    }
+    stmts_and_call_snippet
+}
+
 fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Expr<'_>]) {
     let mut applicability = Applicability::MachineApplicable;
     let (singular, plural) = if args_to_recover.len() > 1 {
@@ -844,43 +886,52 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
                         Applicability::MaybeIncorrect,
                     );
                     or = "or ";
+                    applicability = Applicability::MaybeIncorrect;
                 });
-            let sugg = args_to_recover
+
+            let arg_snippets: Vec<String> = args_to_recover
+                .iter()
+                .filter_map(|arg| snippet_opt(cx, arg.span))
+                .collect();
+            let arg_snippets_without_empty_blocks: Vec<String> = args_to_recover
                 .iter()
                 .filter(|arg| !is_empty_block(arg))
-                .enumerate()
-                .map(|(i, arg)| {
-                    let indent = if i == 0 {
-                        0
-                    } else {
-                        indent_of(cx, expr.span).unwrap_or(0)
-                    };
-                    format!(
-                        "{}{};",
-                        " ".repeat(indent),
-                        snippet_block_with_applicability(cx, arg.span, "..", Some(expr.span), &mut applicability)
-                    )
-                })
-                .collect::<Vec<String>>();
-            let mut and = "";
-            if !sugg.is_empty() {
-                let plural = if sugg.len() > 1 { "s" } else { "" };
-                db.span_suggestion(
-                    expr.span.with_hi(expr.span.lo()),
-                    &format!("{}move the expression{} in front of the call...", or, plural),
-                    format!("{}\n", sugg.join("\n")),
-                    applicability,
+                .filter_map(|arg| snippet_opt(cx, arg.span))
+                .collect();
+
+            if let Some(call_snippet) = snippet_opt(cx, expr.span) {
+                let sugg = fmt_stmts_and_call(
+                    cx,
+                    expr,
+                    &call_snippet,
+                    &arg_snippets,
+                    &arg_snippets_without_empty_blocks,
                 );
-                and = "...and "
+
+                if arg_snippets_without_empty_blocks.is_empty() {
+                    db.multipart_suggestion(
+                        &format!("use {}unit literal{} instead", singular, plural),
+                        args_to_recover
+                            .iter()
+                            .map(|arg| (arg.span, "()".to_string()))
+                            .collect::<Vec<_>>(),
+                        applicability,
+                    );
+                } else {
+                    let plural = arg_snippets_without_empty_blocks.len() > 1;
+                    let empty_or_s = if plural { "s" } else { "" };
+                    let it_or_them = if plural { "them" } else { "it" };
+                    db.span_suggestion(
+                        expr.span,
+                        &format!(
+                            "{}move the expression{} in front of the call and replace {} with the unit literal `()`",
+                            or, empty_or_s, it_or_them
+                        ),
+                        sugg,
+                        applicability,
+                    );
+                }
             }
-            db.multipart_suggestion(
-                &format!("{}use {}unit literal{} instead", and, singular, plural),
-                args_to_recover
-                    .iter()
-                    .map(|arg| (arg.span, "()".to_string()))
-                    .collect::<Vec<_>>(),
-                applicability,
-            );
         },
     );
 }
@@ -2055,6 +2106,7 @@ impl PartialOrd for FullInt {
         })
     }
 }
+
 impl Ord for FullInt {
     #[must_use]
     fn cmp(&self, other: &Self) -> Ordering {
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs
index 8b00d29acb5..9b6a9075a29 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_sort_by.rs
@@ -1,5 +1,4 @@
 use crate::utils;
-use crate::utils::paths;
 use crate::utils::sugg::Sugg;
 use if_chain::if_chain;
 use rustc_errors::Applicability;
@@ -171,12 +170,22 @@ fn mirrored_exprs(
 }
 
 fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
+    // NOTE: Vectors of references are not supported. In order to avoid hitting https://github.com/rust-lang/rust/issues/34162,
+    // (different unnamed lifetimes for closure arg and return type) we need to make sure the suggested
+    // closure parameter is not a reference in case we suggest `Reverse`. Trying to destructure more
+    // than one level of references would add some extra complexity as we would have to compensate
+    // in the closure body.
+
     if_chain! {
         if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind;
         if let name = name_ident.ident.name.to_ident_string();
         if name == "sort_by" || name == "sort_unstable_by";
         if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args;
-        if utils::match_type(cx, &cx.typeck_results().expr_ty(vec), &paths::VEC);
+        let vec_ty = cx.typeck_results().expr_ty(vec);
+        if utils::is_type_diagnostic_item(cx, vec_ty, sym!(vec_type));
+        let ty = vec_ty.walk().nth(1).unwrap().expect_ty(); // T in Vec<T>
+        if !matches!(&ty.kind(), ty::Ref(..));
+        if utils::is_copy(cx, ty);
         if let closure_body = cx.tcx.hir().body(*closure_body_id);
         if let &[
             Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..},
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 3c3f8b26e3a..0e9feef3746 100644
--- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
@@ -191,7 +191,9 @@ pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {
         (Item(l), Item(r)) => eq_item(l, r, eq_item_kind),
         (Expr(l), Expr(r)) | (Semi(l), Semi(r)) => eq_expr(l, r),
         (Empty, Empty) => true,
-        (MacCall(l), MacCall(r)) => l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r)),
+        (MacCall(l), MacCall(r)) => {
+            l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
+        },
         _ => false,
     }
 }
@@ -392,7 +394,7 @@ pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {
 
 pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {
     use VisibilityKind::*;
-    match (&l.node, &r.node) {
+    match (&l.kind, &r.kind) {
         (Public, Public) | (Inherited, Inherited) | (Crate(_), Crate(_)) => true,
         (Restricted { path: l, .. }, Restricted { path: r, .. }) => eq_path(l, r),
         _ => false,
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 292dbd7ad6b..9c5a12ea9c8 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -122,7 +122,7 @@ define_Conf! {
         "IPv4", "IPv6",
         "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript",
         "NaN", "NaNs",
-        "OAuth",
+        "OAuth", "GraphQL",
         "OCaml",
         "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap",
         "TensorFlow",
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index 45add9ab284..3ebbfed6456 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -19,6 +19,7 @@ pub mod paths;
 pub mod ptr;
 pub mod sugg;
 pub mod usage;
+
 pub use self::attrs::*;
 pub use self::diagnostics::*;
 pub use self::hir_utils::{both, eq_expr_value, over, SpanlessEq, SpanlessHash};
@@ -108,6 +109,7 @@ pub fn in_macro(span: Span) -> bool {
         false
     }
 }
+
 // If the snippet is empty, it's an attribute that was inserted during macro
 // expansion and we want to ignore those, because they could come from external
 // sources that the user has no control over.
@@ -571,7 +573,7 @@ pub fn snippet_block<'a, T: LintContext>(
 ) -> Cow<'a, str> {
     let snip = snippet(cx, span, default);
     let indent = indent_relative_to.and_then(|s| indent_of(cx, s));
-    trim_multiline(snip, true, indent)
+    reindent_multiline(snip, true, indent)
 }
 
 /// Same as `snippet_block`, but adapts the applicability level by the rules of
@@ -585,7 +587,7 @@ pub fn snippet_block_with_applicability<'a, T: LintContext>(
 ) -> Cow<'a, str> {
     let snip = snippet_with_applicability(cx, span, default, applicability);
     let indent = indent_relative_to.and_then(|s| indent_of(cx, s));
-    trim_multiline(snip, true, indent)
+    reindent_multiline(snip, true, indent)
 }
 
 /// Returns a new Span that extends the original Span to the first non-whitespace char of the first
@@ -661,16 +663,16 @@ pub fn expr_block<'a, T: LintContext>(
     }
 }
 
-/// Trim indentation from a multiline string with possibility of ignoring the
-/// first line.
-fn trim_multiline(s: Cow<'_, str>, ignore_first: bool, indent: Option<usize>) -> Cow<'_, str> {
-    let s_space = trim_multiline_inner(s, ignore_first, indent, ' ');
-    let s_tab = trim_multiline_inner(s_space, ignore_first, indent, '\t');
-    trim_multiline_inner(s_tab, ignore_first, indent, ' ')
+/// Reindent a multiline string with possibility of ignoring the first line.
+#[allow(clippy::needless_pass_by_value)]
+pub fn reindent_multiline(s: Cow<'_, str>, ignore_first: bool, indent: Option<usize>) -> Cow<'_, str> {
+    let s_space = reindent_multiline_inner(&s, ignore_first, indent, ' ');
+    let s_tab = reindent_multiline_inner(&s_space, ignore_first, indent, '\t');
+    reindent_multiline_inner(&s_tab, ignore_first, indent, ' ').into()
 }
 
-fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, indent: Option<usize>, ch: char) -> Cow<'_, str> {
-    let mut x = s
+fn reindent_multiline_inner(s: &str, ignore_first: bool, indent: Option<usize>, ch: char) -> String {
+    let x = s
         .lines()
         .skip(ignore_first as usize)
         .filter_map(|l| {
@@ -683,26 +685,20 @@ fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, indent: Option<usiz
         })
         .min()
         .unwrap_or(0);
-    if let Some(indent) = indent {
-        x = x.saturating_sub(indent);
-    }
-    if x > 0 {
-        Cow::Owned(
-            s.lines()
-                .enumerate()
-                .map(|(i, l)| {
-                    if (ignore_first && i == 0) || l.is_empty() {
-                        l
-                    } else {
-                        l.split_at(x).1
-                    }
-                })
-                .collect::<Vec<_>>()
-                .join("\n"),
-        )
-    } else {
-        s
-    }
+    let indent = indent.unwrap_or(0);
+    s.lines()
+        .enumerate()
+        .map(|(i, l)| {
+            if (ignore_first && i == 0) || l.is_empty() {
+                l.to_owned()
+            } else if x > indent {
+                l.split_at(x - indent).1.to_owned()
+            } else {
+                " ".repeat(indent - x) + l
+            }
+        })
+        .collect::<Vec<String>>()
+        .join("\n")
 }
 
 /// Gets the parent expression, if any –- this is useful to constrain a lint.
@@ -899,7 +895,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_
             return match res {
                 def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
                 // FIXME: check the constness of the arguments, see https://github.com/rust-lang/rust-clippy/pull/5682#issuecomment-638681210
-                def::Res::Def(DefKind::Fn, def_id) if has_no_arguments(cx, def_id) => {
+                def::Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) if has_no_arguments(cx, def_id) => {
                     const_eval::is_const_fn(cx.tcx, def_id)
                 },
                 def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
@@ -1432,7 +1428,7 @@ pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<S
             } else {
                 unreachable!()
             }
-        }
+        },
         _ => false,
     };
 
@@ -1474,26 +1470,26 @@ macro_rules! unwrap_cargo_metadata {
 
 #[cfg(test)]
 mod test {
-    use super::{trim_multiline, without_block_comments};
+    use super::{reindent_multiline, without_block_comments};
 
     #[test]
-    fn test_trim_multiline_single_line() {
-        assert_eq!("", trim_multiline("".into(), false, None));
-        assert_eq!("...", trim_multiline("...".into(), false, None));
-        assert_eq!("...", trim_multiline("    ...".into(), false, None));
-        assert_eq!("...", trim_multiline("\t...".into(), false, None));
-        assert_eq!("...", trim_multiline("\t\t...".into(), false, None));
+    fn test_reindent_multiline_single_line() {
+        assert_eq!("", reindent_multiline("".into(), false, None));
+        assert_eq!("...", reindent_multiline("...".into(), false, None));
+        assert_eq!("...", reindent_multiline("    ...".into(), false, None));
+        assert_eq!("...", reindent_multiline("\t...".into(), false, None));
+        assert_eq!("...", reindent_multiline("\t\t...".into(), false, None));
     }
 
     #[test]
     #[rustfmt::skip]
-    fn test_trim_multiline_block() {
+    fn test_reindent_multiline_block() {
         assert_eq!("\
     if x {
         y
     } else {
         z
-    }", trim_multiline("    if x {
+    }", reindent_multiline("    if x {
             y
         } else {
             z
@@ -1503,7 +1499,7 @@ mod test {
     \ty
     } else {
     \tz
-    }", trim_multiline("    if x {
+    }", reindent_multiline("    if x {
         \ty
         } else {
         \tz
@@ -1512,14 +1508,14 @@ mod test {
 
     #[test]
     #[rustfmt::skip]
-    fn test_trim_multiline_empty_line() {
+    fn test_reindent_multiline_empty_line() {
         assert_eq!("\
     if x {
         y
 
     } else {
         z
-    }", trim_multiline("    if x {
+    }", reindent_multiline("    if x {
             y
 
         } else {
@@ -1528,6 +1524,22 @@ mod test {
     }
 
     #[test]
+    #[rustfmt::skip]
+    fn test_reindent_multiline_lines_deeper() {
+        assert_eq!("\
+        if x {
+            y
+        } else {
+            z
+        }", reindent_multiline("\
+    if x {
+        y
+    } else {
+        z
+    }".into(), true, Some(8)));
+    }
+
+    #[test]
     fn test_without_block_comments_lines_without_block_comments() {
         let result = without_block_comments(vec!["/*", "", "*/"]);
         println!("result: {:?}", result);
diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs
index d44854aefe9..65320d6a0e0 100644
--- a/src/tools/clippy/clippy_lints/src/utils/paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs
@@ -110,6 +110,7 @@ pub const SLICE_ITER: [&str; 3] = ["core", "slice", "Iter"];
 pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
 pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
 pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
+pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
 pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
 pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
 pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
diff --git a/src/tools/clippy/clippy_lints/src/utils/sugg.rs b/src/tools/clippy/clippy_lints/src/utils/sugg.rs
index 2955f8d8e59..811fde388d1 100644
--- a/src/tools/clippy/clippy_lints/src/utils/sugg.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/sugg.rs
@@ -132,7 +132,11 @@ impl<'a> Sugg<'a> {
     pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
         use rustc_ast::ast::RangeLimits;
 
-        let snippet = snippet(cx, expr.span, default);
+        let snippet = if expr.span.from_expansion() {
+            snippet_with_macro_callsite(cx, expr.span, default)
+        } else {
+            snippet(cx, expr.span, default)
+        };
 
         match expr.kind {
             ast::ExprKind::AddrOf(..)
diff --git a/src/tools/clippy/src/lintlist/mod.rs b/src/tools/clippy/src/lintlist/mod.rs
index 687fac7baa8..6697835e950 100644
--- a/src/tools/clippy/src/lintlist/mod.rs
+++ b/src/tools/clippy/src/lintlist/mod.rs
@@ -53,6 +53,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "assign_ops",
     },
     Lint {
+        name: "async_yields_async",
+        group: "correctness",
+        desc: "async blocks that return a type that can be awaited",
+        deprecation: None,
+        module: "async_yields_async",
+    },
+    Lint {
         name: "await_holding_lock",
         group: "pedantic",
         desc: "Inside an async function, holding a MutexGuard while calling await",
@@ -291,6 +298,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "copy_iterator",
     },
     Lint {
+        name: "create_dir",
+        group: "restriction",
+        desc: "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`",
+        deprecation: None,
+        module: "create_dir",
+    },
+    Lint {
         name: "crosspointer_transmute",
         group: "complexity",
         desc: "transmutes that have to or from types that are a pointer to the other",
diff --git a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
index fb12257021a..a27ce945ca5 100644
--- a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
@@ -1,4 +1,4 @@
-error: this function has a large number of lines
+error: this function has too many lines (2/1)
   --> $DIR/test.rs:18:1
    |
 LL | / fn too_many_lines() {
@@ -9,7 +9,7 @@ LL | | }
    |
    = note: `-D clippy::too-many-lines` implied by `-D warnings`
 
-error: this function has a large number of lines
+error: this function has too many lines (2/1)
   --> $DIR/test.rs:38:1
    |
 LL | / fn comment_before_code() {
diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed
new file mode 100644
index 00000000000..9b1a7ac3ba9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/async_yields_async.fixed
@@ -0,0 +1,68 @@
+// run-rustfix
+// edition:2018
+
+#![feature(async_closure)]
+#![warn(clippy::async_yields_async)]
+
+use core::future::Future;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+struct CustomFutureType;
+
+impl Future for CustomFutureType {
+    type Output = u8;
+
+    fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
+        Poll::Ready(3)
+    }
+}
+
+fn custom_future_type_ctor() -> CustomFutureType {
+    CustomFutureType
+}
+
+async fn f() -> CustomFutureType {
+    // Don't warn for functions since you have to explicitly declare their
+    // return types.
+    CustomFutureType
+}
+
+#[rustfmt::skip]
+fn main() {
+    let _f = {
+        3
+    };
+    let _g = async {
+        3
+    };
+    let _h = async {
+        async {
+            3
+        }.await
+    };
+    let _i = async {
+        CustomFutureType.await
+    };
+    let _i = async || {
+        3
+    };
+    let _j = async || {
+        async {
+            3
+        }.await
+    };
+    let _k = async || {
+        CustomFutureType.await
+    };
+    let _l = async || CustomFutureType.await;
+    let _m = async || {
+        println!("I'm bored");
+        // Some more stuff
+
+        // Finally something to await
+        CustomFutureType.await
+    };
+    let _n = async || custom_future_type_ctor();
+    let _o = async || f();
+}
diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs
new file mode 100644
index 00000000000..731c094edb4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/async_yields_async.rs
@@ -0,0 +1,68 @@
+// run-rustfix
+// edition:2018
+
+#![feature(async_closure)]
+#![warn(clippy::async_yields_async)]
+
+use core::future::Future;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+struct CustomFutureType;
+
+impl Future for CustomFutureType {
+    type Output = u8;
+
+    fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
+        Poll::Ready(3)
+    }
+}
+
+fn custom_future_type_ctor() -> CustomFutureType {
+    CustomFutureType
+}
+
+async fn f() -> CustomFutureType {
+    // Don't warn for functions since you have to explicitly declare their
+    // return types.
+    CustomFutureType
+}
+
+#[rustfmt::skip]
+fn main() {
+    let _f = {
+        3
+    };
+    let _g = async {
+        3
+    };
+    let _h = async {
+        async {
+            3
+        }
+    };
+    let _i = async {
+        CustomFutureType
+    };
+    let _i = async || {
+        3
+    };
+    let _j = async || {
+        async {
+            3
+        }
+    };
+    let _k = async || {
+        CustomFutureType
+    };
+    let _l = async || CustomFutureType;
+    let _m = async || {
+        println!("I'm bored");
+        // Some more stuff
+
+        // Finally something to await
+        CustomFutureType
+    };
+    let _n = async || custom_future_type_ctor();
+    let _o = async || f();
+}
diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr
new file mode 100644
index 00000000000..17d0c375106
--- /dev/null
+++ b/src/tools/clippy/tests/ui/async_yields_async.stderr
@@ -0,0 +1,96 @@
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:40:9
+   |
+LL |        let _h = async {
+   |   ____________________-
+LL |  |         async {
+   |  |_________^
+LL | ||             3
+LL | ||         }
+   | ||_________^ awaitable value not awaited
+LL |  |     };
+   |  |_____- outer async construct
+   |
+   = note: `-D clippy::async-yields-async` implied by `-D warnings`
+help: consider awaiting this value
+   |
+LL |         async {
+LL |             3
+LL |         }.await
+   |
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:45:9
+   |
+LL |       let _i = async {
+   |  ____________________-
+LL | |         CustomFutureType
+   | |         ^^^^^^^^^^^^^^^^
+   | |         |
+   | |         awaitable value not awaited
+   | |         help: consider awaiting this value: `CustomFutureType.await`
+LL | |     };
+   | |_____- outer async construct
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:51:9
+   |
+LL |        let _j = async || {
+   |   _______________________-
+LL |  |         async {
+   |  |_________^
+LL | ||             3
+LL | ||         }
+   | ||_________^ awaitable value not awaited
+LL |  |     };
+   |  |_____- outer async construct
+   |
+help: consider awaiting this value
+   |
+LL |         async {
+LL |             3
+LL |         }.await
+   |
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:56:9
+   |
+LL |       let _k = async || {
+   |  _______________________-
+LL | |         CustomFutureType
+   | |         ^^^^^^^^^^^^^^^^
+   | |         |
+   | |         awaitable value not awaited
+   | |         help: consider awaiting this value: `CustomFutureType.await`
+LL | |     };
+   | |_____- outer async construct
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:58:23
+   |
+LL |     let _l = async || CustomFutureType;
+   |                       ^^^^^^^^^^^^^^^^
+   |                       |
+   |                       outer async construct
+   |                       awaitable value not awaited
+   |                       help: consider awaiting this value: `CustomFutureType.await`
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:64:9
+   |
+LL |       let _m = async || {
+   |  _______________________-
+LL | |         println!("I'm bored");
+LL | |         // Some more stuff
+LL | |
+LL | |         // Finally something to await
+LL | |         CustomFutureType
+   | |         ^^^^^^^^^^^^^^^^
+   | |         |
+   | |         awaitable value not awaited
+   | |         help: consider awaiting this value: `CustomFutureType.await`
+LL | |     };
+   | |_____- outer async construct
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs
index a414832bcd3..39f87510548 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs
@@ -1,5 +1,6 @@
 #![warn(clippy::borrow_interior_mutable_const)]
 #![allow(clippy::declare_interior_mutable_const, clippy::ref_in_deref)]
+#![allow(const_item_mutation)]
 
 use std::borrow::Cow;
 use std::cell::{Cell, UnsafeCell};
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr
index 1e0b3e4d20a..5800af7e960 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr
@@ -1,5 +1,5 @@
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:65:5
+  --> $DIR/borrow_interior_mutable_const.rs:66:5
    |
 LL |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^
@@ -8,7 +8,7 @@ LL |     ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:66:16
+  --> $DIR/borrow_interior_mutable_const.rs:67:16
    |
 LL |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutability
    |                ^^^^^^
@@ -16,7 +16,7 @@ LL |     assert_eq!(ATOMIC.load(Ordering::SeqCst), 5); //~ ERROR interior mutabi
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:69:22
+  --> $DIR/borrow_interior_mutable_const.rs:70:22
    |
 LL |     let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
    |                      ^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     let _once_ref = &ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:70:25
+  --> $DIR/borrow_interior_mutable_const.rs:71:25
    |
 LL |     let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
    |                         ^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     let _once_ref_2 = &&ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:71:27
+  --> $DIR/borrow_interior_mutable_const.rs:72:27
    |
 LL |     let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
    |                           ^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     let _once_ref_4 = &&&&ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:72:26
+  --> $DIR/borrow_interior_mutable_const.rs:73:26
    |
 LL |     let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
    |                          ^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     let _once_mut = &mut ONCE_INIT; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:83:14
+  --> $DIR/borrow_interior_mutable_const.rs:84:14
    |
 LL |     let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     let _ = &ATOMIC_TUPLE; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:84:14
+  --> $DIR/borrow_interior_mutable_const.rs:85:14
    |
 LL |     let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     let _ = &ATOMIC_TUPLE.0; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:85:19
+  --> $DIR/borrow_interior_mutable_const.rs:86:19
    |
 LL |     let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
    |                   ^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:86:14
+  --> $DIR/borrow_interior_mutable_const.rs:87:14
    |
 LL |     let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    |              ^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:87:13
+  --> $DIR/borrow_interior_mutable_const.rs:88:13
    |
 LL |     let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mutability
    |             ^^^^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR interior mu
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:93:13
+  --> $DIR/borrow_interior_mutable_const.rs:94:13
    |
 LL |     let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    |             ^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     let _ = ATOMIC_TUPLE.0[0]; //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:98:5
+  --> $DIR/borrow_interior_mutable_const.rs:99:5
    |
 LL |     CELL.set(2); //~ ERROR interior mutability
    |     ^^^^
@@ -104,7 +104,7 @@ LL |     CELL.set(2); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:99:16
+  --> $DIR/borrow_interior_mutable_const.rs:100:16
    |
 LL |     assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
    |                ^^^^
@@ -112,7 +112,7 @@ LL |     assert_eq!(CELL.get(), 6); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:112:5
+  --> $DIR/borrow_interior_mutable_const.rs:113:5
    |
 LL |     u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
    |     ^^^^^^^^^^^
@@ -120,7 +120,7 @@ LL |     u64::ATOMIC.store(5, Ordering::SeqCst); //~ ERROR interior mutability
    = help: assign this const to a local or static variable, and use the variable here
 
 error: a `const` item with interior mutability should not be borrowed
-  --> $DIR/borrow_interior_mutable_const.rs:113:16
+  --> $DIR/borrow_interior_mutable_const.rs:114:16
    |
 LL |     assert_eq!(u64::ATOMIC.load(Ordering::SeqCst), 9); //~ ERROR interior mutability
    |                ^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/collapsible_if.fixed b/src/tools/clippy/tests/ui/collapsible_if.fixed
index 561283fc8e7..efd4187947b 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_if.fixed
@@ -135,4 +135,7 @@ fn main() {
             if truth() {}
         }
     }
+
+    // Fix #5962
+    if matches!(true, true) && matches!(true, true) {}
 }
diff --git a/src/tools/clippy/tests/ui/collapsible_if.rs b/src/tools/clippy/tests/ui/collapsible_if.rs
index dc9d9b451c0..657f32d38a3 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_if.rs
@@ -149,4 +149,9 @@ fn main() {
             if truth() {}
         }
     }
+
+    // Fix #5962
+    if matches!(true, true) {
+        if matches!(true, true) {}
+    }
 }
diff --git a/src/tools/clippy/tests/ui/collapsible_if.stderr b/src/tools/clippy/tests/ui/collapsible_if.stderr
index f56dd65b9dd..acd1ec3f2ca 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_if.stderr
@@ -118,5 +118,13 @@ LL |         println!("Hello world!");
 LL |     }
    |
 
-error: aborting due to 7 previous errors
+error: this `if` statement can be collapsed
+  --> $DIR/collapsible_if.rs:154:5
+   |
+LL | /     if matches!(true, true) {
+LL | |         if matches!(true, true) {}
+LL | |     }
+   | |_____^ help: collapse nested if block: `if matches!(true, true) && matches!(true, true) {}`
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/create_dir.fixed b/src/tools/clippy/tests/ui/create_dir.fixed
new file mode 100644
index 00000000000..8ed53a56ac0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/create_dir.fixed
@@ -0,0 +1,17 @@
+// run-rustfix
+#![allow(unused_must_use)]
+#![warn(clippy::create_dir)]
+
+use std::fs::create_dir_all;
+
+fn create_dir() {}
+
+fn main() {
+    // Should be warned
+    create_dir_all("foo");
+    create_dir_all("bar").unwrap();
+
+    // Shouldn't be warned
+    create_dir();
+    std::fs::create_dir_all("foobar");
+}
diff --git a/src/tools/clippy/tests/ui/create_dir.rs b/src/tools/clippy/tests/ui/create_dir.rs
new file mode 100644
index 00000000000..19c8fc24ba2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/create_dir.rs
@@ -0,0 +1,17 @@
+// run-rustfix
+#![allow(unused_must_use)]
+#![warn(clippy::create_dir)]
+
+use std::fs::create_dir_all;
+
+fn create_dir() {}
+
+fn main() {
+    // Should be warned
+    std::fs::create_dir("foo");
+    std::fs::create_dir("bar").unwrap();
+
+    // Shouldn't be warned
+    create_dir();
+    std::fs::create_dir_all("foobar");
+}
diff --git a/src/tools/clippy/tests/ui/create_dir.stderr b/src/tools/clippy/tests/ui/create_dir.stderr
new file mode 100644
index 00000000000..67298fc4709
--- /dev/null
+++ b/src/tools/clippy/tests/ui/create_dir.stderr
@@ -0,0 +1,16 @@
+error: calling `std::fs::create_dir` where there may be a better way
+  --> $DIR/create_dir.rs:11:5
+   |
+LL |     std::fs::create_dir("foo");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("foo")`
+   |
+   = note: `-D clippy::create-dir` implied by `-D warnings`
+
+error: calling `std::fs::create_dir` where there may be a better way
+  --> $DIR/create_dir.rs:12:5
+   |
+LL |     std::fs::create_dir("bar").unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `std::fs::create_dir_all` instead: `create_dir_all("bar")`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed
new file mode 100644
index 00000000000..d05567a3f82
--- /dev/null
+++ b/src/tools/clippy/tests/ui/default_trait_access.fixed
@@ -0,0 +1,106 @@
+// run-rustfix
+
+#![allow(unused_imports)]
+#![deny(clippy::default_trait_access)]
+
+use std::default;
+use std::default::Default as D2;
+use std::string;
+
+fn main() {
+    let s1: String = std::string::String::default();
+
+    let s2 = String::default();
+
+    let s3: String = std::string::String::default();
+
+    let s4: String = std::string::String::default();
+
+    let s5 = string::String::default();
+
+    let s6: String = std::string::String::default();
+
+    let s7 = std::string::String::default();
+
+    let s8: String = DefaultFactory::make_t_badly();
+
+    let s9: String = DefaultFactory::make_t_nicely();
+
+    let s10 = DerivedDefault::default();
+
+    let s11: GenericDerivedDefault<String> = GenericDerivedDefault::default();
+
+    let s12 = GenericDerivedDefault::<String>::default();
+
+    let s13 = TupleDerivedDefault::default();
+
+    let s14: TupleDerivedDefault = TupleDerivedDefault::default();
+
+    let s15: ArrayDerivedDefault = ArrayDerivedDefault::default();
+
+    let s16 = ArrayDerivedDefault::default();
+
+    let s17: TupleStructDerivedDefault = TupleStructDerivedDefault::default();
+
+    let s18 = TupleStructDerivedDefault::default();
+
+    let s19 = <DerivedDefault as Default>::default();
+
+    println!(
+        "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}], [{:?}]",
+        s1,
+        s2,
+        s3,
+        s4,
+        s5,
+        s6,
+        s7,
+        s8,
+        s9,
+        s10,
+        s11,
+        s12,
+        s13,
+        s14,
+        s15,
+        s16,
+        s17,
+        s18,
+        s19,
+    );
+}
+
+struct DefaultFactory;
+
+impl DefaultFactory {
+    pub fn make_t_badly<T: Default>() -> T {
+        Default::default()
+    }
+
+    pub fn make_t_nicely<T: Default>() -> T {
+        T::default()
+    }
+}
+
+#[derive(Debug, Default)]
+struct DerivedDefault {
+    pub s: String,
+}
+
+#[derive(Debug, Default)]
+struct GenericDerivedDefault<T: Default + std::fmt::Debug> {
+    pub s: T,
+}
+
+#[derive(Debug, Default)]
+struct TupleDerivedDefault {
+    pub s: (String, String),
+}
+
+#[derive(Debug, Default)]
+struct ArrayDerivedDefault {
+    pub s: [String; 10],
+}
+
+#[derive(Debug, Default)]
+struct TupleStructDerivedDefault(String);
diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs
index 2f1490a7036..447e70c0bbb 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.rs
+++ b/src/tools/clippy/tests/ui/default_trait_access.rs
@@ -1,4 +1,7 @@
-#![warn(clippy::default_trait_access)]
+// run-rustfix
+
+#![allow(unused_imports)]
+#![deny(clippy::default_trait_access)]
 
 use std::default;
 use std::default::Default as D2;
diff --git a/src/tools/clippy/tests/ui/default_trait_access.stderr b/src/tools/clippy/tests/ui/default_trait_access.stderr
index 26b2057548b..df8a5b94ddc 100644
--- a/src/tools/clippy/tests/ui/default_trait_access.stderr
+++ b/src/tools/clippy/tests/ui/default_trait_access.stderr
@@ -1,49 +1,53 @@
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:8:22
+  --> $DIR/default_trait_access.rs:11:22
    |
 LL |     let s1: String = Default::default();
    |                      ^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
    |
-   = note: `-D clippy::default-trait-access` implied by `-D warnings`
+note: the lint level is defined here
+  --> $DIR/default_trait_access.rs:4:9
+   |
+LL | #![deny(clippy::default_trait_access)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:12:22
+  --> $DIR/default_trait_access.rs:15:22
    |
 LL |     let s3: String = D2::default();
    |                      ^^^^^^^^^^^^^ help: try: `std::string::String::default()`
 
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:14:22
+  --> $DIR/default_trait_access.rs:17:22
    |
 LL |     let s4: String = std::default::Default::default();
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
 
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:18:22
+  --> $DIR/default_trait_access.rs:21:22
    |
 LL |     let s6: String = default::Default::default();
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
 
-error: calling `GenericDerivedDefault<std::string::String>::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:28:46
+error: calling `GenericDerivedDefault::default()` is more clear than this expression
+  --> $DIR/default_trait_access.rs:31:46
    |
 LL |     let s11: GenericDerivedDefault<String> = Default::default();
-   |                                              ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault<std::string::String>::default()`
+   |                                              ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()`
 
 error: calling `TupleDerivedDefault::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:34:36
+  --> $DIR/default_trait_access.rs:37:36
    |
 LL |     let s14: TupleDerivedDefault = Default::default();
    |                                    ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()`
 
 error: calling `ArrayDerivedDefault::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:36:36
+  --> $DIR/default_trait_access.rs:39:36
    |
 LL |     let s15: ArrayDerivedDefault = Default::default();
    |                                    ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()`
 
 error: calling `TupleStructDerivedDefault::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:40:42
+  --> $DIR/default_trait_access.rs:43:42
    |
 LL |     let s17: TupleStructDerivedDefault = Default::default();
    |                                          ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()`
diff --git a/src/tools/clippy/tests/ui/doc.rs b/src/tools/clippy/tests/ui/doc.rs
index 77620c857e6..68c5d32846f 100644
--- a/src/tools/clippy/tests/ui/doc.rs
+++ b/src/tools/clippy/tests/ui/doc.rs
@@ -49,6 +49,16 @@ fn test_emphasis() {
 fn test_units() {
 }
 
+/// This tests allowed identifiers.
+/// DirectX
+/// ECMAScript
+/// OAuth GraphQL
+/// TeX LaTeX BibTeX BibLaTeX
+/// CamelCase (see also #2395)
+/// be_sure_we_got_to_the_end_of_it
+fn test_allowed() {
+}
+
 /// This test has [a link_with_underscores][chunked-example] inside it. See #823.
 /// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)
 /// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].
@@ -168,9 +178,6 @@ fn issue_1920() {}
 /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
 fn issue_1832() {}
 
-/// Ok: CamelCase (It should not be surrounded by backticks)
-fn issue_2395() {}
-
 /// An iterator over mycrate::Collection's values.
 /// It should not lint a `'static` lifetime in ticks.
 fn issue_2210() {}
diff --git a/src/tools/clippy/tests/ui/doc.stderr b/src/tools/clippy/tests/ui/doc.stderr
index ae9bb394cb9..23fca43590b 100644
--- a/src/tools/clippy/tests/ui/doc.stderr
+++ b/src/tools/clippy/tests/ui/doc.stderr
@@ -54,131 +54,137 @@ error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the doc
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
+  --> $DIR/doc.rs:58:5
+   |
+LL | /// be_sure_we_got_to_the_end_of_it
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: you should put `link_with_underscores` between ticks in the documentation
-  --> $DIR/doc.rs:52:22
+  --> $DIR/doc.rs:62:22
    |
 LL | /// This test has [a link_with_underscores][chunked-example] inside it. See #823.
    |                      ^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `inline_link2` between ticks in the documentation
-  --> $DIR/doc.rs:55:21
+  --> $DIR/doc.rs:65:21
    |
 LL | /// It can also be [inline_link2].
    |                     ^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:65:5
+  --> $DIR/doc.rs:75:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:73:8
+  --> $DIR/doc.rs:83:8
    |
 LL | /// ## CamelCaseThing
    |        ^^^^^^^^^^^^^^
 
 error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:76:7
+  --> $DIR/doc.rs:86:7
    |
 LL | /// # CamelCaseThing
    |       ^^^^^^^^^^^^^^
 
 error: you should put `CamelCaseThing` between ticks in the documentation
-  --> $DIR/doc.rs:78:22
+  --> $DIR/doc.rs:88:22
    |
 LL | /// Not a title #897 CamelCaseThing
    |                      ^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:79:5
+  --> $DIR/doc.rs:89:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:86:5
+  --> $DIR/doc.rs:96:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:99:5
+  --> $DIR/doc.rs:109:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `FooBar` between ticks in the documentation
-  --> $DIR/doc.rs:110:43
+  --> $DIR/doc.rs:120:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
 
 error: you should put `BarQuz` between ticks in the documentation
-  --> $DIR/doc.rs:115:5
+  --> $DIR/doc.rs:125:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:116:1
+  --> $DIR/doc.rs:126:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `FooBar` between ticks in the documentation
-  --> $DIR/doc.rs:121:43
+  --> $DIR/doc.rs:131:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
 
 error: you should put `BarQuz` between ticks in the documentation
-  --> $DIR/doc.rs:126:5
+  --> $DIR/doc.rs:136:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:127:1
+  --> $DIR/doc.rs:137:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `be_sure_we_got_to_the_end_of_it` between ticks in the documentation
-  --> $DIR/doc.rs:138:5
+  --> $DIR/doc.rs:148:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:165:13
+  --> $DIR/doc.rs:175:13
    |
 LL | /// Not ok: http://www.unicode.org
    |             ^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:166:13
+  --> $DIR/doc.rs:176:13
    |
 LL | /// Not ok: https://www.unicode.org
    |             ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:167:13
+  --> $DIR/doc.rs:177:13
    |
 LL | /// Not ok: http://www.unicode.org/
    |             ^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> $DIR/doc.rs:168:13
+  --> $DIR/doc.rs:178:13
    |
 LL | /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: you should put `mycrate::Collection` between ticks in the documentation
-  --> $DIR/doc.rs:174:22
+  --> $DIR/doc.rs:181:22
    |
 LL | /// An iterator over mycrate::Collection's values.
    |                      ^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 30 previous errors
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/functions_maxlines.stderr b/src/tools/clippy/tests/ui/functions_maxlines.stderr
index c640c82d6d7..dc6c8ba2f15 100644
--- a/src/tools/clippy/tests/ui/functions_maxlines.stderr
+++ b/src/tools/clippy/tests/ui/functions_maxlines.stderr
@@ -1,4 +1,4 @@
-error: this function has a large number of lines
+error: this function has too many lines (102/100)
   --> $DIR/functions_maxlines.rs:58:1
    |
 LL | / fn bad_lines() {
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
index 1312c70b6d5..d7d45ef9b0b 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
@@ -1,4 +1,4 @@
-error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:38:5
    |
 LL |     x.field.map(do_nothing);
@@ -8,7 +8,7 @@ LL |     x.field.map(do_nothing);
    |
    = note: `-D clippy::option-map-unit-fn` implied by `-D warnings`
 
-error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:40:5
    |
 LL |     x.field.map(do_nothing);
@@ -16,7 +16,7 @@ LL |     x.field.map(do_nothing);
    |     |
    |     help: try this: `if let Some(x_field) = x.field { do_nothing(x_field) }`
 
-error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:42:5
    |
 LL |     x.field.map(diverge);
@@ -24,7 +24,7 @@ LL |     x.field.map(diverge);
    |     |
    |     help: try this: `if let Some(x_field) = x.field { diverge(x_field) }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:48:5
    |
 LL |     x.field.map(|value| x.do_option_nothing(value + captured));
@@ -32,7 +32,7 @@ LL |     x.field.map(|value| x.do_option_nothing(value + captured));
    |     |
    |     help: try this: `if let Some(value) = x.field { x.do_option_nothing(value + captured) }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:50:5
    |
 LL |     x.field.map(|value| { x.do_option_plus_one(value + captured); });
@@ -40,7 +40,7 @@ LL |     x.field.map(|value| { x.do_option_plus_one(value + captured); });
    |     |
    |     help: try this: `if let Some(value) = x.field { x.do_option_plus_one(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:53:5
    |
 LL |     x.field.map(|value| do_nothing(value + captured));
@@ -48,7 +48,7 @@ LL |     x.field.map(|value| do_nothing(value + captured));
    |     |
    |     help: try this: `if let Some(value) = x.field { do_nothing(value + captured) }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:55:5
    |
 LL |     x.field.map(|value| { do_nothing(value + captured) });
@@ -56,7 +56,7 @@ LL |     x.field.map(|value| { do_nothing(value + captured) });
    |     |
    |     help: try this: `if let Some(value) = x.field { do_nothing(value + captured) }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:57:5
    |
 LL |     x.field.map(|value| { do_nothing(value + captured); });
@@ -64,7 +64,7 @@ LL |     x.field.map(|value| { do_nothing(value + captured); });
    |     |
    |     help: try this: `if let Some(value) = x.field { do_nothing(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:59:5
    |
 LL |     x.field.map(|value| { { do_nothing(value + captured); } });
@@ -72,7 +72,7 @@ LL |     x.field.map(|value| { { do_nothing(value + captured); } });
    |     |
    |     help: try this: `if let Some(value) = x.field { do_nothing(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:62:5
    |
 LL |     x.field.map(|value| diverge(value + captured));
@@ -80,7 +80,7 @@ LL |     x.field.map(|value| diverge(value + captured));
    |     |
    |     help: try this: `if let Some(value) = x.field { diverge(value + captured) }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:64:5
    |
 LL |     x.field.map(|value| { diverge(value + captured) });
@@ -88,7 +88,7 @@ LL |     x.field.map(|value| { diverge(value + captured) });
    |     |
    |     help: try this: `if let Some(value) = x.field { diverge(value + captured) }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:66:5
    |
 LL |     x.field.map(|value| { diverge(value + captured); });
@@ -96,7 +96,7 @@ LL |     x.field.map(|value| { diverge(value + captured); });
    |     |
    |     help: try this: `if let Some(value) = x.field { diverge(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:68:5
    |
 LL |     x.field.map(|value| { { diverge(value + captured); } });
@@ -104,7 +104,7 @@ LL |     x.field.map(|value| { { diverge(value + captured); } });
    |     |
    |     help: try this: `if let Some(value) = x.field { diverge(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:73:5
    |
 LL |     x.field.map(|value| { let y = plus_one(value + captured); });
@@ -112,7 +112,7 @@ LL |     x.field.map(|value| { let y = plus_one(value + captured); });
    |     |
    |     help: try this: `if let Some(value) = x.field { let y = plus_one(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:75:5
    |
 LL |     x.field.map(|value| { plus_one(value + captured); });
@@ -120,7 +120,7 @@ LL |     x.field.map(|value| { plus_one(value + captured); });
    |     |
    |     help: try this: `if let Some(value) = x.field { plus_one(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:77:5
    |
 LL |     x.field.map(|value| { { plus_one(value + captured); } });
@@ -128,7 +128,7 @@ LL |     x.field.map(|value| { { plus_one(value + captured); } });
    |     |
    |     help: try this: `if let Some(value) = x.field { plus_one(value + captured); }`
 
-error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:80:5
    |
 LL |     x.field.map(|ref value| { do_nothing(value + captured) });
@@ -136,7 +136,7 @@ LL |     x.field.map(|ref value| { do_nothing(value + captured) });
    |     |
    |     help: try this: `if let Some(ref value) = x.field { do_nothing(value + captured) }`
 
-error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:82:5
    |
 LL |     option().map(do_nothing);}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index 67faa8bd4a0..5fb568672d3 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -58,12 +58,6 @@ fn or_fun_call() {
     let without_default = Some(Foo);
     without_default.unwrap_or_else(Foo::new);
 
-    let mut map = HashMap::<u64, String>::new();
-    map.entry(42).or_insert_with(String::new);
-
-    let mut btree = BTreeMap::<u64, String>::new();
-    btree.entry(42).or_insert_with(String::new);
-
     let stringy = Some(String::from(""));
     let _ = stringy.unwrap_or_else(|| "".to_owned());
 
@@ -122,6 +116,17 @@ pub fn skip_const_fn_with_no_args() {
         Some(42)
     }
     let _ = None.or(foo());
+
+    // See issue #5693.
+    let mut map = std::collections::HashMap::new();
+    map.insert(1, vec![1]);
+    map.entry(1).or_insert(vec![]);
+
+    let mut map = HashMap::<u64, String>::new();
+    map.entry(42).or_insert(String::new());
+
+    let mut btree = BTreeMap::<u64, String>::new();
+    btree.entry(42).or_insert(String::new());
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index 9867e2eedcf..737b0f7e55b 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -58,12 +58,6 @@ fn or_fun_call() {
     let without_default = Some(Foo);
     without_default.unwrap_or(Foo::new());
 
-    let mut map = HashMap::<u64, String>::new();
-    map.entry(42).or_insert(String::new());
-
-    let mut btree = BTreeMap::<u64, String>::new();
-    btree.entry(42).or_insert(String::new());
-
     let stringy = Some(String::from(""));
     let _ = stringy.unwrap_or("".to_owned());
 
@@ -122,6 +116,17 @@ pub fn skip_const_fn_with_no_args() {
         Some(42)
     }
     let _ = None.or(foo());
+
+    // See issue #5693.
+    let mut map = std::collections::HashMap::new();
+    map.insert(1, vec![1]);
+    map.entry(1).or_insert(vec![]);
+
+    let mut map = HashMap::<u64, String>::new();
+    map.entry(42).or_insert(String::new());
+
+    let mut btree = BTreeMap::<u64, String>::new();
+    btree.entry(42).or_insert(String::new());
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index bc5978b538f..b8a436993f3 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -60,35 +60,23 @@ error: use of `unwrap_or` followed by a function call
 LL |     without_default.unwrap_or(Foo::new());
    |                     ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)`
 
-error: use of `or_insert` followed by a function call
-  --> $DIR/or_fun_call.rs:62:19
-   |
-LL |     map.entry(42).or_insert(String::new());
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
-
-error: use of `or_insert` followed by a function call
-  --> $DIR/or_fun_call.rs:65:21
-   |
-LL |     btree.entry(42).or_insert(String::new());
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
-
 error: use of `unwrap_or` followed by a function call
-  --> $DIR/or_fun_call.rs:68:21
+  --> $DIR/or_fun_call.rs:62:21
    |
 LL |     let _ = stringy.unwrap_or("".to_owned());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())`
 
 error: use of `or` followed by a function call
-  --> $DIR/or_fun_call.rs:93:35
+  --> $DIR/or_fun_call.rs:87:35
    |
 LL |     let _ = Some("a".to_string()).or(Some("b".to_string()));
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))`
 
 error: use of `or` followed by a function call
-  --> $DIR/or_fun_call.rs:97:10
+  --> $DIR/or_fun_call.rs:91:10
    |
 LL |         .or(Some(Bar(b, Duration::from_secs(2))));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some(Bar(b, Duration::from_secs(2))))`
 
-error: aborting due to 15 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
index 467e00263cd..4f3a8c6b792 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
@@ -1,4 +1,4 @@
-error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:35:5
    |
 LL |     x.field.map(do_nothing);
@@ -8,7 +8,7 @@ LL |     x.field.map(do_nothing);
    |
    = note: `-D clippy::result-map-unit-fn` implied by `-D warnings`
 
-error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:37:5
    |
 LL |     x.field.map(do_nothing);
@@ -16,7 +16,7 @@ LL |     x.field.map(do_nothing);
    |     |
    |     help: try this: `if let Ok(x_field) = x.field { do_nothing(x_field) }`
 
-error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:39:5
    |
 LL |     x.field.map(diverge);
@@ -24,7 +24,7 @@ LL |     x.field.map(diverge);
    |     |
    |     help: try this: `if let Ok(x_field) = x.field { diverge(x_field) }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:45:5
    |
 LL |     x.field.map(|value| x.do_result_nothing(value + captured));
@@ -32,7 +32,7 @@ LL |     x.field.map(|value| x.do_result_nothing(value + captured));
    |     |
    |     help: try this: `if let Ok(value) = x.field { x.do_result_nothing(value + captured) }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:47:5
    |
 LL |     x.field.map(|value| { x.do_result_plus_one(value + captured); });
@@ -40,7 +40,7 @@ LL |     x.field.map(|value| { x.do_result_plus_one(value + captured); });
    |     |
    |     help: try this: `if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:50:5
    |
 LL |     x.field.map(|value| do_nothing(value + captured));
@@ -48,7 +48,7 @@ LL |     x.field.map(|value| do_nothing(value + captured));
    |     |
    |     help: try this: `if let Ok(value) = x.field { do_nothing(value + captured) }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:52:5
    |
 LL |     x.field.map(|value| { do_nothing(value + captured) });
@@ -56,7 +56,7 @@ LL |     x.field.map(|value| { do_nothing(value + captured) });
    |     |
    |     help: try this: `if let Ok(value) = x.field { do_nothing(value + captured) }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:54:5
    |
 LL |     x.field.map(|value| { do_nothing(value + captured); });
@@ -64,7 +64,7 @@ LL |     x.field.map(|value| { do_nothing(value + captured); });
    |     |
    |     help: try this: `if let Ok(value) = x.field { do_nothing(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:56:5
    |
 LL |     x.field.map(|value| { { do_nothing(value + captured); } });
@@ -72,7 +72,7 @@ LL |     x.field.map(|value| { { do_nothing(value + captured); } });
    |     |
    |     help: try this: `if let Ok(value) = x.field { do_nothing(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:59:5
    |
 LL |     x.field.map(|value| diverge(value + captured));
@@ -80,7 +80,7 @@ LL |     x.field.map(|value| diverge(value + captured));
    |     |
    |     help: try this: `if let Ok(value) = x.field { diverge(value + captured) }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:61:5
    |
 LL |     x.field.map(|value| { diverge(value + captured) });
@@ -88,7 +88,7 @@ LL |     x.field.map(|value| { diverge(value + captured) });
    |     |
    |     help: try this: `if let Ok(value) = x.field { diverge(value + captured) }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:63:5
    |
 LL |     x.field.map(|value| { diverge(value + captured); });
@@ -96,7 +96,7 @@ LL |     x.field.map(|value| { diverge(value + captured); });
    |     |
    |     help: try this: `if let Ok(value) = x.field { diverge(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:65:5
    |
 LL |     x.field.map(|value| { { diverge(value + captured); } });
@@ -104,7 +104,7 @@ LL |     x.field.map(|value| { { diverge(value + captured); } });
    |     |
    |     help: try this: `if let Ok(value) = x.field { diverge(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:70:5
    |
 LL |     x.field.map(|value| { let y = plus_one(value + captured); });
@@ -112,7 +112,7 @@ LL |     x.field.map(|value| { let y = plus_one(value + captured); });
    |     |
    |     help: try this: `if let Ok(value) = x.field { let y = plus_one(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:72:5
    |
 LL |     x.field.map(|value| { plus_one(value + captured); });
@@ -120,7 +120,7 @@ LL |     x.field.map(|value| { plus_one(value + captured); });
    |     |
    |     help: try this: `if let Ok(value) = x.field { plus_one(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:74:5
    |
 LL |     x.field.map(|value| { { plus_one(value + captured); } });
@@ -128,7 +128,7 @@ LL |     x.field.map(|value| { { plus_one(value + captured); } });
    |     |
    |     help: try this: `if let Ok(value) = x.field { plus_one(value + captured); }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_fixable.rs:77:5
    |
 LL |     x.field.map(|ref value| { do_nothing(value + captured) });
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
index b23cc608621..88e4efdb0f0 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr
@@ -1,4 +1,4 @@
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_unfixable.rs:23:5
    |
 LL |     x.field.map(|value| { do_nothing(value); do_nothing(value) });
@@ -8,7 +8,7 @@ LL |     x.field.map(|value| { do_nothing(value); do_nothing(value) });
    |
    = note: `-D clippy::result-map-unit-fn` implied by `-D warnings`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_unfixable.rs:25:5
    |
 LL |     x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });
@@ -16,7 +16,7 @@ LL |     x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value)
    |     |
    |     help: try this: `if let Ok(value) = x.field { ... }`
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_unfixable.rs:29:5
    |
 LL |        x.field.map(|value| {
@@ -30,7 +30,7 @@ LL | ||     });
    | |_______|
    | 
 
-error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
   --> $DIR/result_map_unit_fn_unfixable.rs:33:5
    |
 LL |     x.field.map(|value| { do_nothing(value); do_nothing(value); });
@@ -38,7 +38,7 @@ LL |     x.field.map(|value| { do_nothing(value); do_nothing(value); });
    |     |
    |     help: try this: `if let Ok(value) = x.field { ... }`
 
-error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
   --> $DIR/result_map_unit_fn_unfixable.rs:37:5
    |
 LL |     "12".parse::<i32>().map(diverge);
@@ -46,7 +46,7 @@ LL |     "12".parse::<i32>().map(diverge);
    |     |
    |     help: try this: `if let Ok(a) = "12".parse::<i32>() { diverge(a) }`
 
-error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type
+error: called `map(f)` on an `Result` value where `f` is a function that returns the unit type `()`
   --> $DIR/result_map_unit_fn_unfixable.rs:43:5
    |
 LL |     y.map(do_nothing);
diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs
index bfe27e02044..a37c8782ec3 100644
--- a/src/tools/clippy/tests/ui/same_item_push.rs
+++ b/src/tools/clippy/tests/ui/same_item_push.rs
@@ -1,5 +1,7 @@
 #![warn(clippy::same_item_push)]
 
+const VALUE: u8 = 7;
+
 fn mutate_increment(x: &mut u8) -> u8 {
     *x += 1;
     *x
@@ -9,65 +11,81 @@ fn increment(x: u8) -> u8 {
     x + 1
 }
 
-fn main() {
-    // Test for basic case
-    let mut spaces = Vec::with_capacity(10);
-    for _ in 0..10 {
-        spaces.push(vec![b' ']);
-    }
+fn fun() -> usize {
+    42
+}
 
-    let mut vec2: Vec<u8> = Vec::new();
+fn main() {
+    // ** linted cases **
+    let mut vec: Vec<u8> = Vec::new();
     let item = 2;
     for _ in 5..=20 {
-        vec2.push(item);
+        vec.push(item);
     }
 
-    let mut vec3: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     for _ in 0..15 {
         let item = 2;
-        vec3.push(item);
+        vec.push(item);
     }
 
-    let mut vec4: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     for _ in 0..15 {
-        vec4.push(13);
+        vec.push(13);
+    }
+
+    let mut vec = Vec::new();
+    for _ in 0..20 {
+        vec.push(VALUE);
+    }
+
+    let mut vec = Vec::new();
+    let item = VALUE;
+    for _ in 0..20 {
+        vec.push(item);
+    }
+
+    // ** non-linted cases **
+    let mut spaces = Vec::with_capacity(10);
+    for _ in 0..10 {
+        spaces.push(vec![b' ']);
     }
 
     // Suggestion should not be given as pushed variable can mutate
-    let mut vec5: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     let mut item: u8 = 2;
     for _ in 0..30 {
-        vec5.push(mutate_increment(&mut item));
+        vec.push(mutate_increment(&mut item));
     }
 
-    let mut vec6: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     let mut item: u8 = 2;
     let mut item2 = &mut mutate_increment(&mut item);
     for _ in 0..30 {
-        vec6.push(mutate_increment(item2));
+        vec.push(mutate_increment(item2));
     }
 
-    let mut vec7: Vec<usize> = Vec::new();
+    let mut vec: Vec<usize> = Vec::new();
     for (a, b) in [0, 1, 4, 9, 16].iter().enumerate() {
-        vec7.push(a);
+        vec.push(a);
     }
 
-    let mut vec8: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     for i in 0..30 {
-        vec8.push(increment(i));
+        vec.push(increment(i));
     }
 
-    let mut vec9: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     for i in 0..30 {
-        vec9.push(i + i * i);
+        vec.push(i + i * i);
     }
 
     // Suggestion should not be given as there are multiple pushes that are not the same
-    let mut vec10: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     let item: u8 = 2;
     for _ in 0..30 {
-        vec10.push(item);
-        vec10.push(item * 2);
+        vec.push(item);
+        vec.push(item * 2);
     }
 
     // Suggestion should not be given as Vec is not involved
@@ -82,16 +100,52 @@ fn main() {
     for i in 0..30 {
         vec_a.push(A { kind: i });
     }
-    let mut vec12: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     for a in vec_a {
-        vec12.push(2u8.pow(a.kind));
+        vec.push(2u8.pow(a.kind));
     }
 
     // Fix #5902
-    let mut vec13: Vec<u8> = Vec::new();
+    let mut vec: Vec<u8> = Vec::new();
     let mut item = 0;
     for _ in 0..10 {
-        vec13.push(item);
+        vec.push(item);
         item += 10;
     }
+
+    // Fix #5979
+    let mut vec: Vec<std::fs::File> = Vec::new();
+    for _ in 0..10 {
+        vec.push(std::fs::File::open("foobar").unwrap());
+    }
+    // Fix #5979
+    #[derive(Clone)]
+    struct S {}
+
+    trait T {}
+    impl T for S {}
+
+    let mut vec: Vec<Box<dyn T>> = Vec::new();
+    for _ in 0..10 {
+        vec.push(Box::new(S {}));
+    }
+
+    // Fix #5985
+    let mut vec = Vec::new();
+    let item = 42;
+    let item = fun();
+    for _ in 0..20 {
+        vec.push(item);
+    }
+
+    // Fix #5985
+    let mut vec = Vec::new();
+    let key = 1;
+    for _ in 0..20 {
+        let item = match key {
+            1 => 10,
+            _ => 0,
+        };
+        vec.push(item);
+    }
 }
diff --git a/src/tools/clippy/tests/ui/same_item_push.stderr b/src/tools/clippy/tests/ui/same_item_push.stderr
index ddc5d48cd41..d9ffa15780a 100644
--- a/src/tools/clippy/tests/ui/same_item_push.stderr
+++ b/src/tools/clippy/tests/ui/same_item_push.stderr
@@ -1,35 +1,43 @@
 error: it looks like the same item is being pushed into this Vec
-  --> $DIR/same_item_push.rs:16:9
+  --> $DIR/same_item_push.rs:23:9
    |
-LL |         spaces.push(vec![b' ']);
-   |         ^^^^^^
+LL |         vec.push(item);
+   |         ^^^
    |
    = note: `-D clippy::same-item-push` implied by `-D warnings`
-   = help: try using vec![vec![b' '];SIZE] or spaces.resize(NEW_SIZE, vec![b' '])
+   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
 
 error: it looks like the same item is being pushed into this Vec
-  --> $DIR/same_item_push.rs:22:9
+  --> $DIR/same_item_push.rs:29:9
    |
-LL |         vec2.push(item);
-   |         ^^^^
+LL |         vec.push(item);
+   |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec2.resize(NEW_SIZE, item)
+   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
 
 error: it looks like the same item is being pushed into this Vec
-  --> $DIR/same_item_push.rs:28:9
+  --> $DIR/same_item_push.rs:34:9
    |
-LL |         vec3.push(item);
-   |         ^^^^
+LL |         vec.push(13);
+   |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec3.resize(NEW_SIZE, item)
+   = help: try using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
 
 error: it looks like the same item is being pushed into this Vec
-  --> $DIR/same_item_push.rs:33:9
+  --> $DIR/same_item_push.rs:39:9
    |
-LL |         vec4.push(13);
-   |         ^^^^
+LL |         vec.push(VALUE);
+   |         ^^^
    |
-   = help: try using vec![13;SIZE] or vec4.resize(NEW_SIZE, 13)
+   = help: try using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
 
-error: aborting due to 4 previous errors
+error: it looks like the same item is being pushed into this Vec
+  --> $DIR/same_item_push.rs:45:9
+   |
+LL |         vec.push(item);
+   |         ^^^
+   |
+   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.rs b/src/tools/clippy/tests/ui/temporary_assignment.rs
index c6c315d5fab..b4a931043b0 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.rs
+++ b/src/tools/clippy/tests/ui/temporary_assignment.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::temporary_assignment)]
+#![allow(const_item_mutation)]
 
 use std::ops::{Deref, DerefMut};
 
@@ -53,11 +54,6 @@ fn main() {
     ArrayStruct { array: [0] }.array[0] = 1;
     (0, 0).0 = 1;
 
-    A.0 = 2;
-    B.field = 2;
-    C.structure.field = 2;
-    D.array[0] = 2;
-
     // no error
     s.field = 1;
     t.0 = 1;
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.stderr b/src/tools/clippy/tests/ui/temporary_assignment.stderr
index 4efe2d4bb67..4cc32c79f05 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.stderr
+++ b/src/tools/clippy/tests/ui/temporary_assignment.stderr
@@ -1,5 +1,5 @@
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:47:5
+  --> $DIR/temporary_assignment.rs:48:5
    |
 LL |     Struct { field: 0 }.field = 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     Struct { field: 0 }.field = 1;
    = note: `-D clippy::temporary-assignment` implied by `-D warnings`
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:48:5
+  --> $DIR/temporary_assignment.rs:49:5
    |
 LL | /     MultiStruct {
 LL | |         structure: Struct { field: 0 },
@@ -17,40 +17,16 @@ LL | |     .field = 1;
    | |______________^
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:53:5
+  --> $DIR/temporary_assignment.rs:54:5
    |
 LL |     ArrayStruct { array: [0] }.array[0] = 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:54:5
+  --> $DIR/temporary_assignment.rs:55:5
    |
 LL |     (0, 0).0 = 1;
    |     ^^^^^^^^^^^^
 
-error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:56:5
-   |
-LL |     A.0 = 2;
-   |     ^^^^^^^
-
-error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:57:5
-   |
-LL |     B.field = 2;
-   |     ^^^^^^^^^^^
-
-error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:58:5
-   |
-LL |     C.structure.field = 2;
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
-error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:59:5
-   |
-LL |     D.array[0] = 2;
-   |     ^^^^^^^^^^^^^^
-
-error: aborting due to 8 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
index 0d8a322f2b2..26b03bdc740 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
@@ -51,4 +51,12 @@ fn transmute_ptr_to_ptr() {
     let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
 }
 
+// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
+const _: &() = {
+    struct ZST;
+    let zst = &ZST;
+
+    unsafe { std::mem::transmute::<&'static ZST, &'static ()>(zst) }
+};
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs
index 2992abae775..fec115ff29d 100644
--- a/src/tools/clippy/tests/ui/unit_arg.rs
+++ b/src/tools/clippy/tests/ui/unit_arg.rs
@@ -1,5 +1,11 @@
 #![warn(clippy::unit_arg)]
-#![allow(clippy::no_effect, unused_must_use, unused_variables)]
+#![allow(
+    clippy::no_effect,
+    unused_must_use,
+    unused_variables,
+    clippy::unused_unit,
+    clippy::or_fun_call
+)]
 
 use std::fmt::Debug;
 
@@ -47,6 +53,11 @@ fn bad() {
             foo(3);
         },
     );
+    // here Some(foo(2)) isn't the top level statement expression, wrap the suggestion in a block
+    None.or(Some(foo(2)));
+    // in this case, the suggestion can be inlined, no need for a surrounding block
+    // foo(()); foo(()) instead of { foo(()); foo(()) }
+    foo(foo(()))
 }
 
 fn ok() {
diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr
index 56f6a855dfa..90fee3aab23 100644
--- a/src/tools/clippy/tests/ui/unit_arg.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg.stderr
@@ -1,5 +1,5 @@
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:23:5
+  --> $DIR/unit_arg.rs:29:5
    |
 LL | /     foo({
 LL | |         1;
@@ -11,34 +11,28 @@ help: remove the semicolon from the last statement in the block
    |
 LL |         1
    |
-help: or move the expression in front of the call...
+help: or move the expression in front of the call and replace it with the unit literal `()`
    |
 LL |     {
 LL |         1;
 LL |     };
-   |
-help: ...and use a unit literal instead
-   |
 LL |     foo(());
-   |         ^^
+   |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:26:5
+  --> $DIR/unit_arg.rs:32:5
    |
 LL |     foo(foo(1));
    |     ^^^^^^^^^^^
    |
-help: move the expression in front of the call...
+help: move the expression in front of the call and replace it with the unit literal `()`
    |
 LL |     foo(1);
-   |
-help: ...and use a unit literal instead
-   |
 LL |     foo(());
-   |         ^^
+   |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:27:5
+  --> $DIR/unit_arg.rs:33:5
    |
 LL | /     foo({
 LL | |         foo(1);
@@ -50,20 +44,17 @@ help: remove the semicolon from the last statement in the block
    |
 LL |         foo(2)
    |
-help: or move the expression in front of the call...
+help: or move the expression in front of the call and replace it with the unit literal `()`
    |
 LL |     {
 LL |         foo(1);
 LL |         foo(2);
 LL |     };
-   |
-help: ...and use a unit literal instead
-   |
 LL |     foo(());
-   |         ^^
+   |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:32:5
+  --> $DIR/unit_arg.rs:38:5
    |
 LL | /     b.bar({
 LL | |         1;
@@ -74,35 +65,29 @@ help: remove the semicolon from the last statement in the block
    |
 LL |         1
    |
-help: or move the expression in front of the call...
+help: or move the expression in front of the call and replace it with the unit literal `()`
    |
 LL |     {
 LL |         1;
 LL |     };
-   |
-help: ...and use a unit literal instead
-   |
 LL |     b.bar(());
-   |           ^^
+   |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:35:5
+  --> $DIR/unit_arg.rs:41:5
    |
 LL |     taking_multiple_units(foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: move the expressions in front of the call...
+help: move the expressions in front of the call and replace them with the unit literal `()`
    |
 LL |     foo(0);
 LL |     foo(1);
-   |
-help: ...and use unit literals instead
-   |
 LL |     taking_multiple_units((), ());
-   |                           ^^  ^^
+   |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:36:5
+  --> $DIR/unit_arg.rs:42:5
    |
 LL | /     taking_multiple_units(foo(0), {
 LL | |         foo(1);
@@ -114,21 +99,18 @@ help: remove the semicolon from the last statement in the block
    |
 LL |         foo(2)
    |
-help: or move the expressions in front of the call...
+help: or move the expressions in front of the call and replace them with the unit literal `()`
    |
 LL |     foo(0);
 LL |     {
 LL |         foo(1);
 LL |         foo(2);
 LL |     };
-   |
-help: ...and use unit literals instead
-   |
 LL |     taking_multiple_units((), ());
-   |                           ^^  ^^
+   |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:40:5
+  --> $DIR/unit_arg.rs:46:5
    |
 LL | /     taking_multiple_units(
 LL | |         {
@@ -147,7 +129,7 @@ help: remove the semicolon from the last statement in the block
    |
 LL |             foo(3)
    |
-help: or move the expressions in front of the call...
+help: or move the expressions in front of the call and replace them with the unit literal `()`
    |
 LL |     {
 LL |         foo(0);
@@ -156,26 +138,44 @@ LL |     };
 LL |     {
 LL |         foo(2);
  ...
-help: ...and use unit literals instead
+
+error: passing a unit value to a function
+  --> $DIR/unit_arg.rs:57:13
+   |
+LL |     None.or(Some(foo(2)));
+   |             ^^^^^^^^^^^^
    |
-LL |         (),
-LL |         (),
+help: move the expression in front of the call and replace it with the unit literal `()`
+   |
+LL |     None.or({
+LL |         foo(2);
+LL |         Some(())
+LL |     });
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:82:5
+  --> $DIR/unit_arg.rs:60:5
    |
-LL |     Some(foo(1))
+LL |     foo(foo(()))
    |     ^^^^^^^^^^^^
    |
-help: move the expression in front of the call...
+help: move the expression in front of the call and replace it with the unit literal `()`
    |
-LL |     foo(1);
+LL |     foo(());
+LL |     foo(())
    |
-help: ...and use a unit literal instead
+
+error: passing a unit value to a function
+  --> $DIR/unit_arg.rs:93:5
    |
+LL |     Some(foo(1))
+   |     ^^^^^^^^^^^^
+   |
+help: move the expression in front of the call and replace it with the unit literal `()`
+   |
+LL |     foo(1);
 LL |     Some(())
-   |          ^^
+   |
 
-error: aborting due to 8 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr
index bb58483584b..456b12a2c6b 100644
--- a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.stderr
@@ -22,14 +22,11 @@ error: passing unit values to a function
 LL |     taking_two_units({}, foo(0));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: move the expression in front of the call...
+help: move the expression in front of the call and replace it with the unit literal `()`
    |
 LL |     foo(0);
-   |
-help: ...and use unit literals instead
-   |
 LL |     taking_two_units((), ());
-   |                      ^^  ^^
+   |
 
 error: passing unit values to a function
   --> $DIR/unit_arg_empty_blocks.rs:18:5
@@ -37,15 +34,12 @@ error: passing unit values to a function
 LL |     taking_three_units({}, foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: move the expressions in front of the call...
+help: move the expressions in front of the call and replace them with the unit literal `()`
    |
 LL |     foo(0);
 LL |     foo(1);
-   |
-help: ...and use unit literals instead
-   |
 LL |     taking_three_units((), (), ());
-   |                        ^^  ^^  ^^
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed b/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed
index 31c2ba0f9c5..ad0d0387db0 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed
@@ -25,17 +25,25 @@ fn unnecessary_sort_by() {
     vec.sort_by(|_, b| b.cmp(&5));
     vec.sort_by(|_, b| b.cmp(c));
     vec.sort_unstable_by(|a, _| a.cmp(c));
+
+    // Ignore vectors of references
+    let mut vec: Vec<&&&isize> = vec![&&&3, &&&6, &&&1, &&&2, &&&5];
+    vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));
+    vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));
+    vec.sort_by(|a, b| b.cmp(a));
+    vec.sort_unstable_by(|a, b| b.cmp(a));
 }
 
-// Should not be linted to avoid hitting https://github.com/rust-lang/rust/issues/34162
+// Do not suggest returning a reference to the closure parameter of `Vec::sort_by_key`
 mod issue_5754 {
-    struct Test(String);
+    #[derive(Clone, Copy)]
+    struct Test(usize);
 
     #[derive(PartialOrd, Ord, PartialEq, Eq)]
-    struct Wrapper<'a>(&'a str);
+    struct Wrapper<'a>(&'a usize);
 
     impl Test {
-        fn name(&self) -> &str {
+        fn name(&self) -> &usize {
             &self.0
         }
 
@@ -60,7 +68,33 @@ mod issue_5754 {
     }
 }
 
+// `Vec::sort_by_key` closure parameter is `F: FnMut(&T) -> K`
+// The suggestion is destructuring T and we know T is not a reference, so test that non-Copy T are
+// not linted.
+mod issue_6001 {
+    struct Test(String);
+
+    impl Test {
+        // Return an owned type so that we don't hit the fix for 5754
+        fn name(&self) -> String {
+            self.0.clone()
+        }
+    }
+
+    pub fn test() {
+        let mut args: Vec<Test> = vec![];
+
+        // Forward
+        args.sort_by(|a, b| a.name().cmp(&b.name()));
+        args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));
+        // Reverse
+        args.sort_by(|a, b| b.name().cmp(&a.name()));
+        args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));
+    }
+}
+
 fn main() {
     unnecessary_sort_by();
     issue_5754::test();
+    issue_6001::test();
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.rs b/src/tools/clippy/tests/ui/unnecessary_sort_by.rs
index a3c8ae468ed..9746f6e6849 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.rs
@@ -25,17 +25,25 @@ fn unnecessary_sort_by() {
     vec.sort_by(|_, b| b.cmp(&5));
     vec.sort_by(|_, b| b.cmp(c));
     vec.sort_unstable_by(|a, _| a.cmp(c));
+
+    // Ignore vectors of references
+    let mut vec: Vec<&&&isize> = vec![&&&3, &&&6, &&&1, &&&2, &&&5];
+    vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));
+    vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));
+    vec.sort_by(|a, b| b.cmp(a));
+    vec.sort_unstable_by(|a, b| b.cmp(a));
 }
 
-// Should not be linted to avoid hitting https://github.com/rust-lang/rust/issues/34162
+// Do not suggest returning a reference to the closure parameter of `Vec::sort_by_key`
 mod issue_5754 {
-    struct Test(String);
+    #[derive(Clone, Copy)]
+    struct Test(usize);
 
     #[derive(PartialOrd, Ord, PartialEq, Eq)]
-    struct Wrapper<'a>(&'a str);
+    struct Wrapper<'a>(&'a usize);
 
     impl Test {
-        fn name(&self) -> &str {
+        fn name(&self) -> &usize {
             &self.0
         }
 
@@ -60,7 +68,33 @@ mod issue_5754 {
     }
 }
 
+// `Vec::sort_by_key` closure parameter is `F: FnMut(&T) -> K`
+// The suggestion is destructuring T and we know T is not a reference, so test that non-Copy T are
+// not linted.
+mod issue_6001 {
+    struct Test(String);
+
+    impl Test {
+        // Return an owned type so that we don't hit the fix for 5754
+        fn name(&self) -> String {
+            self.0.clone()
+        }
+    }
+
+    pub fn test() {
+        let mut args: Vec<Test> = vec![];
+
+        // Forward
+        args.sort_by(|a, b| a.name().cmp(&b.name()));
+        args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));
+        // Reverse
+        args.sort_by(|a, b| b.name().cmp(&a.name()));
+        args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));
+    }
+}
+
 fn main() {
     unnecessary_sort_by();
     issue_5754::test();
+    issue_6001::test();
 }
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index b222e2f7976..a5fcde768f1 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -49,6 +49,14 @@ mod a {
     pub use self::b::C;
 }
 
+// don't lint on clippy::wildcard_imports for `use` items
+#[allow(clippy::wildcard_imports)]
+pub use std::io::prelude::*;
+
+// don't lint on clippy::enum_glob_use for `use` items
+#[allow(clippy::enum_glob_use)]
+pub use std::cmp::Ordering::*;
+
 fn test_indented_attr() {
     #![allow(clippy::almost_swapped)]
     use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index 3422eace4ab..0396d39e3d5 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -49,6 +49,14 @@ mod a {
     pub use self::b::C;
 }
 
+// don't lint on clippy::wildcard_imports for `use` items
+#[allow(clippy::wildcard_imports)]
+pub use std::io::prelude::*;
+
+// don't lint on clippy::enum_glob_use for `use` items
+#[allow(clippy::enum_glob_use)]
+pub use std::cmp::Ordering::*;
+
 fn test_indented_attr() {
     #[allow(clippy::almost_swapped)]
     use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/useless_attribute.stderr b/src/tools/clippy/tests/ui/useless_attribute.stderr
index 57ba976730c..d0194e4bbbe 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.stderr
+++ b/src/tools/clippy/tests/ui/useless_attribute.stderr
@@ -13,7 +13,7 @@ LL | #[cfg_attr(feature = "cargo-clippy", allow(dead_code))]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(feature = "cargo-clippy", allow(dead_code)`
 
 error: useless lint attribute
-  --> $DIR/useless_attribute.rs:53:5
+  --> $DIR/useless_attribute.rs:61:5
    |
 LL |     #[allow(clippy::almost_swapped)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(clippy::almost_swapped)]`
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 848bd3a43e8..2f832b53a90 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -261,6 +261,9 @@ pub struct Config {
     /// Path to / name of the Microsoft Console Debugger (CDB) executable
     pub cdb: Option<OsString>,
 
+    /// Version of CDB
+    pub cdb_version: Option<[u16; 4]>,
+
     /// Path to / name of the GDB executable
     pub gdb: Option<String>,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 0efa668ecc8..17649dfab37 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -8,8 +8,8 @@ use std::path::{Path, PathBuf};
 use tracing::*;
 
 use crate::common::{CompareMode, Config, Debugger, FailMode, Mode, PassMode};
-use crate::extract_gdb_version;
 use crate::util;
+use crate::{extract_cdb_version, extract_gdb_version};
 
 #[cfg(test)]
 mod tests;
@@ -105,6 +105,10 @@ impl EarlyProps {
                     props.ignore = true;
                 }
 
+                if config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln) {
+                    props.ignore = true;
+                }
+
                 if config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln) {
                     props.ignore = true;
                 }
@@ -131,6 +135,21 @@ impl EarlyProps {
 
         return props;
 
+        fn ignore_cdb(config: &Config, line: &str) -> bool {
+            if let Some(actual_version) = config.cdb_version {
+                if let Some(min_version) = line.strip_prefix("min-cdb-version:").map(str::trim) {
+                    let min_version = extract_cdb_version(min_version).unwrap_or_else(|| {
+                        panic!("couldn't parse version range: {:?}", min_version);
+                    });
+
+                    // Ignore if actual version is smaller than the minimum
+                    // required version
+                    return actual_version < min_version;
+                }
+            }
+            false
+        }
+
         fn ignore_gdb(config: &Config, line: &str) -> bool {
             if let Some(actual_version) = config.gdb_version {
                 if let Some(rest) = line.strip_prefix("min-gdb-version:").map(str::trim) {
@@ -142,8 +161,8 @@ impl EarlyProps {
                     if start_ver != end_ver {
                         panic!("Expected single GDB version")
                     }
-                    // Ignore if actual version is smaller the minimum required
-                    // version
+                    // Ignore if actual version is smaller than the minimum
+                    // required version
                     return actual_version < start_ver;
                 } else if let Some(rest) = line.strip_prefix("ignore-gdb-version:").map(str::trim) {
                     let (min_version, max_version) =
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index adf2fa7fd8e..190a9c62210 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -163,7 +163,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
 
     let target = opt_str2(matches.opt_str("target"));
     let android_cross_path = opt_path(matches, "android-cross-path");
-    let cdb = analyze_cdb(matches.opt_str("cdb"), &target);
+    let (cdb, cdb_version) = analyze_cdb(matches.opt_str("cdb"), &target);
     let (gdb, gdb_version, gdb_native_rust) =
         analyze_gdb(matches.opt_str("gdb"), &target, &android_cross_path);
     let (lldb_version, lldb_native_rust) = matches
@@ -216,6 +216,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         target,
         host: opt_str2(matches.opt_str("host")),
         cdb,
+        cdb_version,
         gdb,
         gdb_version,
         gdb_native_rust,
@@ -773,8 +774,30 @@ fn find_cdb(target: &str) -> Option<OsString> {
 }
 
 /// Returns Path to CDB
-fn analyze_cdb(cdb: Option<String>, target: &str) -> Option<OsString> {
-    cdb.map(OsString::from).or_else(|| find_cdb(target))
+fn analyze_cdb(cdb: Option<String>, target: &str) -> (Option<OsString>, Option<[u16; 4]>) {
+    let cdb = cdb.map(OsString::from).or_else(|| find_cdb(target));
+
+    let mut version = None;
+    if let Some(cdb) = cdb.as_ref() {
+        if let Ok(output) = Command::new(cdb).arg("/version").output() {
+            if let Some(first_line) = String::from_utf8_lossy(&output.stdout).lines().next() {
+                version = extract_cdb_version(&first_line);
+            }
+        }
+    }
+
+    (cdb, version)
+}
+
+fn extract_cdb_version(full_version_line: &str) -> Option<[u16; 4]> {
+    // Example full_version_line: "cdb version 10.0.18362.1"
+    let version = full_version_line.rsplit(' ').next()?;
+    let mut components = version.split('.');
+    let major: u16 = components.next().unwrap().parse().unwrap();
+    let minor: u16 = components.next().unwrap().parse().unwrap();
+    let patch: u16 = components.next().unwrap_or("0").parse().unwrap();
+    let build: u16 = components.next().unwrap_or("0").parse().unwrap();
+    Some([major, minor, patch, build])
 }
 
 /// Returns (Path to GDB, GDB Version, GDB has Rust Support)
diff --git a/src/tools/miri b/src/tools/miri
-Subproject c28a8eeb742d7104bc407e12212c5143439963f
+Subproject 604a674ea37b302fd605df67be10a24ce94ad0a
diff --git a/src/tools/rls b/src/tools/rls
-Subproject 48ef96dd00b90d950a122ca180923aba77efaf7
+Subproject db6a9e01aa3453b64c05707e99e97045f971295
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject ac4b134c6be27642dbe915f32a41f9a21bd0c1c
+Subproject 0275b08d1521606fa733f76fe5d5707717456fb
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 351e2d4481c..11d61606ff5 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -69,7 +69,7 @@ serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value"] }
 smallvec-0_6 = { package = "smallvec", version = "0.6", features = ['union', 'may_dangle'] }
 smallvec = { version = "1.0", features = ['union', 'may_dangle'] }
-syn = { version = "1", features = ['fold', 'full', 'extra-traits', 'visit'] }
+syn = { version = "1", features = ['fold', 'full', 'extra-traits', 'visit', 'visit-mut'] }
 url = { version = "2.0", features = ['serde'] }
 
 [target.'cfg(not(windows))'.dependencies]
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
-Subproject 48f6c32ec1dd370f3157a27b48a000fd8c1185a
+Subproject 01f2eadccc74cf70eb11e6300ffa7e02b18b002