about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
-rw-r--r--Cargo.lock35
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs2
-rw-r--r--compiler/rustc_attr/src/builtin.rs27
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs1
-rw-r--r--compiler/rustc_driver/Cargo.toml6
-rw-r--r--compiler/rustc_driver/src/pretty.rs48
-rw-r--r--compiler/rustc_error_codes/src/lib.rs3
-rw-r--r--compiler/rustc_expand/src/base.rs12
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_lint/src/context.rs6
-rw-r--r--compiler/rustc_lint/src/lib.rs41
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs111
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs95
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp24
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp124
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp55
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs66
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs12
-rw-r--r--compiler/rustc_middle/src/ty/error.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs33
-rw-r--r--compiler/rustc_mir/src/borrow_check/invalidation.rs8
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/input_output.rs7
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs2
-rw-r--r--compiler/rustc_mir/src/shim.rs2
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs2
-rw-r--r--compiler/rustc_mir/src/transform/const_prop.rs2
-rw-r--r--compiler/rustc_mir/src/transform/generator.rs13
-rw-r--r--compiler/rustc_mir/src/transform/inline.rs2
-rw-r--r--compiler/rustc_mir/src/transform/promote_consts.rs2
-rw-r--r--compiler/rustc_mir/src/util/pretty.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs25
-rw-r--r--compiler/rustc_passes/src/check_attr.rs25
-rw-r--r--compiler/rustc_passes/src/lib_features.rs2
-rw-r--r--compiler/rustc_passes/src/stability.rs76
-rw-r--r--compiler/rustc_resolve/src/imports.rs32
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs29
-rw-r--r--compiler/rustc_session/src/config.rs18
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs6
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs7
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_traits/src/chalk/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs2
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs2
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs8
-rw-r--r--library/alloc/src/vec/mod.rs24
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/vec.rs4
-rw-r--r--library/core/src/borrow.rs2
-rw-r--r--library/core/src/clone.rs3
-rw-r--r--library/core/src/iter/adapters/zip.rs3
-rw-r--r--library/core/src/iter/traits/iterator.rs1
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/ops/deref.rs2
-rw-r--r--library/core/tests/iter/adapters/intersperse.rs4
-rw-r--r--library/core/tests/iter/adapters/zip.rs20
-rw-r--r--library/profiler_builtins/build.rs1
-rw-r--r--library/std/src/collections/hash/map/tests.rs8
-rw-r--r--library/std/src/io/buffered/bufreader.rs10
-rw-r--r--library/std/src/io/mod.rs37
-rw-r--r--library/std/src/io/tests.rs49
-rw-r--r--library/std/src/io/util.rs10
-rw-r--r--src/bootstrap/bootstrap.py5
-rw-r--r--src/bootstrap/builder.rs18
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/ci/docker/host-x86_64/arm-android/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-android/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile8
-rw-r--r--src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile8
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-python.sh7
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile3
-rwxr-xr-xsrc/ci/docker/scripts/cmake.sh34
-rw-r--r--src/doc/rust.css6
-rw-r--r--src/doc/rustdoc/src/lints.md35
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/core.rs106
-rw-r--r--src/librustdoc/doctest.rs15
-rw-r--r--src/librustdoc/html/layout.rs9
-rw-r--r--src/librustdoc/html/markdown.rs3
-rw-r--r--src/librustdoc/html/render/mod.rs17
-rw-r--r--src/librustdoc/html/static/main.js98
-rw-r--r--src/librustdoc/html/static/rustdoc.css14
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/librustdoc/lint.rs188
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs6
-rw-r--r--src/librustdoc/passes/doc_test_lints.rs7
-rw-r--r--src/librustdoc/passes/html_tags.rs3
-rw-r--r--src/librustdoc/passes/non_autolinks.rs3
m---------src/llvm-project0
-rw-r--r--src/test/assembly/asm/riscv-types.rs29
-rw-r--r--src/test/codegen/function-arguments.rs3
-rw-r--r--src/test/codegen/packed.rs4
-rw-r--r--src/test/codegen/repr-transparent-aggregates-1.rs18
-rw-r--r--src/test/codegen/repr-transparent-aggregates-2.rs18
-rw-r--r--src/test/codegen/repr-transparent-aggregates-3.rs18
-rw-r--r--src/test/run-make-fulldeps/pgo-use/Makefile9
-rw-r--r--src/test/run-make-fulldeps/split-dwarf/Makefile2
-rw-r--r--src/test/rustdoc-ui/assoc-item-not-in-scope.rs2
-rw-r--r--src/test/rustdoc-ui/assoc-item-not-in-scope.stderr4
-rw-r--r--src/test/rustdoc-ui/check-attr-test.rs2
-rw-r--r--src/test/rustdoc-ui/check-attr-test.stderr4
-rw-r--r--src/test/rustdoc-ui/check-attr.rs2
-rw-r--r--src/test/rustdoc-ui/check-attr.stderr4
-rw-r--r--src/test/rustdoc-ui/check-fail.stderr4
-rw-r--r--src/test/rustdoc-ui/check.stderr15
-rw-r--r--src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs2
-rw-r--r--src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr4
-rw-r--r--src/test/rustdoc-ui/doc-attr.rs10
-rw-r--r--src/test/rustdoc-ui/doc-attr.stderr13
-rw-r--r--src/test/rustdoc-ui/doc-without-codeblock.rs2
-rw-r--r--src/test/rustdoc-ui/doc-without-codeblock.stderr6
-rw-r--r--src/test/rustdoc-ui/intra-doc/alias-ice.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/alias-ice.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/ambiguity.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/ambiguity.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/anchors.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/anchors.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/broken-reexport.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/double-anchor.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/errors.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/errors.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/malformed-generics.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/malformed-generics.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/non-path-primitives.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/prim-conflict.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/prim-conflict.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.private.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/private.public.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/span-ice-55723.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/unused-extern-crate.rs2
-rw-r--r--src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr4
-rw-r--r--src/test/rustdoc-ui/intra-doc/warning-crlf.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc/warning.stderr2
-rw-r--r--src/test/rustdoc-ui/invalid-html-tags.rs2
-rw-r--r--src/test/rustdoc-ui/invalid-html-tags.stderr4
-rw-r--r--src/test/rustdoc-ui/issue-58473-2.rs2
-rw-r--r--src/test/rustdoc-ui/issue-74134.private.stderr2
-rw-r--r--src/test/rustdoc-ui/issue-74134.public.stderr2
-rw-r--r--src/test/rustdoc-ui/lint-group.stderr8
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.rs4
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.stderr4
-rw-r--r--src/test/rustdoc-ui/no-crate-level-doc-lint.rs4
-rw-r--r--src/test/rustdoc-ui/no-crate-level-doc-lint.stderr6
-rw-r--r--src/test/rustdoc-ui/private-doc-test.rs2
-rw-r--r--src/test/rustdoc-ui/private-item-doc-test.rs2
-rw-r--r--src/test/rustdoc-ui/private-item-doc-test.stderr4
-rw-r--r--src/test/rustdoc-ui/pub-export-lint.rs2
-rw-r--r--src/test/rustdoc-ui/pub-export-lint.stderr4
-rw-r--r--src/test/rustdoc-ui/reference-link-reports-error-once.rs2
-rw-r--r--src/test/rustdoc-ui/reference-link-reports-error-once.stderr4
-rw-r--r--src/test/rustdoc-ui/reference-links.rs2
-rw-r--r--src/test/rustdoc-ui/reference-links.stderr4
-rw-r--r--src/test/rustdoc-ui/renamed-lint-still-applies.rs5
-rw-r--r--src/test/rustdoc-ui/renamed-lint-still-applies.stderr23
-rw-r--r--src/test/rustdoc-ui/unknown-renamed-lints.rs11
-rw-r--r--src/test/rustdoc-ui/unknown-renamed-lints.stderr24
-rw-r--r--src/test/rustdoc-ui/url-improvements.rs4
-rw-r--r--src/test/rustdoc-ui/url-improvements.stderr4
-rw-r--r--src/test/rustdoc/extern-links.rs2
-rw-r--r--src/test/rustdoc/intra-doc/non-path-primitives.rs2
-rw-r--r--src/test/rustdoc/issue-28927.rs2
-rw-r--r--src/test/ui/attributes/const-stability-on-macro.rs13
-rw-r--r--src/test/ui/attributes/const-stability-on-macro.stderr20
-rw-r--r--src/test/ui/attributes/doc-attr.rs10
-rw-r--r--src/test/ui/attributes/doc-attr.stderr13
-rw-r--r--src/test/ui/deprecation/deprecation-in-staged-api.rs8
-rw-r--r--src/test/ui/deprecation/deprecation-in-staged-api.stderr10
-rw-r--r--src/test/ui/issues/issue-81584.fixed8
-rw-r--r--src/test/ui/issues/issue-81584.rs8
-rw-r--r--src/test/ui/issues/issue-81584.stderr14
-rw-r--r--src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs16
-rw-r--r--src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr40
-rw-r--r--src/test/ui/lint/auxiliary/lint_stability_fields.rs23
-rw-r--r--src/test/ui/lint/lint-stability-fields-deprecated.rs11
-rw-r--r--src/test/ui/lint/lint-stability-fields-deprecated.stderr126
-rw-r--r--src/test/ui/lint/lint-stability-fields.rs20
-rw-r--r--src/test/ui/lint/lint-stability-fields.stderr86
-rw-r--r--src/test/ui/lint/noop-method-call.rs54
-rw-r--r--src/test/ui/lint/noop-method-call.stderr39
-rw-r--r--src/test/ui/lint/rustdoc-renamed.rs14
-rw-r--r--src/test/ui/lint/rustdoc-renamed.stderr20
-rw-r--r--src/test/ui/pub/pub-reexport-priv-extern-crate.rs8
-rw-r--r--src/test/ui/pub/pub-reexport-priv-extern-crate.stderr39
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-issue-43027.rs9
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr8
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.rs7
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.stderr20
-rw-r--r--src/test/ui/static/static-reference-to-fn-2.stderr2
-rw-r--r--src/test/ui/underscore-imports/hygiene-2.rs1
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/tidy/src/deps.rs1
236 files changed, 2065 insertions, 888 deletions
diff --git a/.gitmodules b/.gitmodules
index 40e6fc2c19d..8618f61f04a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -37,7 +37,7 @@
 [submodule "src/llvm-project"]
 	path = src/llvm-project
 	url = https://github.com/rust-lang/llvm-project.git
-	branch = rustc/11.0-2021-01-05
+	branch = rustc/12.0-2021-02-03
 [submodule "src/doc/embedded-book"]
 	path = src/doc/embedded-book
 	url = https://github.com/rust-embedded/book.git
diff --git a/Cargo.lock b/Cargo.lock
index 0666abadcba..9e773c572cc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -533,13 +533,15 @@ dependencies = [
 
 [[package]]
 name = "chrono"
-version = "0.4.15"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
 dependencies = [
+ "libc",
  "num-integer",
  "num-traits",
  "time",
+ "winapi 0.3.9",
 ]
 
 [[package]]
@@ -4844,9 +4846,9 @@ dependencies = [
 
 [[package]]
 name = "sharded-slab"
-version = "0.0.9"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
+checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
 dependencies = [
  "lazy_static",
 ]
@@ -5340,20 +5342,21 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
 
 [[package]]
 name = "tracing"
-version = "0.1.19"
+version = "0.1.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
+checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
+ "pin-project-lite 0.2.4",
  "tracing-attributes",
  "tracing-core",
 ]
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.11"
+version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
+checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5371,9 +5374,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-log"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
+checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
 dependencies = [
  "lazy_static",
  "log",
@@ -5392,9 +5395,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-subscriber"
-version = "0.2.13"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ef0a5e15477aa303afbfac3a44cba9b6430fdaad52423b1e6c0dbbe28c3eedd"
+checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96"
 dependencies = [
  "ansi_term 0.12.1",
  "chrono",
@@ -5415,15 +5418,15 @@ dependencies = [
 
 [[package]]
 name = "tracing-tree"
-version = "0.1.6"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43aac8afb493b08e1e1904956f7407c1e671b9c83b26a17e1bd83d6a3520e350"
+checksum = "1a60657cfbf397c603257a8230b3f427e6a2a4e5911a59331b9bb4dffff5b608"
 dependencies = [
  "ansi_term 0.12.1",
  "atty",
- "chrono",
  "termcolor",
  "tracing",
+ "tracing-log",
  "tracing-subscriber",
 ]
 
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 52ac7540f69..1e224dbf833 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -34,7 +34,7 @@ impl MarkedAttrs {
 }
 
 pub fn is_known_lint_tool(m_item: Ident) -> bool {
-    [sym::clippy, sym::rustc].contains(&m_item.name)
+    [sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item.name)
 }
 
 impl NestedMetaItem {
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 24da75114a6..e58b266fdb9 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -176,7 +176,7 @@ pub fn find_stability(
     sess: &Session,
     attrs: &[Attribute],
     item_sp: Span,
-) -> (Option<Stability>, Option<ConstStability>) {
+) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>) {
     find_stability_generic(sess, attrs.iter(), item_sp)
 }
 
@@ -184,15 +184,16 @@ fn find_stability_generic<'a, I>(
     sess: &Session,
     attrs_iter: I,
     item_sp: Span,
-) -> (Option<Stability>, Option<ConstStability>)
+) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>)
 where
     I: Iterator<Item = &'a Attribute>,
 {
     use StabilityLevel::*;
 
-    let mut stab: Option<Stability> = None;
-    let mut const_stab: Option<ConstStability> = None;
+    let mut stab: Option<(Stability, Span)> = None;
+    let mut const_stab: Option<(ConstStability, Span)> = None;
     let mut promotable = false;
+
     let diagnostic = &sess.parse_sess.span_diagnostic;
 
     'outer: for attr in attrs_iter {
@@ -356,10 +357,12 @@ where
                             }
                             let level = Unstable { reason, issue: issue_num, is_soft };
                             if sym::unstable == meta_name {
-                                stab = Some(Stability { level, feature });
+                                stab = Some((Stability { level, feature }, attr.span));
                             } else {
-                                const_stab =
-                                    Some(ConstStability { level, feature, promotable: false });
+                                const_stab = Some((
+                                    ConstStability { level, feature, promotable: false },
+                                    attr.span,
+                                ));
                             }
                         }
                         (None, _, _) => {
@@ -432,10 +435,12 @@ where
                         (Some(feature), Some(since)) => {
                             let level = Stable { since };
                             if sym::stable == meta_name {
-                                stab = Some(Stability { level, feature });
+                                stab = Some((Stability { level, feature }, attr.span));
                             } else {
-                                const_stab =
-                                    Some(ConstStability { level, feature, promotable: false });
+                                const_stab = Some((
+                                    ConstStability { level, feature, promotable: false },
+                                    attr.span,
+                                ));
                             }
                         }
                         (None, _) => {
@@ -455,7 +460,7 @@ where
 
     // Merge the const-unstable info into the stability info
     if promotable {
-        if let Some(ref mut stab) = const_stab {
+        if let Some((ref mut stab, _)) = const_stab {
             stab.promotable = promotable;
         } else {
             struct_span_err!(
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index d714ff1fe9b..d9393ffe534 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -430,7 +430,13 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
                 assert!(!on_stack);
                 let i = apply(attrs);
-                llvm::Attribute::StructRet.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
+                unsafe {
+                    llvm::LLVMRustAddStructRetAttr(
+                        llfn,
+                        llvm::AttributePlace::Argument(i).as_uint(),
+                        self.ret.layout.llvm_type(cx),
+                    );
+                }
             }
             _ => {}
         }
@@ -486,8 +492,13 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
                 assert!(!on_stack);
                 let i = apply(attrs);
-                llvm::Attribute::StructRet
-                    .apply_callsite(llvm::AttributePlace::Argument(i), callsite);
+                unsafe {
+                    llvm::LLVMRustAddStructRetCallSiteAttr(
+                        callsite,
+                        llvm::AttributePlace::Argument(i).as_uint(),
+                        self.ret.layout.llvm_type(bx),
+                    );
+                }
             }
             _ => {}
         }
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 26815de403f..38c8ae711a4 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -304,6 +304,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
             } else if options.contains(InlineAsmOptions::READONLY) {
                 llvm::Attribute::ReadOnly.apply_callsite(llvm::AttributePlace::Function, result);
             }
+            llvm::Attribute::WillReturn.apply_callsite(llvm::AttributePlace::Function, result);
         } else if options.contains(InlineAsmOptions::NOMEM) {
             llvm::Attribute::InaccessibleMemOnly
                 .apply_callsite(llvm::AttributePlace::Function, result);
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 3ddc7424202..9f6a2ae3ca1 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -104,6 +104,10 @@ fn strip_x86_address_spaces(data_layout: String) -> String {
     data_layout.replace("-p270:32:32-p271:32:32-p272:64:64-", "-")
 }
 
+fn strip_powerpc64_vectors(data_layout: String) -> String {
+    data_layout.replace("-v256:256:256-v512:512:512", "")
+}
+
 pub unsafe fn create_module(
     tcx: TyCtxt<'_>,
     llcx: &'ll llvm::Context,
@@ -119,6 +123,9 @@ pub unsafe fn create_module(
     {
         target_data_layout = strip_x86_address_spaces(target_data_layout);
     }
+    if llvm_util::get_version() < (12, 0, 0) && sess.target.arch == "powerpc64" {
+        target_data_layout = strip_powerpc64_vectors(target_data_layout);
+    }
 
     // Ensure the data-layout values hardcoded remain the defaults.
     if sess.target.is_builtin {
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index e777f363eb0..e47b8fde40f 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -162,7 +162,7 @@ pub(crate) fn write_filenames_section_to_buffer<'a>(
 pub(crate) fn write_mapping_to_buffer(
     virtual_file_mapping: Vec<u32>,
     expressions: Vec<CounterExpression>,
-    mut mapping_regions: Vec<CounterMappingRegion>,
+    mapping_regions: Vec<CounterMappingRegion>,
     buffer: &RustString,
 ) {
     unsafe {
@@ -171,7 +171,7 @@ pub(crate) fn write_mapping_to_buffer(
             virtual_file_mapping.len() as c_uint,
             expressions.as_ptr(),
             expressions.len() as c_uint,
-            mapping_regions.as_mut_ptr(),
+            mapping_regions.as_ptr(),
             mapping_regions.len() as c_uint,
             buffer,
         );
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 85d1b702399..b2e0a4311a7 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1417,7 +1417,7 @@ fn generator_layout_and_saved_local_names(
     def_id: DefId,
 ) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
     let body = tcx.optimized_mir(def_id);
-    let generator_layout = body.generator_layout.as_ref().unwrap();
+    let generator_layout = body.generator_layout().unwrap();
     let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);
 
     let state_arg = mir::Local::new(1);
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 8c1740d8f25..e6d60044c84 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -132,6 +132,7 @@ pub enum Attribute {
     ReadNone = 26,
     InaccessibleMemOnly = 27,
     SanitizeHWAddress = 28,
+    WillReturn = 29,
 }
 
 /// LLVMIntPredicate
@@ -239,6 +240,7 @@ pub enum TypeKind {
     Token = 16,
     ScalableVector = 17,
     BFloat = 18,
+    X86_AMX = 19,
 }
 
 impl TypeKind {
@@ -263,6 +265,7 @@ impl TypeKind {
             TypeKind::Token => rustc_codegen_ssa::common::TypeKind::Token,
             TypeKind::ScalableVector => rustc_codegen_ssa::common::TypeKind::ScalableVector,
             TypeKind::BFloat => rustc_codegen_ssa::common::TypeKind::BFloat,
+            TypeKind::X86_AMX => rustc_codegen_ssa::common::TypeKind::X86_AMX,
         }
     }
 }
@@ -674,9 +677,7 @@ pub mod coverageinfo {
     /// array", encoded separately), and source location (start and end positions of the represented
     /// code region).
     ///
-    /// Aligns with [llvm::coverage::CounterMappingRegion](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L224-L227)
-    /// Important: The Rust struct layout (order and types of fields) must match its C++
-    /// counterpart.
+    /// Matches LLVMRustCounterMappingRegion.
     #[derive(Copy, Clone, Debug)]
     #[repr(C)]
     pub struct CounterMappingRegion {
@@ -1073,6 +1074,7 @@ extern "C" {
     pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64);
     pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64);
     pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type);
+    pub fn LLVMRustAddStructRetAttr(Fn: &Value, index: c_uint, ty: &Type);
     pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute);
     pub fn LLVMRustAddFunctionAttrStringValue(
         Fn: &Value,
@@ -1108,6 +1110,7 @@ extern "C" {
     pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
     pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
     pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type);
+    pub fn LLVMRustAddStructRetCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type);
 
     // Operations on load/store instructions (only)
     pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool);
@@ -1792,7 +1795,7 @@ extern "C" {
         NumVirtualFileMappingIDs: c_uint,
         Expressions: *const coverage_map::CounterExpression,
         NumExpressions: c_uint,
-        MappingRegions: *mut coverageinfo::CounterMappingRegion,
+        MappingRegions: *const coverageinfo::CounterMappingRegion,
         NumMappingRegions: c_uint,
         BufferOut: &RustString,
     );
diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs
index 005d2efdd3b..5f21046b05e 100644
--- a/compiler/rustc_codegen_ssa/src/back/rpath.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs
@@ -24,7 +24,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig<'_>) -> Vec<String> {
 
     debug!("preparing the RPATH!");
 
-    let libs = config.used_crates.clone();
+    let libs = config.used_crates;
     let libs = libs.iter().filter_map(|&(_, ref l)| l.option()).collect::<Vec<_>>();
     let rpaths = get_rpaths(config, &libs);
     let mut flags = rpaths_to_flags(&rpaths);
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index 780b1d2cd94..afd83bfcb56 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -95,6 +95,7 @@ pub enum TypeKind {
     Token,
     ScalableVector,
     BFloat,
+    X86_AMX,
 }
 
 // FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
index b88b556d143..47cff34cd3e 100644
--- a/compiler/rustc_driver/Cargo.toml
+++ b/compiler/rustc_driver/Cargo.toml
@@ -10,9 +10,9 @@ crate-type = ["dylib"]
 [dependencies]
 libc = "0.2"
 atty = "0.2"
-tracing = { version = "0.1.18" }
-tracing-subscriber = { version = "0.2.13", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
-tracing-tree = "0.1.6"
+tracing = { version = "0.1.25" }
+tracing-subscriber = { version = "0.2.16", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
+tracing-tree = "0.1.8"
 rustc_middle = { path = "../rustc_middle" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs
index 1dcc4d147ac..38c493a920d 100644
--- a/compiler/rustc_driver/src/pretty.rs
+++ b/compiler/rustc_driver/src/pretty.rs
@@ -9,7 +9,7 @@ use rustc_hir_pretty as pprust_hir;
 use rustc_middle::hir::map as hir_map;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_mir::util::{write_mir_graphviz, write_mir_pretty};
-use rustc_session::config::{Input, PpHirMode, PpMode, PpSourceMode};
+use rustc_session::config::{Input, PpAstTreeMode, PpHirMode, PpMode, PpSourceMode};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
 use rustc_span::FileName;
@@ -391,24 +391,29 @@ pub fn print_after_parsing(
 ) {
     let (src, src_name) = get_source(input, sess);
 
-    let out = if let Source(s) = ppm {
-        // Silently ignores an identified node.
-        call_with_pp_support(&s, sess, None, move |annotation| {
-            debug!("pretty printing source code {:?}", s);
-            let sess = annotation.sess();
-            let parse = &sess.parse_sess;
-            pprust::print_crate(
-                sess.source_map(),
-                krate,
-                src_name,
-                src,
-                annotation.pp_ann(),
-                false,
-                parse.edition,
-            )
-        })
-    } else {
-        unreachable!()
+    let out = match ppm {
+        Source(s) => {
+            // Silently ignores an identified node.
+            call_with_pp_support(&s, sess, None, move |annotation| {
+                debug!("pretty printing source code {:?}", s);
+                let sess = annotation.sess();
+                let parse = &sess.parse_sess;
+                pprust::print_crate(
+                    sess.source_map(),
+                    krate,
+                    src_name,
+                    src,
+                    annotation.pp_ann(),
+                    false,
+                    parse.edition,
+                )
+            })
+        }
+        AstTree(PpAstTreeMode::Normal) => {
+            debug!("pretty printing AST tree");
+            format!("{:#?}", krate)
+        }
+        _ => unreachable!(),
     };
 
     write_or_print(&out, ofile);
@@ -447,6 +452,11 @@ pub fn print_after_hir_lowering<'tcx>(
             })
         }
 
+        AstTree(PpAstTreeMode::Expanded) => {
+            debug!("pretty-printing expanded AST");
+            format!("{:#?}", krate)
+        }
+
         Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
             debug!("pretty printing HIR {:?}", s);
             let sess = annotation.sess();
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index e4a70253144..14ddb3e2079 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -1,4 +1,5 @@
-#![deny(invalid_codeblock_attributes)]
+#![cfg_attr(bootstrap, deny(invalid_codeblock_attributes))]
+#![cfg_attr(not(bootstrap), deny(rustdoc::invalid_codeblock_attributes))]
 //! This library is used to gather all error codes into one place,
 //! the goal being to make their maintenance easier.
 
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index ce8103c0f85..929cc56294d 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -774,10 +774,16 @@ impl SyntaxExtension {
             .find_by_name(attrs, sym::rustc_builtin_macro)
             .map(|a| a.value_str().unwrap_or(name));
         let (stability, const_stability) = attr::find_stability(&sess, attrs, span);
-        if const_stability.is_some() {
+        if let Some((_, sp)) = const_stability {
             sess.parse_sess
                 .span_diagnostic
-                .span_err(span, "macros cannot have const stability attributes");
+                .struct_span_err(sp, "macros cannot have const stability attributes")
+                .span_label(sp, "invalid const stability attribute")
+                .span_label(
+                    sess.source_map().guess_head_span(span),
+                    "const stability attribute affects this macro",
+                )
+                .emit();
         }
 
         SyntaxExtension {
@@ -786,7 +792,7 @@ impl SyntaxExtension {
             allow_internal_unstable,
             allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe),
             local_inner_macros,
-            stability,
+            stability: stability.map(|(s, _)| s),
             deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
             helper_attrs,
             edition,
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index aa54ffb132d..5012d500cee 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -272,7 +272,7 @@ declare_features! (
     (accepted, doc_alias, "1.48.0", Some(50146), None),
     /// Allows patterns with concurrent by-move and by-ref bindings.
     /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
-    (accepted, move_ref_pattern, "1.48.0", Some(68354), None),
+    (accepted, move_ref_pattern, "1.49.0", Some(68354), None),
     /// The smallest useful subset of `const_generics`.
     (accepted, min_const_generics, "1.51.0", Some(74878), None),
 
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b8db51f590d..7d5577cdca6 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -89,6 +89,7 @@ impl SessionLintStore for LintStore {
 }
 
 /// The target of the `by_name` map, which accounts for renaming/deprecation.
+#[derive(Debug)]
 enum TargetLint {
     /// A direct lint target
     Id(LintId),
@@ -470,7 +471,10 @@ impl LintStore {
             Some(&Id(ref id)) => {
                 CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name)))
             }
-            _ => CheckLintNameResult::NoLint(None),
+            Some(other) => {
+                tracing::debug!("got renamed lint {:?}", other);
+                CheckLintNameResult::NoLint(None)
+            }
         }
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 638b73c27a8..9e61c83fda3 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -57,6 +57,7 @@ mod methods;
 mod non_ascii_idents;
 mod non_fmt_panic;
 mod nonstandard_style;
+mod noop_method_call;
 mod passes;
 mod redundant_semicolon;
 mod traits;
@@ -69,9 +70,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::{
-    BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS,
-    EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS,
-    MISSING_DOC_CODE_EXAMPLES, NON_AUTOLINKS, PRIVATE_DOC_TESTS,
+    BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
 };
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
@@ -83,6 +82,7 @@ use methods::*;
 use non_ascii_idents::*;
 use non_fmt_panic::NonPanicFmt;
 use nonstandard_style::*;
+use noop_method_call::*;
 use redundant_semicolon::*;
 use traits::*;
 use types::*;
@@ -170,6 +170,7 @@ macro_rules! late_lint_passes {
                 DropTraitConstraints: DropTraitConstraints,
                 TemporaryCStringAsPtr: TemporaryCStringAsPtr,
                 NonPanicFmt: NonPanicFmt,
+                NoopMethodCall: NoopMethodCall,
             ]
         );
     };
@@ -314,17 +315,6 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
                                        // MACRO_USE_EXTERN_CRATE
     );
 
-    add_lint_group!(
-        "rustdoc",
-        NON_AUTOLINKS,
-        BROKEN_INTRA_DOC_LINKS,
-        PRIVATE_INTRA_DOC_LINKS,
-        INVALID_CODEBLOCK_ATTRIBUTES,
-        MISSING_DOC_CODE_EXAMPLES,
-        PRIVATE_DOC_TESTS,
-        INVALID_HTML_TAGS
-    );
-
     // Register renamed and removed lints.
     store.register_renamed("single_use_lifetime", "single_use_lifetimes");
     store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
@@ -334,8 +324,29 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
     store.register_renamed("async_idents", "keyword_idents");
     store.register_renamed("exceeding_bitshifts", "arithmetic_overflow");
     store.register_renamed("redundant_semicolon", "redundant_semicolons");
-    store.register_renamed("intra_doc_link_resolution_failure", "broken_intra_doc_links");
     store.register_renamed("overlapping_patterns", "overlapping_range_endpoints");
+
+    // These were moved to tool lints, but rustc still sees them when compiling normally, before
+    // tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use
+    // `register_removed` explicitly.
+    const RUSTDOC_LINTS: &[&str] = &[
+        "broken_intra_doc_links",
+        "private_intra_doc_links",
+        "missing_crate_level_docs",
+        "missing_doc_code_examples",
+        "private_doc_tests",
+        "invalid_codeblock_attributes",
+        "invalid_html_tags",
+        "non_autolinks",
+    ];
+    for rustdoc_lint in RUSTDOC_LINTS {
+        store.register_removed(rustdoc_lint, &format!("use `rustdoc::{}` instead", rustdoc_lint));
+    }
+    store.register_removed(
+        "intra_doc_link_resolution_failure",
+        "use `rustdoc::broken_intra_doc_links` instead",
+    );
+
     store.register_removed("unknown_features", "replaced by an error");
     store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
     store.register_removed("negate_unsigned", "cast a signed value instead");
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
new file mode 100644
index 00000000000..479cc00199f
--- /dev/null
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -0,0 +1,111 @@
+use crate::context::LintContext;
+use crate::rustc_middle::ty::TypeFoldable;
+use crate::LateContext;
+use crate::LateLintPass;
+use rustc_hir::def::DefKind;
+use rustc_hir::{Expr, ExprKind};
+use rustc_middle::ty;
+use rustc_span::symbol::sym;
+
+declare_lint! {
+    /// The `noop_method_call` lint detects specific calls to noop methods
+    /// such as a calling `<&T as Clone>::clone` where `T: !Clone`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// # #![allow(unused)]
+    /// #![warn(noop_method_call)]
+    /// struct Foo;
+    /// let foo = &Foo;
+    /// let clone: &Foo = foo.clone();
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Some method calls are noops meaning that they do nothing. Usually such methods
+    /// are the result of blanket implementations that happen to create some method invocations
+    /// that end up not doing anything. For instance, `Clone` is implemented on all `&T`, but
+    /// calling `clone` on a `&T` where `T` does not implement clone, actually doesn't do anything
+    /// as references are copy. This lint detects these calls and warns the user about them.
+    pub NOOP_METHOD_CALL,
+    Allow,
+    "detects the use of well-known noop methods"
+}
+
+declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]);
+
+impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        // We only care about method calls.
+        let (call, elements) = match expr.kind {
+            ExprKind::MethodCall(call, _, elements, _) => (call, elements),
+            _ => return,
+        };
+        // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
+        // traits and ignore any other method call.
+        let (trait_id, did) = match cx.typeck_results().type_dependent_def(expr.hir_id) {
+            // Verify we are dealing with a method/associated function.
+            Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) {
+                // Check that we're dealing with a trait method for one of the traits we care about.
+                Some(trait_id)
+                    if [sym::Clone, sym::Deref, sym::Borrow]
+                        .iter()
+                        .any(|s| cx.tcx.is_diagnostic_item(*s, trait_id)) =>
+                {
+                    (trait_id, did)
+                }
+                _ => return,
+            },
+            _ => return,
+        };
+        let substs = cx.typeck_results().node_substs(expr.hir_id);
+        if substs.needs_subst() {
+            // We can't resolve on types that require monomorphization, so we don't handle them if
+            // we need to perfom substitution.
+            return;
+        }
+        let param_env = cx.tcx.param_env(trait_id);
+        // Resolve the trait method instance.
+        let i = match ty::Instance::resolve(cx.tcx, param_env, did, substs) {
+            Ok(Some(i)) => i,
+            _ => return,
+        };
+        // (Re)check that it implements the noop diagnostic.
+        for s in [sym::noop_method_clone, sym::noop_method_deref, sym::noop_method_borrow].iter() {
+            if cx.tcx.is_diagnostic_item(*s, i.def_id()) {
+                let method = &call.ident.name;
+                let receiver = &elements[0];
+                let receiver_ty = cx.typeck_results().expr_ty(receiver);
+                let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
+                if receiver_ty != expr_ty {
+                    // This lint will only trigger if the receiver type and resulting expression \
+                    // type are the same, implying that the method call is unnecessary.
+                    return;
+                }
+                let expr_span = expr.span;
+                let note = format!(
+                    "the type `{:?}` which `{}` is being called on is the same as \
+                     the type returned from `{}`, so the method call does not do \
+                     anything and can be removed",
+                    receiver_ty, method, method,
+                );
+
+                let span = expr_span.with_lo(receiver.span.hi());
+                cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
+                    let method = &call.ident.name;
+                    let message = format!(
+                        "call to `.{}()` on a reference in this situation does nothing",
+                        &method,
+                    );
+                    lint.build(&message)
+                        .span_label(span, "unnecessary method call")
+                        .note(&note)
+                        .emit()
+                });
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 46138df07bf..12d849e3b94 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1876,93 +1876,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `broken_intra_doc_links` lint detects failures in resolving
-    /// intra-doc link targets. This is a `rustdoc` only lint, see the
-    /// documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#broken_intra_doc_links
-    pub BROKEN_INTRA_DOC_LINKS,
-    Warn,
-    "failures in resolving intra-doc link targets"
-}
-
-declare_lint! {
-    /// This is a subset of `broken_intra_doc_links` that warns when linking from
-    /// a public item to a private one. This is a `rustdoc` only lint, see the
-    /// documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#private_intra_doc_links
-    pub PRIVATE_INTRA_DOC_LINKS,
-    Warn,
-    "linking from a public item to a private one"
-}
-
-declare_lint! {
-    /// The `invalid_codeblock_attributes` lint detects code block attributes
-    /// in documentation examples that have potentially mis-typed values. This
-    /// is a `rustdoc` only lint, see the documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#invalid_codeblock_attributes
-    pub INVALID_CODEBLOCK_ATTRIBUTES,
-    Warn,
-    "codeblock attribute looks a lot like a known one"
-}
-
-declare_lint! {
-    /// The `missing_crate_level_docs` lint detects if documentation is
-    /// missing at the crate root. This is a `rustdoc` only lint, see the
-    /// documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#missing_crate_level_docs
-    pub MISSING_CRATE_LEVEL_DOCS,
-    Allow,
-    "detects crates with no crate-level documentation"
-}
-
-declare_lint! {
-    /// The `missing_doc_code_examples` lint detects publicly-exported items
-    /// without code samples in their documentation. This is a `rustdoc` only
-    /// lint, see the documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples
-    pub MISSING_DOC_CODE_EXAMPLES,
-    Allow,
-    "detects publicly-exported items without code samples in their documentation"
-}
-
-declare_lint! {
-    /// The `private_doc_tests` lint detects code samples in docs of private
-    /// items not documented by `rustdoc`. This is a `rustdoc` only lint, see
-    /// the documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#private_doc_tests
-    pub PRIVATE_DOC_TESTS,
-    Allow,
-    "detects code samples in docs of private items not documented by rustdoc"
-}
-
-declare_lint! {
-    /// The `invalid_html_tags` lint detects invalid HTML tags. This is a
-    /// `rustdoc` only lint, see the documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#invalid_html_tags
-    pub INVALID_HTML_TAGS,
-    Allow,
-    "detects invalid HTML tags in doc comments"
-}
-
-declare_lint! {
-    /// The `non_autolinks` lint detects when a URL could be written using
-    /// only angle brackets. This is a `rustdoc` only lint, see the
-    /// documentation in the [rustdoc book].
-    ///
-    /// [rustdoc book]: ../../../rustdoc/lints.html#non_autolinks
-    pub NON_AUTOLINKS,
-    Warn,
-    "detects URLs that could be written using only angle brackets"
-}
-
-declare_lint! {
     /// The `where_clauses_object_safety` lint detects for [object safety] of
     /// [where clauses].
     ///
@@ -3020,14 +2933,6 @@ declare_lint_pass! {
         ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
         UNSTABLE_NAME_COLLISIONS,
         IRREFUTABLE_LET_PATTERNS,
-        BROKEN_INTRA_DOC_LINKS,
-        PRIVATE_INTRA_DOC_LINKS,
-        INVALID_CODEBLOCK_ATTRIBUTES,
-        MISSING_CRATE_LEVEL_DOCS,
-        MISSING_DOC_CODE_EXAMPLES,
-        INVALID_HTML_TAGS,
-        PRIVATE_DOC_TESTS,
-        NON_AUTOLINKS,
         WHERE_CLAUSES_OBJECT_SAFETY,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
         MACRO_USE_EXTERN_CRATE,
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 25badc3f4e1..e97d96e3a4e 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -8,6 +8,17 @@
 
 using namespace llvm;
 
+struct LLVMRustCounterMappingRegion {
+  coverage::Counter Count;
+  uint32_t FileID;
+  uint32_t ExpandedFileID;
+  uint32_t LineStart;
+  uint32_t ColumnStart;
+  uint32_t LineEnd;
+  uint32_t ColumnEnd;
+  coverage::CounterMappingRegion::RegionKind Kind;
+};
+
 extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
     const char* const Filenames[],
     size_t FilenamesLen,
@@ -27,13 +38,22 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
     unsigned NumVirtualFileMappingIDs,
     const coverage::CounterExpression *Expressions,
     unsigned NumExpressions,
-    coverage::CounterMappingRegion *MappingRegions,
+    LLVMRustCounterMappingRegion *RustMappingRegions,
     unsigned NumMappingRegions,
     RustStringRef BufferOut) {
+  // Convert from FFI representation to LLVM representation.
+  SmallVector<coverage::CounterMappingRegion, 0> MappingRegions;
+  MappingRegions.reserve(NumMappingRegions);
+  for (const auto &Region : makeArrayRef(RustMappingRegions, NumMappingRegions)) {
+    MappingRegions.emplace_back(
+        Region.Count, Region.FileID, Region.ExpandedFileID,
+        Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
+        Region.Kind);
+  }
   auto CoverageMappingWriter = coverage::CoverageMappingWriter(
       makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
       makeArrayRef(Expressions, NumExpressions),
-      makeMutableArrayRef(MappingRegions, NumMappingRegions));
+      MappingRegions);
   RawRustStringOstream OS(BufferOut);
   CoverageMappingWriter.write(OS);
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 0e3bf5615af..f67e06706ea 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -86,6 +86,7 @@ enum LLVMRustAttribute {
   ReadNone = 26,
   InaccessibleMemOnly = 27,
   SanitizeHWAddress = 28,
+  WillReturn = 29,
 };
 
 typedef struct OpaqueRustString *RustStringRef;
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 5263d5dcf3e..2f28162f908 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -5,6 +5,7 @@
 
 #include "LLVMWrapper.h"
 
+#include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -683,6 +684,25 @@ void LLVMSelfProfileInitializeCallbacks(
     PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
     LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
+#if LLVM_VERSION_GE(12, 0)
+  PIC.registerBeforeNonSkippedPassCallback([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.registerAfterPassCallback(
+      [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any IR,
+                                            const PreservedAnalyses &Preserved) {
+        AfterPassCallback(LlvmSelfProfiler);
+      });
+
+  PIC.registerAfterPassInvalidatedCallback(
+      [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, const PreservedAnalyses &Preserved) {
+        AfterPassCallback(LlvmSelfProfiler);
+      });
+#else
   PIC.registerBeforePassCallback([LlvmSelfProfiler, BeforePassCallback](
                                      StringRef Pass, llvm::Any Ir) {
     std::string PassName = Pass.str();
@@ -700,6 +720,7 @@ void LLVMSelfProfileInitializeCallbacks(
       [LlvmSelfProfiler, AfterPassCallback](StringRef Pass) {
         AfterPassCallback(LlvmSelfProfiler);
       });
+#endif
 
   PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
                                          StringRef Pass, llvm::Any Ir) {
@@ -760,8 +781,15 @@ LLVMRustOptimizeWithNewPassManager(
   PTO.LoopVectorization = LoopVectorize;
   PTO.SLPVectorization = SLPVectorize;
 
+  // FIXME: We may want to expose this as an option.
+  bool DebugPassManager = false;
+
   PassInstrumentationCallbacks PIC;
+#if LLVM_VERSION_GE(12, 0)
+  StandardInstrumentations SI(DebugPassManager);
+#else
   StandardInstrumentations SI;
+#endif
   SI.registerCallbacks(PIC);
 
   if (LlvmSelfProfiler){
@@ -777,10 +805,12 @@ LLVMRustOptimizeWithNewPassManager(
     PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse);
   }
 
+#if LLVM_VERSION_GE(12, 0)
+  PassBuilder PB(DebugPassManager, TM, PTO, PGOOpt, &PIC);
+#else
   PassBuilder PB(TM, PTO, PGOOpt, &PIC);
+#endif
 
-  // FIXME: We may want to expose this as an option.
-  bool DebugPassManager = false;
   LoopAnalysisManager LAM(DebugPassManager);
   FunctionAnalysisManager FAM(DebugPassManager);
   CGSCCAnalysisManager CGAM(DebugPassManager);
@@ -802,7 +832,8 @@ LLVMRustOptimizeWithNewPassManager(
 
   // 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;
+  std::vector<std::function<void(ModulePassManager &, PassBuilder::OptimizationLevel)>>
+      PipelineStartEPCallbacks;
 #if LLVM_VERSION_GE(11, 0)
   std::vector<std::function<void(ModulePassManager &, PassBuilder::OptimizationLevel)>>
       OptimizerLastEPCallbacks;
@@ -812,9 +843,11 @@ LLVMRustOptimizeWithNewPassManager(
 #endif
 
   if (VerifyIR) {
-    PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
+    PipelineStartEPCallbacks.push_back(
+      [VerifyIR](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
         MPM.addPass(VerifierPass());
-    });
+      }
+    );
   }
 
   if (SanitizerOptions) {
@@ -832,9 +865,11 @@ LLVMRustOptimizeWithNewPassManager(
       );
 #else
 #if LLVM_VERSION_GE(10, 0)
-      PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
-        MPM.addPass(MemorySanitizerPass(Options));
-      });
+      PipelineStartEPCallbacks.push_back(
+        [Options](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
+          MPM.addPass(MemorySanitizerPass(Options));
+        }
+      );
 #endif
       OptimizerLastEPCallbacks.push_back(
         [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
@@ -854,9 +889,11 @@ LLVMRustOptimizeWithNewPassManager(
       );
 #else
 #if LLVM_VERSION_GE(10, 0)
-      PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
-        MPM.addPass(ThreadSanitizerPass());
-      });
+      PipelineStartEPCallbacks.push_back(
+        [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
+          MPM.addPass(ThreadSanitizerPass());
+        }
+      );
 #endif
       OptimizerLastEPCallbacks.push_back(
         [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
@@ -879,9 +916,11 @@ LLVMRustOptimizeWithNewPassManager(
         }
       );
 #else
-      PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
-        MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
-      });
+      PipelineStartEPCallbacks.push_back(
+        [&](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
+          MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
+        }
+      );
       OptimizerLastEPCallbacks.push_back(
         [SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
           FPM.addPass(AddressSanitizerPass(
@@ -890,7 +929,7 @@ LLVMRustOptimizeWithNewPassManager(
         }
       );
       PipelineStartEPCallbacks.push_back(
-        [SanitizerOptions](ModulePassManager &MPM) {
+        [SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
           MPM.addPass(ModuleAddressSanitizerPass(
               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
         }
@@ -907,7 +946,7 @@ LLVMRustOptimizeWithNewPassManager(
       );
 #else
       PipelineStartEPCallbacks.push_back(
-        [SanitizerOptions](ModulePassManager &MPM) {
+        [SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
           MPM.addPass(HWAddressSanitizerPass(
               /*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
         }
@@ -917,35 +956,53 @@ LLVMRustOptimizeWithNewPassManager(
   }
 
   ModulePassManager MPM(DebugPassManager);
+  bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
   if (!NoPrepopulatePasses) {
     if (OptLevel == PassBuilder::OptimizationLevel::O0) {
+#if LLVM_VERSION_GE(12, 0)
       for (const auto &C : PipelineStartEPCallbacks)
-        C(MPM);
+        PB.registerPipelineStartEPCallback(C);
+      for (const auto &C : OptimizerLastEPCallbacks)
+        PB.registerOptimizerLastEPCallback(C);
 
-#if LLVM_VERSION_GE(11, 0)
+      // Pass false as we manually schedule ThinLTOBufferPasses below.
+      MPM = PB.buildO0DefaultPipeline(OptLevel, /* PreLinkLTO */ false);
+#else
+      for (const auto &C : PipelineStartEPCallbacks)
+        C(MPM, OptLevel);
+
+# if LLVM_VERSION_GE(11, 0)
       for (const auto &C : OptimizerLastEPCallbacks)
         C(MPM, OptLevel);
-#else
+# else
       if (!OptimizerLastEPCallbacks.empty()) {
         FunctionPassManager FPM(DebugPassManager);
         for (const auto &C : OptimizerLastEPCallbacks)
           C(FPM, OptLevel);
         MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
       }
-#endif
+# endif
 
       MPM.addPass(AlwaysInlinerPass(EmitLifetimeMarkers));
 
-#if LLVM_VERSION_GE(10, 0)
+# if LLVM_VERSION_GE(10, 0)
       if (PGOOpt) {
         PB.addPGOInstrPassesForO0(
             MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
             /*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
       }
+# endif
 #endif
     } else {
+#if LLVM_VERSION_GE(12, 0)
       for (const auto &C : PipelineStartEPCallbacks)
         PB.registerPipelineStartEPCallback(C);
+#else
+      for (const auto &C : PipelineStartEPCallbacks)
+        PB.registerPipelineStartEPCallback([C, OptLevel](ModulePassManager &MPM) {
+          C(MPM, OptLevel);
+        });
+#endif
       if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
         for (const auto &C : OptimizerLastEPCallbacks)
           PB.registerOptimizerLastEPCallback(C);
@@ -956,7 +1013,17 @@ LLVMRustOptimizeWithNewPassManager(
         MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
         break;
       case LLVMRustOptStage::PreLinkThinLTO:
+#if LLVM_VERSION_GE(12, 0)
+        MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel);
+        // The ThinLTOPreLink pipeline already includes ThinLTOBuffer passes. However, callback
+        // passes may still run afterwards. This means we need to run the buffer passes again.
+        // FIXME: In LLVM 13, the ThinLTOPreLink pipeline also runs OptimizerLastEPCallbacks
+        // before the RequiredLTOPreLinkPasses, in which case we can remove these hacks.
+        if (OptimizerLastEPCallbacks.empty())
+          NeedThinLTOBufferPasses = false;
+#else
         MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
+#endif
 #if LLVM_VERSION_GE(11, 0)
         for (const auto &C : OptimizerLastEPCallbacks)
           C(MPM, OptLevel);
@@ -970,21 +1037,34 @@ LLVMRustOptimizeWithNewPassManager(
 #endif
         break;
       case LLVMRustOptStage::PreLinkFatLTO:
+#if LLVM_VERSION_GE(12, 0)
+        MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel);
+        NeedThinLTOBufferPasses = false;
+#else
         MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
+#endif
         break;
       case LLVMRustOptStage::ThinLTO:
         // FIXME: Does it make sense to pass the ModuleSummaryIndex?
         // It only seems to be needed for C++ specific optimizations.
+#if LLVM_VERSION_GE(12, 0)
+        MPM = PB.buildThinLTODefaultPipeline(OptLevel, nullptr);
+#else
         MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
+#endif
         break;
       case LLVMRustOptStage::FatLTO:
+#if LLVM_VERSION_GE(12, 0)
+        MPM = PB.buildLTODefaultPipeline(OptLevel, nullptr);
+#else
         MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
+#endif
         break;
       }
     }
   }
 
-  if (UseThinLTOBuffers) {
+  if (NeedThinLTOBufferPasses) {
     MPM.addPass(CanonicalizeAliasesPass());
     MPM.addPass(NameAnonGlobalPass());
   }
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 45835990cec..a8536595404 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -207,6 +207,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
     return Attribute::InaccessibleMemOnly;
   case SanitizeHWAddress:
     return Attribute::SanitizeHWAddress;
+  case WillReturn:
+    return Attribute::WillReturn;
   }
   report_fatal_error("bad AttributeKind");
 }
@@ -263,6 +265,17 @@ extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index,
   Call->addAttribute(Index, Attr);
 }
 
+extern "C" void LLVMRustAddStructRetCallSiteAttr(LLVMValueRef Instr, unsigned Index,
+                                                 LLVMTypeRef Ty) {
+  CallBase *Call = unwrap<CallBase>(Instr);
+#if LLVM_VERSION_GE(12, 0)
+  Attribute Attr = Attribute::getWithStructRetType(Call->getContext(), unwrap(Ty));
+#else
+  Attribute Attr = Attribute::get(Call->getContext(), Attribute::StructRet);
+#endif
+  Call->addAttribute(Index, Attr);
+}
+
 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
                                              LLVMRustAttribute RustAttr) {
   Function *A = unwrap<Function>(Fn);
@@ -304,6 +317,17 @@ extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index,
   F->addAttribute(Index, Attr);
 }
 
+extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index,
+                                         LLVMTypeRef Ty) {
+  Function *F = unwrap<Function>(Fn);
+#if LLVM_VERSION_GE(12, 0)
+  Attribute Attr = Attribute::getWithStructRetType(F->getContext(), unwrap(Ty));
+#else
+  Attribute Attr = Attribute::get(F->getContext(), Attribute::StructRet);
+#endif
+  F->addAttribute(Index, Attr);
+}
+
 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
                                                    unsigned Index,
                                                    const char *Name,
@@ -1007,12 +1031,19 @@ LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
 
 extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
-                                     LLVMMetadataRef Scope,
+                                     LLVMMetadataRef ScopeRef,
                                      LLVMMetadataRef InlinedAt) {
-  DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
+#if LLVM_VERSION_GE(12, 0)
+  MDNode *Scope = unwrapDIPtr<MDNode>(ScopeRef);
+  DILocation *Loc = DILocation::get(
+      Scope->getContext(), Line, Column, Scope,
+      unwrapDIPtr<MDNode>(InlinedAt));
+  return wrap(Loc);
+#else
+  DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(ScopeRef),
                                      unwrapDIPtr<MDNode>(InlinedAt));
-
   return wrap(debug_loc.getAsMDNode());
+#endif
 }
 
 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
@@ -1263,6 +1294,10 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
   case Type::BFloatTyID:
     return LLVMBFloatTypeKind;
 #endif
+#if LLVM_VERSION_GE(12, 0)
+  case Type::X86_AMXTyID:
+    return LLVMX86_AMXTypeKind;
+#endif
   }
   report_fatal_error("Unhandled TypeID.");
 }
@@ -1708,11 +1743,23 @@ LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned)
 }
 extern "C" LLVMValueRef
 LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
-   return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
+#if LLVM_VERSION_GE(12, 0)
+  Instruction *I = unwrap(B)->CreateFPMinReduce(unwrap(Src));
+  I->setHasNoNaNs(NoNaN);
+  return wrap(I);
+#else
+  return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN));
+#endif
 }
 extern "C" LLVMValueRef
 LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) {
+#if LLVM_VERSION_GE(12, 0)
+  Instruction *I = unwrap(B)->CreateFPMaxReduce(unwrap(Src));
+  I->setHasNoNaNs(NoNaN);
+  return wrap(I);
+#else
   return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN));
+#endif
 }
 
 extern "C" LLVMValueRef
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index f0b52c69881..4d8615a215f 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -146,6 +146,22 @@ impl<'tcx> MirSource<'tcx> {
     }
 }
 
+#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
+pub struct GeneratorInfo<'tcx> {
+    /// The yield type of the function, if it is a generator.
+    pub yield_ty: Option<Ty<'tcx>>,
+
+    /// Generator drop glue.
+    pub generator_drop: Option<Body<'tcx>>,
+
+    /// The layout of a generator. Produced by the state transformation.
+    pub generator_layout: Option<GeneratorLayout<'tcx>>,
+
+    /// If this is a generator then record the type of source expression that caused this generator
+    /// to be created.
+    pub generator_kind: GeneratorKind,
+}
+
 /// The lowered representation of a single function.
 #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
 pub struct Body<'tcx> {
@@ -166,18 +182,7 @@ pub struct Body<'tcx> {
     /// and used for debuginfo. Indexed by a `SourceScope`.
     pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
 
-    /// The yield type of the function, if it is a generator.
-    pub yield_ty: Option<Ty<'tcx>>,
-
-    /// Generator drop glue.
-    pub generator_drop: Option<Box<Body<'tcx>>>,
-
-    /// The layout of a generator. Produced by the state transformation.
-    pub generator_layout: Option<GeneratorLayout<'tcx>>,
-
-    /// If this is a generator then record the type of source expression that caused this generator
-    /// to be created.
-    pub generator_kind: Option<GeneratorKind>,
+    pub generator: Option<Box<GeneratorInfo<'tcx>>>,
 
     /// Declarations of locals.
     ///
@@ -259,10 +264,14 @@ impl<'tcx> Body<'tcx> {
             source,
             basic_blocks,
             source_scopes,
-            yield_ty: None,
-            generator_drop: None,
-            generator_layout: None,
-            generator_kind,
+            generator: generator_kind.map(|generator_kind| {
+                Box::new(GeneratorInfo {
+                    yield_ty: None,
+                    generator_drop: None,
+                    generator_layout: None,
+                    generator_kind,
+                })
+            }),
             local_decls,
             user_type_annotations,
             arg_count,
@@ -289,16 +298,13 @@ impl<'tcx> Body<'tcx> {
             source: MirSource::item(DefId::local(CRATE_DEF_INDEX)),
             basic_blocks,
             source_scopes: IndexVec::new(),
-            yield_ty: None,
-            generator_drop: None,
-            generator_layout: None,
+            generator: None,
             local_decls: IndexVec::new(),
             user_type_annotations: IndexVec::new(),
             arg_count: 0,
             spread_arg: None,
             span: DUMMY_SP,
             required_consts: Vec::new(),
-            generator_kind: None,
             var_debug_info: Vec::new(),
             is_polymorphic: false,
             predecessor_cache: PredecessorCache::new(),
@@ -480,6 +486,26 @@ impl<'tcx> Body<'tcx> {
     pub fn dominators(&self) -> Dominators<BasicBlock> {
         dominators(self)
     }
+
+    #[inline]
+    pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
+        self.generator.as_ref().and_then(|generator| generator.yield_ty)
+    }
+
+    #[inline]
+    pub fn generator_layout(&self) -> Option<&GeneratorLayout<'tcx>> {
+        self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref())
+    }
+
+    #[inline]
+    pub fn generator_drop(&self) -> Option<&Body<'tcx>> {
+        self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref())
+    }
+
+    #[inline]
+    pub fn generator_kind(&self) -> Option<GeneratorKind> {
+        self.generator.as_ref().map(|generator| generator.generator_kind)
+    }
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index bb8c5f175b8..3e92844c4f9 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -241,11 +241,13 @@ macro_rules! make_mir_visitor {
                 body: &$($mutability)? Body<'tcx>,
             ) {
                 let span = body.span;
-                if let Some(yield_ty) = &$($mutability)? body.yield_ty {
-                    self.visit_ty(
-                        yield_ty,
-                        TyContext::YieldTy(SourceInfo::outermost(span))
-                    );
+                if let Some(gen) = &$($mutability)? body.generator {
+                    if let Some(yield_ty) = &$($mutability)? gen.yield_ty {
+                        self.visit_ty(
+                            yield_ty,
+                            TyContext::YieldTy(SourceInfo::outermost(span))
+                        );
+                    }
                 }
 
                 // for best performance, we want to use an iterator rather
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index bf315c81588..f19cc998449 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -12,7 +12,6 @@ use rustc_target::spec::abi;
 
 use std::borrow::Cow;
 use std::fmt;
-use std::ops::Deref;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable)]
 pub struct ExpectedFound<T> {
@@ -548,7 +547,6 @@ impl<T> Trait<T> for X {
             TargetFeatureCast(def_id) => {
                 let attrs = self.get_attrs(*def_id);
                 let target_spans = attrs
-                    .deref()
                     .iter()
                     .filter(|attr| attr.has_name(sym::target_feature))
                     .map(|attr| attr.span);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 154a5e54a53..2e077827873 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2998,7 +2998,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns layout of a generator. Layout might be unavailable if the
     /// generator is tainted by errors.
     pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {
-        self.optimized_mir(def_id).generator_layout.as_ref()
+        self.optimized_mir(def_id).generator_layout()
     }
 
     /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
index b0b58a8d003..24b9408ffb6 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
@@ -10,16 +10,18 @@ use rustc_middle::mir::{
     FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
     ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
 };
-use rustc_middle::ty::{self, suggest_constraining_type_param, Instance, Ty};
-use rustc_span::{source_map::DesugaringKind, symbol::sym, Span};
+use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TypeFoldable};
+use rustc_span::source_map::DesugaringKind;
+use rustc_span::symbol::sym;
+use rustc_span::Span;
 
 use crate::dataflow::drop_flag_effects;
 use crate::dataflow::indexes::{MoveOutIndex, MovePathIndex};
 use crate::util::borrowck_errors;
 
 use crate::borrow_check::{
-    borrow_set::BorrowData, prefixes::IsPrefixOf, InitializationRequiringAction, MirBorrowckCtxt,
-    PrefixSet, WriteKind,
+    borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
+    InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
 };
 
 use super::{
@@ -1267,6 +1269,29 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         if return_span != borrow_span {
             err.span_label(borrow_span, note);
+
+            let tcx = self.infcx.tcx;
+            let ty_params = ty::List::empty();
+
+            let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
+            let return_ty = tcx.erase_regions(return_ty);
+
+            // to avoid panics
+            if !return_ty.has_infer_types() {
+                if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) {
+                    if tcx.type_implements_trait((iter_trait, return_ty, ty_params, self.param_env))
+                    {
+                        if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(return_span) {
+                            err.span_suggestion_hidden(
+                                return_span,
+                                "use `.collect()` to allocate the iterator",
+                                format!("{}{}", snippet, ".collect::<Vec<_>>()"),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+                    }
+                }
+            }
         }
 
         Some(err)
diff --git a/compiler/rustc_mir/src/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs
index 8c05e6fd5d0..e423e449746 100644
--- a/compiler/rustc_mir/src/borrow_check/invalidation.rs
+++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs
@@ -165,7 +165,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 self.consume_operand(location, value);
 
                 // Invalidate all borrows of local places
-                let borrow_set = self.borrow_set.clone();
+                let borrow_set = self.borrow_set;
                 let resume = self.location_table.start_index(resume.start_location());
                 for (i, data) in borrow_set.iter_enumerated() {
                     if borrow_of_local_data(data.borrowed_place) {
@@ -177,7 +177,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
             }
             TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
                 // Invalidate all borrows of local places
-                let borrow_set = self.borrow_set.clone();
+                let borrow_set = self.borrow_set;
                 let start = self.location_table.start_index(location);
                 for (i, data) in borrow_set.iter_enumerated() {
                     if borrow_of_local_data(data.borrowed_place) {
@@ -369,7 +369,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
         );
         let tcx = self.tcx;
         let body = self.body;
-        let borrow_set = self.borrow_set.clone();
+        let borrow_set = self.borrow_set;
         let indices = self.borrow_set.indices();
         each_borrow_involving_path(
             self,
@@ -377,7 +377,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
             body,
             location,
             (sd, place),
-            &borrow_set.clone(),
+            borrow_set,
             indices,
             |this, borrow_index, borrow| {
                 match (rw, borrow.kind) {
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
index 157959b1159..77d91366224 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
@@ -103,11 +103,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
         }
 
-        assert!(
-            body.yield_ty.is_some() && universal_regions.yield_ty.is_some()
-                || body.yield_ty.is_none() && universal_regions.yield_ty.is_none()
-        );
-        if let Some(mir_yield_ty) = body.yield_ty {
+        assert!(body.yield_ty().is_some() == universal_regions.yield_ty.is_some());
+        if let Some(mir_yield_ty) = body.yield_ty() {
             let ur_yield_ty = universal_regions.yield_ty.unwrap();
             let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
             self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);
diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
index aa946fdafa9..fa5b342c6e2 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
@@ -1651,7 +1651,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
             TerminatorKind::Yield { ref value, .. } => {
                 let value_ty = value.ty(body, tcx);
-                match body.yield_ty {
+                match body.yield_ty() {
                     None => span_mirbug!(self, term, "yield in non-generator"),
                     Some(ty) => {
                         if let Err(terr) = self.sub_types(
diff --git a/compiler/rustc_mir/src/shim.rs b/compiler/rustc_mir/src/shim.rs
index 6aaf27bdcb5..b246ec5c814 100644
--- a/compiler/rustc_mir/src/shim.rs
+++ b/compiler/rustc_mir/src/shim.rs
@@ -134,7 +134,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
 
     // Check if this is a generator, if so, return the drop glue for it
     if let Some(&ty::Generator(gen_def_id, substs, _)) = ty.map(|ty| ty.kind()) {
-        let body = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
+        let body = tcx.optimized_mir(gen_def_id).generator_drop().unwrap();
         return body.clone().subst(tcx, substs);
     }
 
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 2845f27d22b..baa27e9499f 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -222,7 +222,7 @@ impl Validator<'mir, 'tcx> {
 
         // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
         // no need to emit duplicate errors here.
-        if is_async_fn(self.ccx) || body.generator_kind.is_some() {
+        if is_async_fn(self.ccx) || body.generator.is_some() {
             tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
             return;
         }
diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs
index 3b27b544310..2a0e5e2c9c5 100644
--- a/compiler/rustc_mir/src/transform/const_prop.rs
+++ b/compiler/rustc_mir/src/transform/const_prop.rs
@@ -140,7 +140,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
             body.arg_count,
             Default::default(),
             body.span,
-            body.generator_kind,
+            body.generator_kind(),
         );
 
         // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
diff --git a/compiler/rustc_mir/src/transform/generator.rs b/compiler/rustc_mir/src/transform/generator.rs
index 9f996e84528..7a1f3d44a5e 100644
--- a/compiler/rustc_mir/src/transform/generator.rs
+++ b/compiler/rustc_mir/src/transform/generator.rs
@@ -1111,7 +1111,7 @@ fn create_generator_resume_function<'tcx>(
     cases.insert(0, (UNRESUMED, BasicBlock::new(0)));
 
     // Panic when resumed on the returned or poisoned state
-    let generator_kind = body.generator_kind.unwrap();
+    let generator_kind = body.generator_kind().unwrap();
 
     if can_unwind {
         cases.insert(
@@ -1236,14 +1236,14 @@ fn create_cases<'tcx>(
 
 impl<'tcx> MirPass<'tcx> for StateTransform {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let yield_ty = if let Some(yield_ty) = body.yield_ty {
+        let yield_ty = if let Some(yield_ty) = body.yield_ty() {
             yield_ty
         } else {
             // This only applies to generators
             return;
         };
 
-        assert!(body.generator_drop.is_none());
+        assert!(body.generator_drop().is_none());
 
         // The first argument is the generator type passed by value
         let gen_ty = body.local_decls.raw[1].ty;
@@ -1340,10 +1340,11 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         transform.visit_body(body);
 
         // Update our MIR struct to reflect the changes we've made
-        body.yield_ty = None;
         body.arg_count = 2; // self, resume arg
         body.spread_arg = None;
-        body.generator_layout = Some(layout);
+
+        body.generator.as_mut().unwrap().yield_ty = None;
+        body.generator.as_mut().unwrap().generator_layout = Some(layout);
 
         // Insert `drop(generator_struct)` which is used to drop upvars for generators in
         // the unresumed state.
@@ -1362,7 +1363,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         // Create a copy of our MIR and use it to create the drop shim for the generator
         let drop_shim = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean);
 
-        body.generator_drop = Some(box drop_shim);
+        body.generator.as_mut().unwrap().generator_drop = Some(drop_shim);
 
         // Create the Generator::resume function
         create_generator_resume_function(tcx, transform, body, can_return);
diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs
index 16410175bd2..0a899273efe 100644
--- a/compiler/rustc_mir/src/transform/inline.rs
+++ b/compiler/rustc_mir/src/transform/inline.rs
@@ -220,7 +220,7 @@ impl Inliner<'tcx> {
             // since their `optimized_mir` is used for layout computation, which can
             // create a cycle, even when no attempt is made to inline the function
             // in the other direction.
-            if caller_body.generator_kind.is_some() {
+            if caller_body.generator.is_some() {
                 return Err("local generator (query cycle avoidance)");
             }
 
diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs
index 1d4438d80c9..47d976281a4 100644
--- a/compiler/rustc_mir/src/transform/promote_consts.rs
+++ b/compiler/rustc_mir/src/transform/promote_consts.rs
@@ -1177,7 +1177,7 @@ pub fn promote_candidates<'tcx>(
             0,
             vec![],
             body.span,
-            body.generator_kind,
+            body.generator_kind(),
         );
 
         let promoter = Promoter {
diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs
index f46e94eea96..247a0beccaf 100644
--- a/compiler/rustc_mir/src/util/pretty.rs
+++ b/compiler/rustc_mir/src/util/pretty.rs
@@ -131,7 +131,7 @@ fn dump_matched_mir_node<'tcx, F>(
             Some(promoted) => write!(file, "::{:?}`", promoted)?,
         }
         writeln!(file, " {} {}", disambiguator, pass_name)?;
-        if let Some(ref layout) = body.generator_layout {
+        if let Some(ref layout) = body.generator_layout() {
             writeln!(file, "/* generator_layout = {:#?} */", layout)?;
         }
         writeln!(file)?;
@@ -956,7 +956,7 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn Write) -> io::Res
         write!(w, ": {} =", body.return_ty())?;
     }
 
-    if let Some(yield_ty) = body.yield_ty {
+    if let Some(yield_ty) = body.yield_ty() {
         writeln!(w)?;
         writeln!(w, "yields {}", yield_ty)?;
     }
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 126fb957a6a..4db7debee7e 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -51,7 +51,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
             PatKind::Constant { value } => Test {
                 span: match_pair.pattern.span,
-                kind: TestKind::Eq { value, ty: match_pair.pattern.ty.clone() },
+                kind: TestKind::Eq { value, ty: match_pair.pattern.ty },
             },
 
             PatKind::Range(range) => {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 5f6c8d26402..b928458df8e 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -188,7 +188,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
                 body,
                 span_with_body,
             );
-            mir.yield_ty = yield_ty;
+            if yield_ty.is_some() {
+                mir.generator.as_mut().unwrap().yield_ty = yield_ty;
+            }
             mir
         } else {
             // Get the revealed type of this const. This is *not* the adjusted
@@ -218,7 +220,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
             !(body.local_decls.has_free_regions()
                 || body.basic_blocks().has_free_regions()
                 || body.var_debug_info.has_free_regions()
-                || body.yield_ty.has_free_regions()),
+                || body.yield_ty().has_free_regions()),
             "Unexpected free regions in MIR: {:?}",
             body,
         );
@@ -686,10 +688,11 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
     let def_id = tcx.hir().local_def_id(owner_id);
     let span = tcx.hir().span(owner_id);
     let ty = tcx.ty_error();
+    let generator_kind = tcx.hir().body(body_id).generator_kind;
     let num_params = match hir.body_owner_kind {
         hir::BodyOwnerKind::Fn => tcx.hir().fn_decl_by_hir_id(owner_id).unwrap().inputs.len(),
         hir::BodyOwnerKind::Closure => {
-            if tcx.hir().body(body_id).generator_kind().is_some() {
+            if generator_kind.is_some() {
                 // Generators have an implicit `self` parameter *and* a possibly
                 // implicit resume parameter.
                 2
@@ -701,8 +704,16 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
         hir::BodyOwnerKind::Const => 0,
         hir::BodyOwnerKind::Static(_) => 0,
     };
-    let mut builder =
-        Builder::new(hir, def_id.to_def_id(), span, num_params, Safety::Safe, ty, span, None);
+    let mut builder = Builder::new(
+        hir,
+        def_id.to_def_id(),
+        span,
+        num_params,
+        Safety::Safe,
+        ty,
+        span,
+        generator_kind,
+    );
     let source_info = builder.source_info(span);
     // Some MIR passes will expect the number of parameters to match the
     // function declaration.
@@ -711,9 +722,7 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
     }
     builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
     let mut body = builder.finish();
-    if tcx.hir().body(body_id).generator_kind.is_some() {
-        body.yield_ty = Some(ty);
-    }
+    body.generator.as_mut().map(|gen| gen.yield_ty = Some(ty));
     body
 }
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index afd1642bbd5..39245ea77e5 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -567,16 +567,23 @@ impl CheckAttrVisitor<'tcx> {
                         .iter()
                         .any(|m| i_meta.has_name(*m))
                         {
-                            self.tcx
-                                .sess
-                                .struct_span_err(
-                                    meta.span(),
-                                    &format!(
+                            self.tcx.struct_span_lint_hir(
+                                UNUSED_ATTRIBUTES,
+                                hir_id,
+                                i_meta.span,
+                                |lint| {
+                                    lint.build(&format!(
                                         "unknown `doc` attribute `{}`",
-                                        i_meta.name_or_empty(),
-                                    ),
-                                )
-                                .emit();
+                                        i_meta.name_or_empty()
+                                    ))
+                                    .warn(
+                                        "this was previously accepted by the compiler but is \
+                                        being phased out; it will become a hard error in \
+                                        a future release!",
+                                    )
+                                    .emit();
+                                },
+                            );
                             return false;
                         }
                     }
diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs
index 7c62a234dba..02b20e45d00 100644
--- a/compiler/rustc_passes/src/lib_features.rs
+++ b/compiler/rustc_passes/src/lib_features.rs
@@ -109,7 +109,7 @@ impl LibFeatureCollector<'tcx> {
     }
 
     fn span_feature_error(&self, span: Span, msg: &str) {
-        struct_span_err!(self.tcx.sess, span, E0711, "{}", &msg,).emit();
+        struct_span_err!(self.tcx.sess, span, E0711, "{}", &msg).emit();
     }
 }
 
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index f538427efd9..c4c10343743 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -70,6 +70,17 @@ impl InheritConstStability {
     }
 }
 
+enum InheritStability {
+    Yes,
+    No,
+}
+
+impl InheritStability {
+    fn yes(&self) -> bool {
+        matches!(self, InheritStability::Yes)
+    }
+}
+
 // A private tree-walker for producing an Index.
 struct Annotator<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -91,6 +102,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         kind: AnnotationKind,
         inherit_deprecation: InheritDeprecation,
         inherit_const_stability: InheritConstStability,
+        inherit_from_parent: InheritStability,
         visit_children: F,
     ) where
         F: FnOnce(&mut Self),
@@ -131,12 +143,13 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         }
 
         if self.tcx.features().staged_api {
-            if let Some(..) = attrs.iter().find(|a| self.tcx.sess.check_name(a, sym::deprecated)) {
-                self.tcx.sess.span_err(
-                    item_sp,
-                    "`#[deprecated]` cannot be used in staged API; \
-                                                use `#[rustc_deprecated]` instead",
-                );
+            if let Some(a) = attrs.iter().find(|a| self.tcx.sess.check_name(a, sym::deprecated)) {
+                self.tcx
+                    .sess
+                    .struct_span_err(a.span, "`#[deprecated]` cannot be used in staged API")
+                    .span_label(a.span, "use `#[rustc_deprecated]` instead")
+                    .span_label(item_sp, "")
+                    .emit();
             }
         } else {
             self.recurse_with_stability_attrs(
@@ -150,7 +163,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
 
         let (stab, const_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp);
 
-        let const_stab = const_stab.map(|const_stab| {
+        let const_stab = const_stab.map(|(const_stab, _)| {
             let const_stab = self.tcx.intern_const_stability(const_stab);
             self.index.const_stab_map.insert(hir_id, const_stab);
             const_stab
@@ -180,12 +193,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
         }
 
-        let stab = stab.map(|stab| {
+        let stab = stab.map(|(stab, span)| {
             // Error if prohibited, or can't inherit anything from a container.
             if kind == AnnotationKind::Prohibited
                 || (kind == AnnotationKind::Container && stab.level.is_stable() && is_deprecated)
             {
-                self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
+                self.tcx.sess.struct_span_err(span,"this stability annotation is useless")
+                    .span_label(span, "useless stability annotation")
+                    .span_label(item_sp, "the stability attribute annotates this item")
+                    .emit();
             }
 
             debug!("annotate: found {:?}", stab);
@@ -202,16 +218,19 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 {
                     match stab_v.parse::<u64>() {
                         Err(_) => {
-                            self.tcx.sess.span_err(item_sp, "Invalid stability version found");
+                            self.tcx.sess.struct_span_err(span, "invalid stability version found")
+                                .span_label(span, "invalid stability version")
+                                .span_label(item_sp, "the stability attribute annotates this item")
+                                .emit();
                             break;
                         }
                         Ok(stab_vp) => match dep_v.parse::<u64>() {
                             Ok(dep_vp) => match dep_vp.cmp(&stab_vp) {
                                 Ordering::Less => {
-                                    self.tcx.sess.span_err(
-                                        item_sp,
-                                        "An API can't be stabilized after it is deprecated",
-                                    );
+                                    self.tcx.sess.struct_span_err(span, "an API can't be stabilized after it is deprecated")
+                                        .span_label(span, "invalid version")
+                                        .span_label(item_sp, "the stability attribute annotates this item")
+                                        .emit();
                                     break;
                                 }
                                 Ordering::Equal => continue,
@@ -219,9 +238,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                             },
                             Err(_) => {
                                 if dep_v != "TBD" {
-                                    self.tcx
-                                        .sess
-                                        .span_err(item_sp, "Invalid deprecation version found");
+                                    self.tcx.sess.struct_span_err(span, "invalid deprecation version found")
+                                        .span_label(span, "invalid deprecation version")
+                                        .span_label(item_sp, "the stability attribute annotates this item")
+                                        .emit();
                                 }
                                 break;
                             }
@@ -237,7 +257,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         if stab.is_none() {
             debug!("annotate: stab not found, parent = {:?}", self.parent_stab);
             if let Some(stab) = self.parent_stab {
-                if inherit_deprecation.yes() && stab.level.is_unstable() {
+                if inherit_deprecation.yes() && stab.level.is_unstable()
+                    || inherit_from_parent.yes()
+                {
                     self.index.stab_map.insert(hir_id, stab);
                 }
             }
@@ -368,6 +390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
                         InheritConstStability::No,
+                        InheritStability::Yes,
                         |_| {},
                     )
                 }
@@ -382,6 +405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             kind,
             InheritDeprecation::Yes,
             const_stab_inherit,
+            InheritStability::No,
             |v| intravisit::walk_item(v, i),
         );
         self.in_trait_impl = orig_in_trait_impl;
@@ -395,6 +419,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::No,
             |v| {
                 intravisit::walk_trait_item(v, ti);
             },
@@ -411,6 +436,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             kind,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::No,
             |v| {
                 intravisit::walk_impl_item(v, ii);
             },
@@ -425,6 +451,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::Yes,
             |v| {
                 if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
                     v.annotate(
@@ -434,6 +461,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
                         AnnotationKind::Required,
                         InheritDeprecation::Yes,
                         InheritConstStability::No,
+                        InheritStability::No,
                         |_| {},
                     );
                 }
@@ -451,6 +479,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::Yes,
             |v| {
                 intravisit::walk_struct_field(v, s);
             },
@@ -465,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::No,
             |v| {
                 intravisit::walk_foreign_item(v, i);
             },
@@ -479,6 +509,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::No,
             |_| {},
         );
     }
@@ -499,6 +530,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             kind,
             InheritDeprecation::No,
             InheritConstStability::No,
+            InheritStability::No,
             |v| {
                 intravisit::walk_generic_param(v, p);
             },
@@ -669,6 +701,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
             AnnotationKind::Required,
             InheritDeprecation::Yes,
             InheritConstStability::No,
+            InheritStability::No,
             |v| intravisit::walk_crate(v, krate),
         );
     }
@@ -729,18 +762,13 @@ impl Visitor<'tcx> for Checker<'tcx> {
                     // error if all involved types and traits are stable, because
                     // it will have no effect.
                     // See: https://github.com/rust-lang/rust/issues/55436
-                    if let (Some(Stability { level: attr::Unstable { .. }, .. }), _) =
+                    if let (Some((Stability { level: attr::Unstable { .. }, .. }, span)), _) =
                         attr::find_stability(&self.tcx.sess, &item.attrs, item.span)
                     {
                         let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
                         c.visit_ty(self_ty);
                         c.visit_trait_ref(t);
                         if c.fully_stable {
-                            let span = item
-                                .attrs
-                                .iter()
-                                .find(|a| a.has_name(sym::unstable))
-                                .map_or(item.span, |a| a.span);
                             self.tcx.struct_span_lint_hir(
                                 INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
                                 item.hir_id(),
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index bd0296751a5..61f4c00a4ca 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -156,6 +156,21 @@ impl<'a> NameResolution<'a> {
     }
 }
 
+// Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
+// are permitted for backward-compatibility under a deprecation lint.
+fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool {
+    match (&import.kind, &binding.kind) {
+        (
+            ImportKind::Single { .. },
+            NameBindingKind::Import {
+                import: Import { kind: ImportKind::ExternCrate { .. }, .. },
+                ..
+            },
+        ) => import.vis.get() == ty::Visibility::Public,
+        _ => false,
+    }
+}
+
 impl<'a> Resolver<'a> {
     crate fn resolve_ident_in_module_unadjusted(
         &mut self,
@@ -263,10 +278,7 @@ impl<'a> Resolver<'a> {
                     return Err((Determined, Weak::No));
                 }
             }
-            // `extern crate` are always usable for backwards compatibility, see issue #37020,
-            // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
-            let usable = this.is_accessible_from(binding.vis, parent_scope.module)
-                || binding.is_extern_crate();
+            let usable = this.is_accessible_from(binding.vis, parent_scope.module);
             if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
         };
 
@@ -309,10 +321,7 @@ impl<'a> Resolver<'a> {
                             }
                         }
 
-                        if !(self.is_accessible_from(binding.vis, parent_scope.module) ||
-                       // Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
-                       (self.last_import_segment && binding.is_extern_crate()))
-                        {
+                        if !self.is_accessible_from(binding.vis, parent_scope.module) {
                             self.privacy_errors.push(PrivacyError {
                                 ident,
                                 binding,
@@ -455,9 +464,8 @@ impl<'a> Resolver<'a> {
         binding: &'a NameBinding<'a>,
         import: &'a Import<'a>,
     ) -> &'a NameBinding<'a> {
-        let vis = if binding.vis.is_at_least(import.vis.get(), self) ||
-                     // cf. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
-                     !import.is_glob() && binding.is_extern_crate()
+        let vis = if binding.vis.is_at_least(import.vis.get(), self)
+            || pub_use_of_private_extern_crate_hack(import, binding)
         {
             import.vis.get()
         } else {
@@ -1188,7 +1196,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         // All namespaces must be re-exported with extra visibility for an error to occur.
         if !any_successful_reexport {
             let (ns, binding) = reexport_error.unwrap();
-            if ns == TypeNS && binding.is_extern_crate() {
+            if pub_use_of_private_extern_crate_hack(import, binding) {
                 let msg = format!(
                     "extern crate `{}` is private, and cannot be \
                                    re-exported (error E0365), consider declaring with \
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index d60f929cb8f..87bf79d722b 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1645,6 +1645,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         );
         err.span_label(lifetime_ref.span, "undeclared lifetime");
         let mut suggests_in_band = false;
+        let mut suggest_note = true;
         for missing in &self.missing_named_lifetime_spots {
             match missing {
                 MissingLifetimeSpot::Generics(generics) => {
@@ -1664,12 +1665,24 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                         suggests_in_band = true;
                         (generics.span, format!("<{}>", lifetime_ref))
                     };
-                    err.span_suggestion(
-                        span,
-                        &format!("consider introducing lifetime `{}` here", lifetime_ref),
-                        sugg,
-                        Applicability::MaybeIncorrect,
-                    );
+                    if !span.from_expansion() {
+                        err.span_suggestion(
+                            span,
+                            &format!("consider introducing lifetime `{}` here", lifetime_ref),
+                            sugg,
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else if suggest_note {
+                        suggest_note = false; // Avoid displaying the same help multiple times.
+                        err.span_label(
+                            span,
+                            &format!(
+                                "lifetime `{}` is missing in item created through this procedural \
+                                 macro",
+                                lifetime_ref,
+                            ),
+                        );
+                    }
                 }
                 MissingLifetimeSpot::HigherRanked { span, span_type } => {
                     err.span_suggestion(
@@ -1684,7 +1697,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                     );
                     err.note(
                         "for more information on higher-ranked polymorphism, visit \
-                            https://doc.rust-lang.org/nomicon/hrtb.html",
+                         https://doc.rust-lang.org/nomicon/hrtb.html",
                     );
                 }
                 _ => {}
@@ -1696,7 +1709,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         {
             err.help(
                 "if you want to experiment with in-band lifetime bindings, \
-                    add `#![feature(in_band_lifetimes)]` to the crate attributes",
+                 add `#![feature(in_band_lifetimes)]` to the crate attributes",
             );
         }
         err.emit();
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index a3900ebcea9..77a9a2b227c 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2066,6 +2066,8 @@ fn parse_pretty(
             ("expanded", _) => Source(PpSourceMode::Expanded),
             ("expanded,identified", _) => Source(PpSourceMode::ExpandedIdentified),
             ("expanded,hygiene", _) => Source(PpSourceMode::ExpandedHygiene),
+            ("ast-tree", true) => AstTree(PpAstTreeMode::Normal),
+            ("ast-tree,expanded", true) => AstTree(PpAstTreeMode::Expanded),
             ("hir", true) => Hir(PpHirMode::Normal),
             ("hir,identified", true) => Hir(PpHirMode::Identified),
             ("hir,typed", true) => Hir(PpHirMode::Typed),
@@ -2080,8 +2082,8 @@ fn parse_pretty(
                             "argument to `unpretty` must be one of `normal`, \
                                         `expanded`, `identified`, `expanded,identified`, \
                                         `expanded,hygiene`, `everybody_loops`, \
-                                        `hir`, `hir,identified`, `hir,typed`, `hir-tree`, \
-                                        `mir` or `mir-cfg`; got {}",
+                                        `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
+                                        `hir,typed`, `hir-tree`, `mir` or `mir-cfg`; got {}",
                             name
                         ),
                     );
@@ -2234,6 +2236,14 @@ pub enum PpSourceMode {
 }
 
 #[derive(Copy, Clone, PartialEq, Debug)]
+pub enum PpAstTreeMode {
+    /// `-Zunpretty=ast`
+    Normal,
+    /// `-Zunpretty=ast,expanded`
+    Expanded,
+}
+
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpHirMode {
     /// `-Zunpretty=hir`
     Normal,
@@ -2248,6 +2258,7 @@ pub enum PpMode {
     /// Options that print the source code, i.e.
     /// `--pretty` and `-Zunpretty=everybody_loops`
     Source(PpSourceMode),
+    AstTree(PpAstTreeMode),
     /// Options that print the HIR, i.e. `-Zunpretty=hir`
     Hir(PpHirMode),
     /// `-Zunpretty=hir-tree`
@@ -2263,9 +2274,10 @@ impl PpMode {
         use PpMode::*;
         use PpSourceMode::*;
         match *self {
-            Source(Normal | Identified) => false,
+            Source(Normal | Identified) | AstTree(PpAstTreeMode::Normal) => false,
 
             Source(Expanded | EveryBodyLoops | ExpandedIdentified | ExpandedHygiene)
+            | AstTree(PpAstTreeMode::Expanded)
             | Hir(_)
             | HirTree
             | Mir
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index e2b6b1dc243..6e7d39547a1 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1158,6 +1158,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         `expanded`, `expanded,identified`,
         `expanded,hygiene` (with internal representations),
         `everybody_loops` (all function bodies replaced with `loop {}`),
+        `ast-tree` (raw AST before expansion),
+        `ast-tree,expanded` (raw AST after expansion),
         `hir` (the HIR), `hir,identified`,
         `hir,typed` (HIR with types for each node),
         `hir-tree` (dump the raw HIR),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 27bb45bcc85..cd47b714db5 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -129,6 +129,7 @@ symbols! {
         BTreeMap,
         BTreeSet,
         BinaryHeap,
+        Borrow,
         C,
         CString,
         Center,
@@ -141,6 +142,7 @@ symbols! {
         Decodable,
         Decoder,
         Default,
+        Deref,
         Encodable,
         Encoder,
         Eq,
@@ -789,6 +791,9 @@ symbols! {
         none_error,
         nontemporal_store,
         nontrapping_dash_fptoint: "nontrapping-fptoint",
+        noop_method_borrow,
+        noop_method_clone,
+        noop_method_deref,
         noreturn,
         nostack,
         not,
@@ -1021,6 +1026,7 @@ symbols! {
         rustc_then_this_would_need,
         rustc_unsafe_specialization_marker,
         rustc_variance,
+        rustdoc,
         rustfmt,
         rvalue_static_promotion,
         sanitize,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 9c49922c286..0deb1186b0f 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -603,6 +603,13 @@ impl<'a, Ty> FnAbi<'a, Ty> {
         Ty: TyAndLayoutMethods<'a, C> + Copy,
         C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
     {
+        if abi == spec::abi::Abi::X86Interrupt {
+            if let Some(arg) = self.args.first_mut() {
+                arg.make_indirect_byval();
+            }
+            return Ok(());
+        }
+
         match &cx.target_spec().arch[..] {
             "x86" => {
                 let flavor = if abi == spec::abi::Abi::Fastcall {
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
index 751022c124b..9db880b0e53 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
@@ -14,7 +14,7 @@ pub fn target() -> Target {
     Target {
         llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64".to_string(),
+        data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
         arch: "powerpc64".to_string(),
         options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
     }
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
index 546dfbab6c7..8767f86b00b 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
     Target {
         llvm_target: "powerpc64-unknown-linux-musl".to_string(),
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64".to_string(),
+        data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
         arch: "powerpc64".to_string(),
         options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
     }
diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
index bb55872109c..2f28a856247 100644
--- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
     Target {
         llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64".to_string(),
+        data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
         arch: "powerpc64".to_string(),
         options: TargetOptions { endian: Endian::Big, ..base },
     }
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
index 07e0bf81bc7..4cbd9976508 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
@@ -9,7 +9,7 @@ pub fn target() -> Target {
     Target {
         llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
         pointer_width: 64,
-        data_layout: "e-m:e-i64:64-n32:64".to_string(),
+        data_layout: "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
         arch: "powerpc64".to_string(),
         options: TargetOptions { mcount: "_mcount".to_string(), ..base },
     }
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
index 41c78a5f276..efdc9ad7517 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
@@ -9,7 +9,7 @@ pub fn target() -> Target {
     Target {
         llvm_target: "powerpc64le-unknown-linux-musl".to_string(),
         pointer_width: 64,
-        data_layout: "e-m:e-i64:64-n32:64".to_string(),
+        data_layout: "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
         arch: "powerpc64".to_string(),
         options: TargetOptions { mcount: "_mcount".to_string(), ..base },
     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index bfb5ebcea58..a3faf4cb7d4 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -819,7 +819,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 sig.decl
                     .inputs
                     .iter()
-                    .map(|arg| match arg.clone().kind {
+                    .map(|arg| match arg.kind {
                         hir::TyKind::Tup(ref tys) => ArgKind::Tuple(
                             Some(arg.span),
                             vec![("_".to_owned(), "_".to_owned()); tys.len()],
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index d98f18182c8..b7275bac190 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -165,7 +165,7 @@ crate fn evaluate_goal<'tcx>(
                         // let's just ignore that
                         let sol = Canonical {
                             max_universe: ty::UniverseIndex::from_usize(0),
-                            variables: obligation.variables.clone(),
+                            variables: obligation.variables,
                             value: QueryResponse {
                                 var_values: CanonicalVarValues { var_values: IndexVec::new() }
                                     .make_identity(tcx),
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index ca1e79fac73..6ef63bcbbbf 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -465,7 +465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expected_arg_tys = self.expected_inputs_for_expected_output(
             call_expr.span,
             expected,
-            fn_sig.output().clone(),
+            fn_sig.output(),
             fn_sig.inputs(),
         );
 
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 2faf128c491..48740e533da 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -711,7 +711,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         });
 
         let ret_ty = ret_coercion.borrow().expected_ty();
-        let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
+        let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
         ret_coercion.borrow_mut().coerce(
             self,
             &self.cause(return_expr.span, ObligationCauseCode::ReturnValue(return_expr.hir_id)),
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index 4e48db7f493..e636e490e1b 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -1801,11 +1801,11 @@ fn test_occupied_entry_key() {
     let key = "hello there";
     let value = "value goes here";
     assert!(a.is_empty());
-    a.insert(key.clone(), value.clone());
+    a.insert(key, value);
     assert_eq!(a.len(), 1);
     assert_eq!(a[key], value);
 
-    match a.entry(key.clone()) {
+    match a.entry(key) {
         Vacant(_) => panic!(),
         Occupied(e) => assert_eq!(key, *e.key()),
     }
@@ -1821,11 +1821,11 @@ fn test_vacant_entry_key() {
     let value = "value goes here";
 
     assert!(a.is_empty());
-    match a.entry(key.clone()) {
+    match a.entry(key) {
         Occupied(_) => panic!(),
         Vacant(e) => {
             assert_eq!(key, *e.key());
-            e.insert(value.clone());
+            e.insert(value);
         }
     }
     assert_eq!(a.len(), 1);
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 01a3f9f9b59..0028e290fac 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1877,7 +1877,15 @@ impl<T, A: Allocator> Vec<T, A> {
     #[unstable(feature = "vec_spare_capacity", issue = "75017")]
     #[inline]
     pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
-        self.split_at_spare_mut().1
+        // Note:
+        // This method is not implemented in terms of `split_at_spare_mut`,
+        // to prevent invalidation of pointers to the buffer.
+        unsafe {
+            slice::from_raw_parts_mut(
+                self.as_mut_ptr().add(self.len) as *mut MaybeUninit<T>,
+                self.buf.capacity() - self.len,
+            )
+        }
     }
 
     /// Returns vector content as a slice of `T`, along with the remaining spare
@@ -1934,20 +1942,16 @@ impl<T, A: Allocator> Vec<T, A> {
     #[unstable(feature = "vec_split_at_spare", issue = "81944")]
     #[inline]
     pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]) {
-        let ptr = self.as_mut_ptr();
-
-        // SAFETY:
-        // - `ptr` is guaranteed to be in bounds for `capacity` elements
-        // - `len` is guaranteed to less or equal to `capacity`
-        // - `MaybeUninit<T>` has the same layout as `T`
-        let spare_ptr = unsafe { ptr.cast::<MaybeUninit<T>>().add(self.len) };
+        let Range { start: ptr, end: spare_ptr } = self.as_mut_ptr_range();
+        let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
+        let spare_len = self.buf.capacity() - self.len;
 
         // SAFETY:
         // - `ptr` is guaranteed to be valid for `len` elements
-        // - `spare_ptr` is offseted from `ptr` by `len`, so it doesn't overlap `initialized` slice
+        // - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
         unsafe {
             let initialized = slice::from_raw_parts_mut(ptr, self.len);
-            let spare = slice::from_raw_parts_mut(spare_ptr, self.buf.capacity() - self.len);
+            let spare = slice::from_raw_parts_mut(spare_ptr, spare_len);
 
             (initialized, spare)
         }
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 9c92d96dc70..799499b9b77 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -20,6 +20,7 @@
 #![feature(vecdeque_binary_search)]
 #![feature(slice_group_by)]
 #![feature(vec_extend_from_within)]
+#![feature(vec_spare_capacity)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 2969da58d42..fab45028585 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1691,6 +1691,10 @@ fn test_stable_pointers() {
     next_then_drop(v.splice(5..6, vec![1; 10].into_iter().filter(|_| true))); // lower bound not exact
     assert_eq!(*v0, 13);
 
+    // spare_capacity_mut
+    v.spare_capacity_mut();
+    assert_eq!(*v0, 13);
+
     // Smoke test that would fire even outside Miri if an actual relocation happened.
     *v0 -= 13;
     assert_eq!(v[0], 0);
diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs
index c9040cd0a16..f28be20aaa1 100644
--- a/library/core/src/borrow.rs
+++ b/library/core/src/borrow.rs
@@ -153,6 +153,7 @@
 /// [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
 /// [`String`]: ../../std/string/struct.String.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_diagnostic_item = "Borrow"]
 pub trait Borrow<Borrowed: ?Sized> {
     /// Immutably borrows from an owned value.
     ///
@@ -205,6 +206,7 @@ pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Borrow<T> for T {
+    #[rustc_diagnostic_item = "noop_method_borrow"]
     fn borrow(&self) -> &T {
         self
     }
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index a953a3a4182..51a2dc03de3 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -104,12 +104,14 @@
 /// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "clone"]
+#[rustc_diagnostic_item = "Clone"]
 pub trait Clone: Sized {
     /// Returns a copy of the value.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![allow(noop_method_call)]
     /// let hello = "Hello"; // &str implements Clone
     ///
     /// assert_eq!("Hello", hello.clone());
@@ -221,6 +223,7 @@ mod impls {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl<T: ?Sized> Clone for &T {
         #[inline]
+        #[rustc_diagnostic_item = "noop_method_clone"]
         fn clone(&self) -> Self {
             *self
         }
diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs
index 9d0f4e3618f..817fc2a51e9 100644
--- a/library/core/src/iter/adapters/zip.rs
+++ b/library/core/src/iter/adapters/zip.rs
@@ -200,6 +200,7 @@ where
         } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a.size() {
             let i = self.index;
             self.index += 1;
+            self.len += 1;
             // match the base implementation's potential side effects
             // SAFETY: we just checked that `i` < `self.a.len()`
             unsafe {
@@ -258,7 +259,7 @@ where
             if sz_a != sz_b {
                 let sz_a = self.a.size();
                 if A::MAY_HAVE_SIDE_EFFECT && sz_a > self.len {
-                    for _ in 0..sz_a - cmp::max(self.len, self.index) {
+                    for _ in 0..sz_a - self.len {
                         self.a.next_back();
                     }
                 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index f28c4673cc0..e179ce01c41 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -93,6 +93,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
     message = "`{Self}` is not an iterator"
 )]
 #[doc(spotlight)]
+#[rustc_diagnostic_item = "Iterator"]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub trait Iterator {
     /// The type of the elements being iterated over.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index c50d9507a17..04926123729 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -297,7 +297,8 @@ pub mod primitive;
     unused_imports,
     unsafe_op_in_unsafe_fn
 )]
-#[allow(non_autolinks)]
+#[cfg_attr(bootstrap, allow(non_autolinks))]
+#[cfg_attr(not(bootstrap), allow(rustdoc::non_autolinks))]
 // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is
 // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet.
 #[allow(clashing_extern_declarations)]
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 2419771eae2..10e3ce67448 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -60,6 +60,7 @@
 #[doc(alias = "*")]
 #[doc(alias = "&*")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_diagnostic_item = "Deref"]
 pub trait Deref {
     /// The resulting type after dereferencing.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -78,6 +79,7 @@ pub trait Deref {
 impl<T: ?Sized> Deref for &T {
     type Target = T;
 
+    #[rustc_diagnostic_item = "noop_method_deref"]
     fn deref(&self) -> &T {
         *self
     }
diff --git a/library/core/tests/iter/adapters/intersperse.rs b/library/core/tests/iter/adapters/intersperse.rs
index 9dbe232e4ee..b336c03b5ad 100644
--- a/library/core/tests/iter/adapters/intersperse.rs
+++ b/library/core/tests/iter/adapters/intersperse.rs
@@ -9,7 +9,7 @@ fn test_intersperse() {
     assert_eq!(v, vec![1]);
 
     let xs = ["a", "", "b", "c"];
-    let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
+    let v: Vec<&str> = xs.iter().map(|x| *x).intersperse(", ").collect();
     let text: String = v.concat();
     assert_eq!(text, "a, , b, c".to_string());
 
@@ -24,7 +24,7 @@ fn test_intersperse_size_hint() {
     assert_eq!(iter.size_hint(), (0, Some(0)));
 
     let xs = ["a", "", "b", "c"];
-    let mut iter = xs.iter().map(|x| x.clone()).intersperse(", ");
+    let mut iter = xs.iter().map(|x| *x).intersperse(", ");
     assert_eq!(iter.size_hint(), (7, Some(7)));
 
     assert_eq!(iter.next(), Some("a"));
diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs
index 1fce0951e36..a5977103929 100644
--- a/library/core/tests/iter/adapters/zip.rs
+++ b/library/core/tests/iter/adapters/zip.rs
@@ -245,3 +245,23 @@ fn test_double_ended_zip() {
     assert_eq!(it.next_back(), Some((3, 3)));
     assert_eq!(it.next(), None);
 }
+
+#[test]
+fn test_issue_82282() {
+    fn overflowed_zip(arr: &[i32]) -> impl Iterator<Item = (i32, &())> {
+        static UNIT_EMPTY_ARR: [(); 0] = [];
+
+        let mapped = arr.into_iter().map(|i| *i);
+        let mut zipped = mapped.zip(UNIT_EMPTY_ARR.iter());
+        zipped.next();
+        zipped
+    }
+
+    let arr = [1, 2, 3];
+    let zip = overflowed_zip(&arr).zip(overflowed_zip(&arr));
+
+    assert_eq!(zip.size_hint(), (0, Some(0)));
+    for _ in zip {
+        panic!();
+    }
+}
diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs
index 7d5c601df53..2de6db762b2 100644
--- a/library/profiler_builtins/build.rs
+++ b/library/profiler_builtins/build.rs
@@ -26,6 +26,7 @@ fn main() {
         "InstrProfilingPlatformWindows.c",
         "InstrProfilingUtil.c",
         "InstrProfilingValue.c",
+        "InstrProfilingVersionVar.c",
         "InstrProfilingWriter.c",
         // This file was renamed in LLVM 10.
         "InstrProfilingRuntime.cc",
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index 467968354e2..819be142227 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -774,11 +774,11 @@ fn test_occupied_entry_key() {
     let key = "hello there";
     let value = "value goes here";
     assert!(a.is_empty());
-    a.insert(key.clone(), value.clone());
+    a.insert(key, value);
     assert_eq!(a.len(), 1);
     assert_eq!(a[key], value);
 
-    match a.entry(key.clone()) {
+    match a.entry(key) {
         Vacant(_) => panic!(),
         Occupied(e) => assert_eq!(key, *e.key()),
     }
@@ -793,11 +793,11 @@ fn test_vacant_entry_key() {
     let value = "value goes here";
 
     assert!(a.is_empty());
-    match a.entry(key.clone()) {
+    match a.entry(key) {
         Occupied(_) => panic!(),
         Vacant(e) => {
             assert_eq!(key, *e.key());
-            e.insert(value.clone());
+            e.insert(value);
         }
     }
     assert_eq!(a.len(), 1);
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 152bd34ffba..02b0fc0c57d 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -1,6 +1,8 @@
 use crate::cmp;
 use crate::fmt;
-use crate::io::{self, BufRead, Initializer, IoSliceMut, Read, Seek, SeekFrom, DEFAULT_BUF_SIZE};
+use crate::io::{
+    self, BufRead, Initializer, IoSliceMut, Read, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
+};
 
 /// The `BufReader<R>` struct adds buffering to any reader.
 ///
@@ -434,3 +436,9 @@ impl<R: Seek> Seek for BufReader<R> {
         })
     }
 }
+
+impl<T> SizeHint for BufReader<T> {
+    fn lower_bound(&self) -> usize {
+        self.buffer().len()
+    }
+}
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 22914987405..17002e3b860 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2238,6 +2238,19 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
     }
 }
 
+impl<T, U> SizeHint for Chain<T, U> {
+    fn lower_bound(&self) -> usize {
+        SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
+    }
+
+    fn upper_bound(&self) -> Option<usize> {
+        match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
+            (Some(first), Some(second)) => Some(first + second),
+            _ => None,
+        }
+    }
+}
+
 /// Reader adaptor which limits the bytes read from an underlying reader.
 ///
 /// This struct is generally created by calling [`take`] on a reader.
@@ -2464,6 +2477,30 @@ impl<R: Read> Iterator for Bytes<R> {
             };
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        SizeHint::size_hint(&self.inner)
+    }
+}
+
+trait SizeHint {
+    fn lower_bound(&self) -> usize;
+
+    fn upper_bound(&self) -> Option<usize>;
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.lower_bound(), self.upper_bound())
+    }
+}
+
+impl<T> SizeHint for T {
+    default fn lower_bound(&self) -> usize {
+        0
+    }
+
+    default fn upper_bound(&self) -> Option<usize> {
+        None
+    }
 }
 
 /// An iterator over the contents of an instance of `BufRead` split on a
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index f176c2f088c..a85dd0d9827 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -1,7 +1,7 @@
 use super::{repeat, Cursor, SeekFrom};
 use crate::cmp::{self, min};
 use crate::io::{self, IoSlice, IoSliceMut};
-use crate::io::{BufRead, Read, Seek, Write};
+use crate::io::{BufRead, BufReader, Read, Seek, Write};
 use crate::ops::Deref;
 
 #[test]
@@ -199,6 +199,53 @@ fn chain_bufread() {
 }
 
 #[test]
+fn bufreader_size_hint() {
+    let testdata = b"ABCDEFGHIJKL";
+    let mut buf_reader = BufReader::new(&testdata[..]);
+    assert_eq!(buf_reader.buffer().len(), 0);
+
+    let buffer_length = testdata.len();
+    buf_reader.fill_buf().unwrap();
+
+    // Check that size hint matches buffer contents
+    let mut buffered_bytes = buf_reader.bytes();
+    let (lower_bound, _upper_bound) = buffered_bytes.size_hint();
+    assert_eq!(lower_bound, buffer_length);
+
+    // Check that size hint matches buffer contents after advancing
+    buffered_bytes.next().unwrap().unwrap();
+    let (lower_bound, _upper_bound) = buffered_bytes.size_hint();
+    assert_eq!(lower_bound, buffer_length - 1);
+}
+
+#[test]
+fn empty_size_hint() {
+    let size_hint = io::empty().bytes().size_hint();
+    assert_eq!(size_hint, (0, Some(0)));
+}
+
+#[test]
+fn chain_empty_size_hint() {
+    let chain = io::empty().chain(io::empty());
+    let size_hint = chain.bytes().size_hint();
+    assert_eq!(size_hint, (0, Some(0)));
+}
+
+#[test]
+fn chain_size_hint() {
+    let testdata = b"ABCDEFGHIJKL";
+    let mut buf_reader_1 = BufReader::new(&testdata[..6]);
+    let mut buf_reader_2 = BufReader::new(&testdata[6..]);
+
+    buf_reader_1.fill_buf().unwrap();
+    buf_reader_2.fill_buf().unwrap();
+
+    let chain = buf_reader_1.chain(buf_reader_2);
+    let size_hint = chain.bytes().size_hint();
+    assert_eq!(size_hint, (testdata.len(), None));
+}
+
+#[test]
 fn chain_zero_length_read_is_not_eof() {
     let a = b"A";
     let b = b"B";
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index e43ce4cdb4b..f472361f916 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -4,7 +4,9 @@
 mod tests;
 
 use crate::fmt;
-use crate::io::{self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
+use crate::io::{
+    self, BufRead, Initializer, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
+};
 
 /// A reader which is always at EOF.
 ///
@@ -80,6 +82,12 @@ impl fmt::Debug for Empty {
     }
 }
 
+impl SizeHint for Empty {
+    fn upper_bound(&self) -> Option<usize> {
+        Some(0)
+    }
+}
+
 /// A reader which yields one byte over and over and over and over and over and...
 ///
 /// This struct is generally created by calling [`repeat()`]. Please
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 62bf4ffd380..3e7d1d54f12 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -647,9 +647,8 @@ class RustBuild(object):
         compiler = "{}/compiler/".format(top_level)
 
         # Look for a version to compare to based on the current commit.
-        # Ideally this would just use `merge-base`, but on beta and stable branches that wouldn't
-        # come up with any commits, so hack it and use `author=bors` instead.
-        merge_base = ["git", "log", "--author=bors", "--pretty=%H", "-n1", "--", compiler]
+        # Only commits merged by bors will have CI artifacts.
+        merge_base = ["git", "log", "--author=bors", "--pretty=%H", "-n1"]
         commit = subprocess.check_output(merge_base, universal_newlines=True).strip()
 
         # Warn if there were changes to the compiler since the ancestor commit.
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 2008348ea8d..9317c89625d 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -735,8 +735,15 @@ impl<'a> Builder<'a> {
             .env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler))
             .env("CFG_RELEASE_CHANNEL", &self.config.channel)
             .env("RUSTDOC_REAL", self.rustdoc(compiler))
-            .env("RUSTC_BOOTSTRAP", "1")
-            .arg("-Winvalid_codeblock_attributes");
+            .env("RUSTC_BOOTSTRAP", "1");
+
+        // cfg(bootstrap), can be removed on the next beta bump
+        if compiler.stage == 0 {
+            cmd.arg("-Winvalid_codeblock_attributes");
+        } else {
+            cmd.arg("-Wrustdoc::invalid_codeblock_attributes");
+        }
+
         if self.config.deny_warnings {
             cmd.arg("-Dwarnings");
         }
@@ -1292,7 +1299,12 @@ impl<'a> Builder<'a> {
             // fixed via better support from Cargo.
             cargo.env("RUSTC_LINT_FLAGS", lint_flags.join(" "));
 
-            rustdocflags.arg("-Winvalid_codeblock_attributes");
+            // cfg(bootstrap), can be removed on the next beta bump
+            if compiler.stage == 0 {
+                rustdocflags.arg("-Winvalid_codeblock_attributes");
+            } else {
+                rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes");
+            }
         }
 
         if mode == Mode::Rustc {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index b5a8b694c94..fb5127bac54 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -383,6 +383,8 @@ fn configure_cmake(
             cfg.define("CMAKE_SYSTEM_NAME", "Windows");
         } else if target.contains("haiku") {
             cfg.define("CMAKE_SYSTEM_NAME", "Haiku");
+        } else if target.contains("solaris") || target.contains("illumos") {
+            cfg.define("CMAKE_SYSTEM_NAME", "SunOS");
         }
         // When cross-compiling we should also set CMAKE_SYSTEM_VERSION, but in
         // that case like CMake we cannot easily determine system version either.
diff --git a/src/ci/docker/host-x86_64/arm-android/Dockerfile b/src/ci/docker/host-x86_64/arm-android/Dockerfile
index f675252fb16..43cdbbe92e3 100644
--- a/src/ci/docker/host-x86_64/arm-android/Dockerfile
+++ b/src/ci/docker/host-x86_64/arm-android/Dockerfile
@@ -36,5 +36,8 @@ ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target $TARGETS
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 COPY scripts/android-start-emulator.sh /scripts/
 ENTRYPOINT ["/scripts/android-start-emulator.sh"]
diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile
index 95c54ca1abc..e6b6b6e53b9 100644
--- a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile
@@ -24,6 +24,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
 
 ENV CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnueabi-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-android/Dockerfile b/src/ci/docker/host-x86_64/dist-android/Dockerfile
index 258dcea06e6..ee727359f39 100644
--- a/src/ci/docker/host-x86_64/dist-android/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-android/Dockerfile
@@ -36,3 +36,6 @@ ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
+
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile
index 88b13eab2d0..1be3fecd88f 100644
--- a/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-arm-linux/Dockerfile
@@ -27,6 +27,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
 
 ENV CC_arm_unknown_linux_gnueabi=arm-unknown-linux-gnueabi-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile
index 977ef08c274..66eb4137a87 100644
--- a/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-armhf-linux/Dockerfile
@@ -19,6 +19,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabihf/bin
 
 ENV CC_arm_unknown_linux_gnueabihf=arm-unknown-linux-gnueabihf-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile
index 65d713359d9..c13f63911f8 100644
--- a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile
@@ -19,6 +19,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/armv7-unknown-linux-gnueabihf/bin
 
 ENV CC_armv7_unknown_linux_gnueabihf=armv7-unknown-linux-gnueabihf-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
index c734202eef6..c98fc7dcfff 100644
--- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile
@@ -30,6 +30,9 @@ RUN CC=gcc CFLAGS="-m32 -Wa,-mrelax-relocations=no" \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-i586=/musl-i586 \
       --musl-root-i686=/musl-i686 \
diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
index 22d7cbb0d14..247b539652b 100644
--- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
@@ -68,11 +68,13 @@ RUN ./build-binutils.sh
 COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
 RUN ./build-gcc.sh && apt-get remove -y gcc g++
 
-# Debian 6 has Python 2.6 by default, but LLVM needs 2.7+
 COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/
-RUN ./build-python.sh
+# Build Python 2.7 needed for Clang 10.
+RUN ./build-python.sh 2.7.12
+# Build Python 3 needed for LLVM 12.
+RUN ./build-python.sh 3.9.1
 
-# LLVM needs cmake 3.4.3 or higher, and is planning to raise to 3.13.4.
+# LLVM needs cmake 3.13.4 or higher.
 COPY host-x86_64/dist-x86_64-linux/build-cmake.sh /tmp/
 RUN ./build-cmake.sh
 
diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
index cb5c17c25ab..b0f06569a9c 100644
--- a/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mips-linux/Dockerfile
@@ -21,6 +21,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV HOSTS=mips-unknown-linux-gnu
 
 ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
index 31146e3ead4..245c28e1fa3 100644
--- a/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mips64-linux/Dockerfile
@@ -20,6 +20,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV HOSTS=mips64-unknown-linux-gnuabi64
 
 ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
index dadd50a7e66..03998c8880a 100644
--- a/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/Dockerfile
@@ -21,6 +21,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV HOSTS=mips64el-unknown-linux-gnuabi64
 
 ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
index d2d65565b10..58617270621 100644
--- a/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/Dockerfile
@@ -20,6 +20,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV HOSTS=mipsel-unknown-linux-gnu
 
 ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile
index 651daac8613..ecaa495e97a 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-powerpc-linux/Dockerfile
@@ -25,6 +25,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
 
 ENV \
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile
index 6ff4d787212..a22d9a7553e 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux/Dockerfile
@@ -26,6 +26,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
 
 ENV \
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
index c1a621ff105..5157dd4c79b 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
@@ -25,6 +25,9 @@ RUN ./build-powerpc64le-toolchain.sh
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV \
     AR_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-ar \
     CC_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
index dff7c475157..80b7793cb7e 100644
--- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
@@ -19,6 +19,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/riscv64-unknown-linux-gnu/bin
 
 ENV CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile
index 1b261993cfc..5e626243952 100644
--- a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile
@@ -25,6 +25,9 @@ USER root
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin
 
 ENV \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
index 8413d775ac4..121dd3f455a 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
@@ -23,6 +23,9 @@ RUN /tmp/freebsd-toolchain.sh x86_64
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV \
     AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd11-ar \
     CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd11-clang \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
index 2a0f6a39c57..c2e44ead51e 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
@@ -22,6 +22,9 @@ RUN bash /tmp/illumos-toolchain.sh x86_64 gcc
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV \
     AR_x86_64_unknown_illumos=x86_64-illumos-ar \
     CC_x86_64_unknown_illumos=x86_64-illumos-gcc \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index d1b4bbf7fff..4dd4378f196 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -68,11 +68,13 @@ RUN ./build-binutils.sh
 COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/
 RUN ./build-gcc.sh && apt-get remove -y gcc g++
 
-# Debian 6 has Python 2.6 by default, but LLVM needs 2.7+
 COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/
-RUN ./build-python.sh
+# Build Python 2.7 needed for Clang 10.
+RUN ./build-python.sh 2.7.12
+# Build Python 3 needed for LLVM 12.
+RUN ./build-python.sh 3.9.1
 
-# LLVM needs cmake 3.4.3 or higher, and is planning to raise to 3.13.4.
+# LLVM needs cmake 3.13.4 or higher.
 COPY host-x86_64/dist-x86_64-linux/build-cmake.sh /tmp/
 RUN ./build-cmake.sh
 
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-python.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-python.sh
index c172b978112..970d67b6db3 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-python.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-python.sh
@@ -3,7 +3,8 @@
 set -ex
 source shared.sh
 
-curl https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz | \
+VERSION=$1
+curl https://www.python.org/ftp/python/$VERSION/Python-$VERSION.tgz | \
   tar xzf -
 
 mkdir python-build
@@ -12,10 +13,10 @@ cd python-build
 # Gotta do some hackery to tell python about our custom OpenSSL build, but other
 # than that fairly normal.
 CFLAGS='-I /rustroot/include' LDFLAGS='-L /rustroot/lib -L /rustroot/lib64' \
-    hide_output ../Python-2.7.12/configure --prefix=/rustroot
+    hide_output ../Python-$VERSION/configure --prefix=/rustroot
 hide_output make -j10
 hide_output make install
 
 cd ..
 rm -rf python-build
-rm -rf Python-2.7.12
+rm -rf Python-$VERSION
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
index 904ee64db3b..08f07eb8284 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
@@ -20,6 +20,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 
 WORKDIR /build/
 
+# Build cmake before musl toolchain, as we replace the compiler during that step.
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 COPY scripts/musl-toolchain.sh /build/
 # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
 RUN CFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
index f3f7255f154..92bdc9811fd 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
@@ -9,6 +9,9 @@ RUN /tmp/build-netbsd-toolchain.sh
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
 
 ENV \
diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
index 0e28ea9668f..0182ebb8b59 100644
--- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
@@ -20,6 +20,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 RUN mkdir -p /config
 RUN echo "[rust]" > /config/nopt-std-config.toml
 RUN echo "optimize = false" >> /config/nopt-std-config.toml
diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
index 195601755f3..feaab819bdd 100644
--- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
@@ -20,6 +20,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu
 # Exclude some tests that are unlikely to be platform specific, to speed up
 # this slow job.
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index cb50e0c8f74..a9398649cf0 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -20,7 +20,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 RUN curl -sL https://nodejs.org/dist/v14.4.0/node-v14.4.0-linux-x64.tar.xz | tar -xJ
 ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
 # Install es-check
-RUN npm install es-check -g
+# Pin its version to prevent unrelated CI failures due to future es-check versions.
+RUN npm install es-check@5.2.3 -g
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
index a5bedadc05b..00ad7b0a710 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
@@ -42,5 +42,8 @@ RUN npm install browser-ui-test -g --unsafe-perm=true
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
 ENV RUST_CHECK_TARGET check-aux-and-gui
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
index 5faa0ccab56..09d9cda02bd 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
@@ -19,6 +19,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --set rust.ignore-git=false
 ENV SCRIPT python3 ../x.py --stage 2 test distcheck
 ENV DIST_SRC 1
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 89171a6f215..d4838c0d6f8 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -18,6 +18,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+COPY scripts/cmake.sh /scripts/
+RUN /scripts/cmake.sh
+
 COPY host-x86_64/x86_64-gnu-tools/checktools.sh /tmp/
 
 ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/docker/scripts/cmake.sh b/src/ci/docker/scripts/cmake.sh
new file mode 100755
index 00000000000..70096173403
--- /dev/null
+++ b/src/ci/docker/scripts/cmake.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+set -ex
+
+hide_output() {
+  set +x
+  on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+  trap "$on_err" ERR
+  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+  PING_LOOP_PID=$!
+  "$@" &> /tmp/build.log
+  trap - ERR
+  kill $PING_LOOP_PID
+  rm /tmp/build.log
+  set -x
+}
+
+# LLVM 12 requires CMake 3.13.4 or higher.
+# This script is not necessary for images using Ubuntu 20.04 or newer.
+CMAKE=3.13.4
+curl -L https://github.com/Kitware/CMake/releases/download/v$CMAKE/cmake-$CMAKE.tar.gz | tar xzf -
+
+mkdir cmake-build
+cd cmake-build
+hide_output ../cmake-$CMAKE/configure
+hide_output make -j$(nproc)
+hide_output make install
+
+cd ..
+rm -rf cmake-build
+rm -rf cmake-$CMAKE
diff --git a/src/doc/rust.css b/src/doc/rust.css
index a92d4ff54db..ff18e1a8f51 100644
--- a/src/doc/rust.css
+++ b/src/doc/rust.css
@@ -3,30 +3,35 @@
 	font-style: normal;
 	font-weight: 400;
 	src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Fira Sans';
 	font-style: normal;
 	font-weight: 500;
 	src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Serif Pro';
 	font-style: normal;
 	font-weight: 400;
 	src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Serif Pro';
 	font-style: italic;
 	font-weight: 400;
 	src: url("SourceSerifPro-It.ttf.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Serif Pro';
 	font-style: normal;
 	font-weight: 700;
 	src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Code Pro';
@@ -35,6 +40,7 @@
 	/* Avoid using locally installed font because bad versions are in circulation:
 	 * see https://github.com/rust-lang/rust/issues/24355 */
 	src: url("SourceCodePro-Regular.woff") format('woff');
+	font-display: swap;
 }
 
 *:not(body) {
diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md
index cce3623dc8f..174db711bce 100644
--- a/src/doc/rustdoc/src/lints.md
+++ b/src/doc/rustdoc/src/lints.md
@@ -4,12 +4,13 @@
 can use them like any other lints by doing this:
 
 ```rust
-#![allow(missing_docs)] // allows the lint, no diagnostics will be reported
-#![warn(missing_docs)] // warn if there are missing docs
-#![deny(missing_docs)] // error if there are missing docs
-# //! Crate docs.
+#![allow(rustdoc::broken_intra_doc_links)] // allows the lint, no diagnostics will be reported
+#![warn(rustdoc::broken_intra_doc_links)] // warn if there are broken intra-doc links
+#![deny(rustdoc::broken_intra_doc_links)] // error if there are broken intra-doc links
 ```
 
+Note that, except for `missing_docs`, these lints are only available when running `rustdoc`, not `rustc`.
+
 Here is the list of the lints provided by `rustdoc`:
 
 ## broken_intra_doc_links
@@ -51,7 +52,7 @@ warning: `Foo` is both an enum and a function
 1 | /// [`Foo`]
   |      ^^^^^ ambiguous link
   |
-  = note: `#[warn(broken_intra_doc_links)]` on by default
+  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
 help: to link to the enum, prefix with the item type
   |
 1 | /// [`enum@Foo`]
@@ -83,7 +84,7 @@ warning: public documentation for `public` links to private item `private`
 1 | /// [private]
   |      ^^^^^^^ this item is private
   |
-  = note: `#[warn(private_intra_doc_links)]` on by default
+  = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
   = note: this link will resolve properly if you pass `--document-private-items`
 ```
 
@@ -97,7 +98,7 @@ warning: public documentation for `public` links to private item `private`
 1 | /// [private]
   |      ^^^^^^^ this item is private
   |
-  = note: `#[warn(private_intra_doc_links)]` on by default
+  = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
   = note: this link resolves only because you passed `--document-private-items`, but will break without
 ```
 
@@ -125,13 +126,15 @@ warning: missing documentation for a function
    | ^^^^^^^^^^^^^^^^^^^^^
 ```
 
+Note that unlike other rustdoc lints, this lint is also available from `rustc` directly.
+
 ## missing_crate_level_docs
 
 This lint is **allowed by default**. It detects if there is no documentation
 at the crate root. For example:
 
 ```rust
-#![warn(missing_crate_level_docs)]
+#![warn(rustdoc::missing_crate_level_docs)]
 ```
 
 This will generate the following warning:
@@ -155,7 +158,7 @@ This lint is **allowed by default** and is **nightly-only**. It detects when a d
 is missing a code example. For example:
 
 ```rust
-#![warn(missing_doc_code_examples)]
+#![warn(rustdoc::missing_doc_code_examples)]
 
 /// There is no code example!
 pub fn no_code_example() {}
@@ -191,7 +194,7 @@ This lint is **allowed by default**. It detects documentation tests when they
 are on a private item. For example:
 
 ```rust
-#![warn(private_doc_tests)]
+#![warn(rustdoc::private_doc_tests)]
 
 mod foo {
     /// private doc test
@@ -245,7 +248,7 @@ warning: unknown attribute `should-panic`. Did you mean `should_panic`?
 5 | | /// ```
   | |_______^
   |
-  = note: `#[warn(invalid_codeblock_attributes)]` on by default
+  = note: `#[warn(rustdoc::invalid_codeblock_attributes)]` on by default
   = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running
 ```
 
@@ -258,7 +261,7 @@ This lint is **allowed by default** and is **nightly-only**. It detects unclosed
 or invalid HTML tags. For example:
 
 ```rust
-#![warn(invalid_html_tags)]
+#![warn(rustdoc::invalid_html_tags)]
 
 /// <h1>
 /// </script>
@@ -275,7 +278,11 @@ warning: unopened HTML tag `script`
 2 | | /// </script>
   | |_____________^
   |
-  = note: `#[warn(invalid_html_tags)]` on by default
+  note: the lint level is defined here
+ --> foo.rs:1:9
+  |
+1 | #![warn(rustdoc::invalid_html_tags)]
+  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unclosed HTML tag `h1`
  --> foo.rs:1:1
@@ -310,7 +317,7 @@ warning: this URL is not a hyperlink
 1 | /// http://example.org
   |     ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.org>`
   |
-  = note: `#[warn(non_autolinks)]` on by default
+  = note: `#[warn(rustdoc::non_autolinks)]` on by default
 
 warning: unneeded long form for URL
  --> foo.rs:2:5
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 09ba0e2740f..e3f47a85d51 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -191,7 +191,7 @@ impl Item {
     }
 
     crate fn links(&self, cache: &Cache) -> Vec<RenderedLink> {
-        self.attrs.links(&self.def_id.krate, cache)
+        self.attrs.links(self.def_id.krate, cache)
     }
 
     crate fn is_crate(&self) -> bool {
@@ -844,7 +844,7 @@ impl Attributes {
     /// Gets links as a vector
     ///
     /// Cache must be populated before call
-    crate fn links(&self, krate: &CrateNum, cache: &Cache) -> Vec<RenderedLink> {
+    crate fn links(&self, krate: CrateNum, cache: &Cache) -> Vec<RenderedLink> {
         use crate::html::format::href;
         use crate::html::render::CURRENT_DEPTH;
 
@@ -869,7 +869,7 @@ impl Attributes {
                     }
                     None => {
                         if let Some(ref fragment) = *fragment {
-                            let url = match cache.extern_locations.get(krate) {
+                            let url = match cache.extern_locations.get(&krate) {
                                 Some(&(_, _, ExternalLocation::Local)) => {
                                     let depth = CURRENT_DEPTH.with(|l| l.get());
                                     "../".repeat(depth)
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 6218aaf8276..9cb0649b314 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -24,9 +24,10 @@ use rustc_span::source_map;
 use rustc_span::symbol::sym;
 use rustc_span::DUMMY_SP;
 
+use std::cell::RefCell;
+use std::collections::hash_map::Entry;
 use std::mem;
 use std::rc::Rc;
-use std::{cell::RefCell, collections::hash_map::Entry};
 
 use crate::clean;
 use crate::clean::inline::build_external_trait;
@@ -227,64 +228,6 @@ crate fn new_handler(
     )
 }
 
-/// This function is used to setup the lint initialization. By default, in rustdoc, everything
-/// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
-/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTES" lint is activated in both
-/// modes.
-///
-/// A little detail easy to forget is that there is a way to set the lint level for all lints
-/// through the "WARNINGS" lint. To prevent this to happen, we set it back to its "normal" level
-/// inside this function.
-///
-/// It returns a tuple containing:
-///  * Vector of tuples of lints' name and their associated "max" level
-///  * HashMap of lint id with their associated "max" level
-pub(crate) fn init_lints<F>(
-    mut allowed_lints: Vec<String>,
-    lint_opts: Vec<(String, lint::Level)>,
-    filter_call: F,
-) -> (Vec<(String, lint::Level)>, FxHashMap<lint::LintId, lint::Level>)
-where
-    F: Fn(&lint::Lint) -> Option<(String, lint::Level)>,
-{
-    let warnings_lint_name = lint::builtin::WARNINGS.name;
-
-    allowed_lints.push(warnings_lint_name.to_owned());
-    allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
-
-    let lints = || {
-        lint::builtin::HardwiredLints::get_lints()
-            .into_iter()
-            .chain(rustc_lint::SoftLints::get_lints().into_iter())
-    };
-
-    let lint_opts = lints()
-        .filter_map(|lint| {
-            // Permit feature-gated lints to avoid feature errors when trying to
-            // allow all lints.
-            if lint.feature_gate.is_some() || allowed_lints.iter().any(|l| lint.name == l) {
-                None
-            } else {
-                filter_call(lint)
-            }
-        })
-        .chain(lint_opts.into_iter())
-        .collect::<Vec<_>>();
-
-    let lint_caps = lints()
-        .filter_map(|lint| {
-            // We don't want to allow *all* lints so let's ignore
-            // those ones.
-            if allowed_lints.iter().any(|l| lint.name == l) {
-                None
-            } else {
-                Some((lint::LintId::of(lint), lint::Allow))
-            }
-        })
-        .collect();
-    (lint_opts, lint_caps)
-}
-
 /// Parse, resolve, and typecheck the given crate.
 crate fn create_config(
     RustdocOptions {
@@ -313,37 +256,22 @@ crate fn create_config(
     let cpath = Some(input.clone());
     let input = Input::File(input);
 
-    let broken_intra_doc_links = lint::builtin::BROKEN_INTRA_DOC_LINKS.name;
-    let private_intra_doc_links = lint::builtin::PRIVATE_INTRA_DOC_LINKS.name;
-    let missing_docs = rustc_lint::builtin::MISSING_DOCS.name;
-    let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name;
-    let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name;
-    let no_crate_level_docs = rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS.name;
-    let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
-    let invalid_html_tags = rustc_lint::builtin::INVALID_HTML_TAGS.name;
-    let renamed_and_removed_lints = rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name;
-    let non_autolinks = rustc_lint::builtin::NON_AUTOLINKS.name;
-    let unknown_lints = rustc_lint::builtin::UNKNOWN_LINTS.name;
-
-    // In addition to those specific lints, we also need to allow those given through
-    // command line, otherwise they'll get ignored and we don't want that.
-    let lints_to_show = vec![
-        broken_intra_doc_links.to_owned(),
-        private_intra_doc_links.to_owned(),
-        missing_docs.to_owned(),
-        missing_doc_example.to_owned(),
-        private_doc_tests.to_owned(),
-        no_crate_level_docs.to_owned(),
-        invalid_codeblock_attributes_name.to_owned(),
-        invalid_html_tags.to_owned(),
-        renamed_and_removed_lints.to_owned(),
-        unknown_lints.to_owned(),
-        non_autolinks.to_owned(),
+    // By default, rustdoc ignores all lints.
+    // Specifically unblock lints relevant to documentation or the lint machinery itself.
+    let mut lints_to_show = vec![
+        // it's unclear whether this should be part of rustdoc directly (#77364)
+        rustc_lint::builtin::MISSING_DOCS.name.to_string(),
+        // these are definitely not part of rustdoc, but we want to warn on them anyway.
+        rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name.to_string(),
+        rustc_lint::builtin::UNKNOWN_LINTS.name.to_string(),
     ];
+    lints_to_show.extend(crate::lint::RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string()));
 
-    let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| {
+    let (lint_opts, lint_caps) = crate::lint::init_lints(lints_to_show, lint_opts, |lint| {
         // FIXME: why is this necessary?
-        if lint.name == broken_intra_doc_links || lint.name == invalid_codeblock_attributes_name {
+        if lint.name == crate::lint::BROKEN_INTRA_DOC_LINKS.name
+            || lint.name == crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name
+        {
             None
         } else {
             Some((lint.name_lower(), lint::Allow))
@@ -383,7 +311,7 @@ crate fn create_config(
         diagnostic_output: DiagnosticOutput::Default,
         stderr: None,
         lint_caps,
-        register_lints: None,
+        register_lints: Some(box crate::lint::register_lints),
         override_queries: Some(|_sess, providers, _external_providers| {
             // Most lints will require typechecking, so just don't run them.
             providers.lint_mod = |_, _| {};
@@ -550,7 +478,7 @@ crate fn run_global_ctxt(
             let help = "The following guide may be of use:\n\
                 https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html";
             tcx.struct_lint_node(
-                rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS,
+                crate::lint::MISSING_CRATE_LEVEL_DOCS,
                 ctxt.as_local_hir_id(m.def_id).unwrap(),
                 |lint| {
                     let mut diag =
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index c3b9fd5a1dd..27ce064669d 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -26,8 +26,8 @@ use std::str;
 
 use crate::clean::Attributes;
 use crate::config::Options;
-use crate::core::init_lints;
 use crate::html::markdown::{self, ErrorCodes, Ignore, LangString};
+use crate::lint::init_lints;
 use crate::passes::span_of_attrs;
 
 #[derive(Clone, Default)]
@@ -44,11 +44,14 @@ crate struct TestOptions {
 crate fn run(options: Options) -> Result<(), ErrorReported> {
     let input = config::Input::File(options.input.clone());
 
-    let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
+    let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;
 
-    // In addition to those specific lints, we also need to allow those given through
-    // command line, otherwise they'll get ignored and we don't want that.
-    let allowed_lints = vec![invalid_codeblock_attributes_name.to_owned()];
+    // See core::create_config for what's going on here.
+    let allowed_lints = vec![
+        invalid_codeblock_attributes_name.to_owned(),
+        lint::builtin::UNKNOWN_LINTS.name.to_owned(),
+        lint::builtin::RENAMED_AND_REMOVED_LINTS.name.to_owned(),
+    ];
 
     let (lint_opts, lint_caps) = init_lints(allowed_lints, options.lint_opts.clone(), |lint| {
         if lint.name == invalid_codeblock_attributes_name {
@@ -92,7 +95,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
         diagnostic_output: DiagnosticOutput::Default,
         stderr: None,
         lint_caps,
-        register_lints: None,
+        register_lints: Some(box crate::lint::register_lints),
         override_queries: None,
         make_codegen_backend: None,
         registry: rustc_driver::diagnostics_registry(),
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 73c106f5ae0..ab65c71d7d1 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -58,6 +58,7 @@ crate fn render<T: Print, S: Print>(
     {style_files}\
     <script id=\"default-settings\"{default_settings}></script>\
     <script src=\"{static_root_path}storage{suffix}.js\"></script>\
+    <script src=\"{static_root_path}crates{suffix}.js\"></script>\
     <noscript><link rel=\"stylesheet\" href=\"{static_root_path}noscript{suffix}.css\"></noscript>\
     {css_extension}\
     {favicon}\
@@ -82,7 +83,7 @@ crate fn render<T: Print, S: Print>(
     <div class=\"theme-picker\">\
         <button id=\"theme-picker\" aria-label=\"Pick another theme!\" aria-haspopup=\"menu\">\
             <img src=\"{static_root_path}brush{suffix}.svg\" \
-                 width=\"18\" \
+                 width=\"18\" height=\"18\" \
                  alt=\"Pick another theme!\">\
         </button>\
         <div id=\"theme-choices\" role=\"menu\"></div>\
@@ -102,7 +103,7 @@ crate fn render<T: Print, S: Print>(
                 <button type=\"button\" class=\"help-button\">?</button>
                 <a id=\"settings-menu\" href=\"{root_path}settings.html\">\
                     <img src=\"{static_root_path}wheel{suffix}.svg\" \
-                         width=\"18\" \
+                         width=\"18\" height=\"18\" \
                          alt=\"Change settings\">\
                 </a>\
             </div>\
@@ -112,10 +113,10 @@ crate fn render<T: Print, S: Print>(
     <section id=\"search\" class=\"content hidden\"></section>\
     <section class=\"footer\"></section>\
     {after_content}\
-    <div id=\"rustdoc-vars\" data-root-path=\"{root_path}\" data-current-crate=\"{krate}\"></div>
+    <div id=\"rustdoc-vars\" data-root-path=\"{root_path}\" data-current-crate=\"{krate}\" \
+       data-search-js=\"{root_path}search-index{suffix}.js\"></div>
     <script src=\"{static_root_path}main{suffix}.js\"></script>\
     {extra_scripts}\
-    <script defer src=\"{root_path}search-index{suffix}.js\"></script>\
 </body>\
 </html>",
         css_extension = if layout.css_file_extension.is_some() {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 9a054e29dd3..f8ca259fb9a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -21,7 +21,6 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
 use rustc_hir::HirId;
 use rustc_middle::ty::TyCtxt;
-use rustc_session::lint;
 use rustc_span::edition::Edition;
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -721,7 +720,7 @@ impl<'tcx> ExtraInfo<'tcx> {
             (None, None) => return,
         };
         self.tcx.struct_span_lint_hir(
-            lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES,
+            crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
             hir_id,
             self.sp,
             |lint| {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 394c57c7214..fbeeb2a6fa2 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1061,10 +1061,12 @@ themePicker.onblur = handleThemeButtonsBlur;
         cx.shared.fs.write(&dst, v.as_bytes())?;
     }
 
-    // Update the search index
+    // Update the search index and crate list.
     let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix));
     let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name.as_str()), &dst);
     all_indexes.push(search_index);
+    krates.push(krate.name.to_string());
+    krates.sort();
 
     // Sort the indexes by crate so the file will be generated identically even
     // with rustdoc running in parallel.
@@ -1072,11 +1074,15 @@ themePicker.onblur = handleThemeButtonsBlur;
     {
         let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
         v.push_str(&all_indexes.join(",\\\n"));
-        // "addSearchOptions" has to be called first so the crate filtering can be set before the
-        // search might start (if it's set into the URL for example).
-        v.push_str("\\\n}');\naddSearchOptions(searchIndex);initSearch(searchIndex);");
+        v.push_str("\\\n}');\ninitSearch(searchIndex);");
         cx.shared.fs.write(&dst, &v)?;
     }
+
+    let crate_list_dst = cx.dst.join(&format!("crates{}.js", cx.shared.resource_suffix));
+    let crate_list =
+        format!("window.ALL_CRATES = [{}];", krates.iter().map(|k| format!("\"{}\"", k)).join(","));
+    cx.shared.fs.write(&crate_list_dst, &crate_list)?;
+
     if options.enable_index_page {
         if let Some(index_page) = options.index_page.clone() {
             let mut md_opts = options.clone();
@@ -1098,9 +1104,6 @@ themePicker.onblur = handleThemeButtonsBlur;
                 extra_scripts: &[],
                 static_extra_scripts: &[],
             };
-            krates.push(krate.name.to_string());
-            krates.sort();
-            krates.dedup();
 
             let content = format!(
                 "<h1 class=\"fqn\">\
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 76449a171d7..89b1362b32b 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -42,6 +42,7 @@ if (!DOMTokenList.prototype.remove) {
     if (rustdocVars) {
         window.rootPath = rustdocVars.attributes["data-root-path"].value;
         window.currentCrate = rustdocVars.attributes["data-current-crate"].value;
+        window.searchJS = rustdocVars.attributes["data-search-js"].value;
     }
     var sidebarVars = document.getElementById("sidebar-vars");
     if (sidebarVars) {
@@ -1922,8 +1923,8 @@ function defocusSearchBar() {
             return searchWords;
         }
 
-        function startSearch() {
-            var callback = function() {
+        function registerSearchEvents() {
+            var searchAfter500ms = function() {
                 clearInputTimeout();
                 if (search_input.value.length === 0) {
                     if (browserSupportsHistoryApi()) {
@@ -1935,8 +1936,8 @@ function defocusSearchBar() {
                     searchTimeout = setTimeout(search, 500);
                 }
             };
-            search_input.onkeyup = callback;
-            search_input.oninput = callback;
+            search_input.onkeyup = searchAfter500ms;
+            search_input.oninput = searchAfter500ms;
             document.getElementsByClassName("search-form")[0].onsubmit = function(e) {
                 e.preventDefault();
                 clearInputTimeout();
@@ -1999,7 +2000,6 @@ function defocusSearchBar() {
                     }
                 });
             }
-            search();
 
             // This is required in firefox to avoid this problem: Navigating to a search result
             // with the keyboard, hitting enter, and then hitting back would take you back to
@@ -2017,8 +2017,14 @@ function defocusSearchBar() {
         }
 
         index = buildIndex(rawSearchIndex);
-        startSearch();
+        registerSearchEvents();
+        // If there's a search term in the URL, execute the search now.
+        if (getQueryStringParams().search) {
+            search();
+        }
+    };
 
+    function addSidebarCrates(crates) {
         // Draw a convenient sidebar of known crates if we have a listing
         if (window.rootPath === "../" || window.rootPath === "./") {
             var sidebar = document.getElementsByClassName("sidebar-elems")[0];
@@ -2029,14 +2035,6 @@ function defocusSearchBar() {
                 var ul = document.createElement("ul");
                 div.appendChild(ul);
 
-                var crates = [];
-                for (var crate in rawSearchIndex) {
-                    if (!hasOwnProperty(rawSearchIndex, crate)) {
-                        continue;
-                    }
-                    crates.push(crate);
-                }
-                crates.sort();
                 for (var i = 0; i < crates.length; ++i) {
                     var klass = "crate";
                     if (window.rootPath !== "./" && crates[i] === window.currentCrate) {
@@ -2044,9 +2042,6 @@ function defocusSearchBar() {
                     }
                     var link = document.createElement("a");
                     link.href = window.rootPath + crates[i] + "/index.html";
-                    // The summary in the search index has HTML, so we need to
-                    // dynamically render it as plaintext.
-                    link.title = convertHTMLToPlaintext(rawSearchIndex[crates[i]].doc);
                     link.className = klass;
                     link.textContent = crates[i];
 
@@ -2057,7 +2052,7 @@ function defocusSearchBar() {
                 sidebar.appendChild(div);
             }
         }
-    };
+    }
 
     /**
      * Convert HTML to plaintext:
@@ -2862,37 +2857,18 @@ function defocusSearchBar() {
         }
     }
 
-    window.addSearchOptions = function(crates) {
+    function addSearchOptions(crates) {
         var elem = document.getElementById("crate-search");
 
         if (!elem) {
             enableSearchInput();
             return;
         }
-        var crates_text = [];
-        if (Object.keys(crates).length > 1) {
-            for (var crate in crates) {
-                if (hasOwnProperty(crates, crate)) {
-                    crates_text.push(crate);
-                }
-            }
-        }
-        crates_text.sort(function(a, b) {
-            var lower_a = a.toLowerCase();
-            var lower_b = b.toLowerCase();
-
-            if (lower_a < lower_b) {
-                return -1;
-            } else if (lower_a > lower_b) {
-                return 1;
-            }
-            return 0;
-        });
         var savedCrate = getSettingValue("saved-filter-crate");
-        for (var i = 0, len = crates_text.length; i < len; ++i) {
+        for (var i = 0, len = crates.length; i < len; ++i) {
             var option = document.createElement("option");
-            option.value = crates_text[i];
-            option.innerText = crates_text[i];
+            option.value = crates[i];
+            option.innerText = crates[i];
             elem.appendChild(option);
             // Set the crate filter from saved storage, if the current page has the saved crate
             // filter.
@@ -2900,7 +2876,7 @@ function defocusSearchBar() {
             // If not, ignore the crate filter -- we want to support filtering for crates on sites
             // like doc.rust-lang.org where the crates may differ from page to page while on the
             // same domain.
-            if (crates_text[i] === savedCrate) {
+            if (crates[i] === savedCrate) {
                 elem.value = savedCrate;
             }
         }
@@ -2969,6 +2945,44 @@ function defocusSearchBar() {
         buildHelperPopup = function() {};
     }
 
+    function loadScript(url) {
+        var script = document.createElement('script');
+        script.src = url;
+        document.head.append(script);
+    }
+
+    function setupSearchLoader() {
+        var searchLoaded = false;
+        function loadSearch() {
+            if (!searchLoaded) {
+                searchLoaded = true;
+                loadScript(window.searchJS);
+            }
+        }
+
+        // `crates{version}.js` should always be loaded before this script, so we can use it safely.
+        addSearchOptions(window.ALL_CRATES);
+        addSidebarCrates(window.ALL_CRATES);
+
+        search_input.addEventListener("focus", function() {
+            search_input.origPlaceholder = search_input.placeholder;
+            search_input.placeholder = "Type your search here.";
+            loadSearch();
+        });
+        search_input.addEventListener("blur", function() {
+            search_input.placeholder = search_input.origPlaceholder;
+        });
+        enableSearchInput();
+
+        var crateSearchDropDown = document.getElementById("crate-search");
+        crateSearchDropDown.addEventListener("focus", loadSearch);
+        var params = getQueryStringParams();
+        if (params.search !== undefined) {
+            loadSearch();
+        }
+    }
+
     onHashChange(null);
     window.onhashchange = onHashChange;
+    setupSearchLoader();
 }());
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index e3d63fa2308..94c231cb33a 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -6,6 +6,7 @@
 	src: local('Fira Sans'),
 		url("FiraSans-Regular.woff2") format("woff2"),
 		url("FiraSans-Regular.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Fira Sans';
@@ -14,6 +15,7 @@
 	src: local('Fira Sans Medium'),
 		url("FiraSans-Medium.woff2") format("woff2"),
 		url("FiraSans-Medium.woff") format('woff');
+	font-display: swap;
 }
 
 /* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license. */
@@ -22,18 +24,21 @@
 	font-style: normal;
 	font-weight: 400;
 	src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Serif Pro';
 	font-style: italic;
 	font-weight: 400;
 	src: local('Source Serif Pro Italic'), url("SourceSerifPro-It.ttf.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Serif Pro';
 	font-style: normal;
 	font-weight: 700;
 	src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff');
+	font-display: swap;
 }
 
 /* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */
@@ -44,12 +49,14 @@
 	/* Avoid using locally installed font because bad versions are in circulation:
 	 * see https://github.com/rust-lang/rust/issues/24355 */
 	src: url("SourceCodePro-Regular.woff") format('woff');
+	font-display: swap;
 }
 @font-face {
 	font-family: 'Source Code Pro';
 	font-style: normal;
 	font-weight: 600;
 	src: url("SourceCodePro-Semibold.woff") format('woff');
+	font-display: swap;
 }
 
 * {
@@ -129,7 +136,7 @@ h1, h2, h3, h4,
 #source-sidebar, #sidebar-toggle,
 /* This selector is for the items listed in the "all items" page. */
 #main > ul.docblock > li > a {
-	font-family: "Fira Sans", sans-serif;
+	font-family: "Fira Sans", Arial;
 }
 
 .content ul.crate a.crate {
@@ -475,7 +482,7 @@ h4 > code, h3 > code, .invisible > code {
 }
 #main > .since {
 	top: inherit;
-	font-family: "Fira Sans", sans-serif;
+	font-family: "Fira Sans", Arial;
 }
 
 .content table:not(.table-display) {
@@ -684,6 +691,7 @@ a {
 	width: calc(100% - 63px);
 }
 #crate-search {
+	min-width: 115px;
 	margin-top: 5px;
 	padding: 6px;
 	padding-right: 19px;
@@ -1293,7 +1301,7 @@ h4 > .notable-traits {
 
 .help-button {
 	right: 30px;
-	font-family: "Fira Sans",sans-serif;
+	font-family: "Fira Sans", Arial;
 	text-align: center;
 	font-size: 17px;
 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index c0e91a05dff..e447b49c11a 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -45,6 +45,7 @@ extern crate rustc_infer;
 extern crate rustc_interface;
 extern crate rustc_lexer;
 extern crate rustc_lint;
+extern crate rustc_lint_defs;
 extern crate rustc_metadata;
 extern crate rustc_middle;
 extern crate rustc_mir;
@@ -86,6 +87,7 @@ mod formats;
 // used by the error-index generator, so it needs to be public
 pub mod html;
 mod json;
+crate mod lint;
 mod markdown;
 mod passes;
 mod theme;
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
new file mode 100644
index 00000000000..e8806c1b6d7
--- /dev/null
+++ b/src/librustdoc/lint.rs
@@ -0,0 +1,188 @@
+use rustc_data_structures::fx::FxHashMap;
+use rustc_lint::LintStore;
+use rustc_lint_defs::{declare_tool_lint, Lint, LintId};
+use rustc_session::{lint, Session};
+
+use std::lazy::SyncLazy as Lazy;
+
+/// This function is used to setup the lint initialization. By default, in rustdoc, everything
+/// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
+/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTES" lint is activated in both
+/// modes.
+///
+/// A little detail easy to forget is that there is a way to set the lint level for all lints
+/// through the "WARNINGS" lint. To prevent this to happen, we set it back to its "normal" level
+/// inside this function.
+///
+/// It returns a tuple containing:
+///  * Vector of tuples of lints' name and their associated "max" level
+///  * HashMap of lint id with their associated "max" level
+pub(crate) fn init_lints<F>(
+    mut allowed_lints: Vec<String>,
+    lint_opts: Vec<(String, lint::Level)>,
+    filter_call: F,
+) -> (Vec<(String, lint::Level)>, FxHashMap<lint::LintId, lint::Level>)
+where
+    F: Fn(&lint::Lint) -> Option<(String, lint::Level)>,
+{
+    let warnings_lint_name = lint::builtin::WARNINGS.name;
+
+    allowed_lints.push(warnings_lint_name.to_owned());
+    allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
+
+    let lints = || {
+        lint::builtin::HardwiredLints::get_lints()
+            .into_iter()
+            .chain(rustc_lint::SoftLints::get_lints().into_iter())
+    };
+
+    let lint_opts = lints()
+        .filter_map(|lint| {
+            // Permit feature-gated lints to avoid feature errors when trying to
+            // allow all lints.
+            if lint.feature_gate.is_some() || allowed_lints.iter().any(|l| lint.name == l) {
+                None
+            } else {
+                filter_call(lint)
+            }
+        })
+        .chain(lint_opts.into_iter())
+        .collect::<Vec<_>>();
+
+    let lint_caps = lints()
+        .filter_map(|lint| {
+            // We don't want to allow *all* lints so let's ignore
+            // those ones.
+            if allowed_lints.iter().any(|l| lint.name == l) {
+                None
+            } else {
+                Some((lint::LintId::of(lint), lint::Allow))
+            }
+        })
+        .collect();
+    (lint_opts, lint_caps)
+}
+
+macro_rules! declare_rustdoc_lint {
+    ($(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)?) => {
+        declare_tool_lint! {
+            $(#[$attr])* pub rustdoc::$name, $level, $descr
+        }
+    }
+}
+
+declare_rustdoc_lint! {
+    /// The `broken_intra_doc_links` lint detects failures in resolving
+    /// intra-doc link targets. This is a `rustdoc` only lint, see the
+    /// documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#broken_intra_doc_links
+    BROKEN_INTRA_DOC_LINKS,
+    Warn,
+    "failures in resolving intra-doc link targets"
+}
+
+declare_rustdoc_lint! {
+    /// This is a subset of `broken_intra_doc_links` that warns when linking from
+    /// a public item to a private one. This is a `rustdoc` only lint, see the
+    /// documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#private_intra_doc_links
+    PRIVATE_INTRA_DOC_LINKS,
+    Warn,
+    "linking from a public item to a private one"
+}
+
+declare_rustdoc_lint! {
+    /// The `invalid_codeblock_attributes` lint detects code block attributes
+    /// in documentation examples that have potentially mis-typed values. This
+    /// is a `rustdoc` only lint, see the documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#invalid_codeblock_attributes
+    INVALID_CODEBLOCK_ATTRIBUTES,
+    Warn,
+    "codeblock attribute looks a lot like a known one"
+}
+
+declare_rustdoc_lint! {
+    /// The `missing_crate_level_docs` lint detects if documentation is
+    /// missing at the crate root. This is a `rustdoc` only lint, see the
+    /// documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#missing_crate_level_docs
+    MISSING_CRATE_LEVEL_DOCS,
+    Allow,
+    "detects crates with no crate-level documentation"
+}
+
+declare_rustdoc_lint! {
+    /// The `missing_doc_code_examples` lint detects publicly-exported items
+    /// without code samples in their documentation. This is a `rustdoc` only
+    /// lint, see the documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples
+    MISSING_DOC_CODE_EXAMPLES,
+    Allow,
+    "detects publicly-exported items without code samples in their documentation"
+}
+
+declare_rustdoc_lint! {
+    /// The `private_doc_tests` lint detects code samples in docs of private
+    /// items not documented by `rustdoc`. This is a `rustdoc` only lint, see
+    /// the documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#private_doc_tests
+    PRIVATE_DOC_TESTS,
+    Allow,
+    "detects code samples in docs of private items not documented by rustdoc"
+}
+
+declare_rustdoc_lint! {
+    /// The `invalid_html_tags` lint detects invalid HTML tags. This is a
+    /// `rustdoc` only lint, see the documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#invalid_html_tags
+    INVALID_HTML_TAGS,
+    Allow,
+    "detects invalid HTML tags in doc comments"
+}
+
+declare_rustdoc_lint! {
+    /// The `non_autolinks` lint detects when a URL could be written using
+    /// only angle brackets. This is a `rustdoc` only lint, see the
+    /// documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#non_autolinks
+    NON_AUTOLINKS,
+    Warn,
+    "detects URLs that could be written using only angle brackets"
+}
+
+crate static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
+    vec![
+        BROKEN_INTRA_DOC_LINKS,
+        PRIVATE_INTRA_DOC_LINKS,
+        MISSING_DOC_CODE_EXAMPLES,
+        PRIVATE_DOC_TESTS,
+        INVALID_CODEBLOCK_ATTRIBUTES,
+        INVALID_HTML_TAGS,
+        NON_AUTOLINKS,
+        MISSING_CRATE_LEVEL_DOCS,
+    ]
+});
+
+crate fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
+    lint_store.register_lints(&**RUSTDOC_LINTS);
+    lint_store.register_group(
+        true,
+        "rustdoc",
+        None,
+        RUSTDOC_LINTS.iter().map(|&lint| LintId::of(lint)).collect(),
+    );
+    for lint in &*RUSTDOC_LINTS {
+        let name = lint.name_lower();
+        lint_store.register_renamed(&name.replace("rustdoc::", ""), &name);
+    }
+    lint_store
+        .register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links");
+}
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c047f8729ad..38efecb393b 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -16,10 +16,7 @@ use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_middle::ty::TyCtxt;
 use rustc_middle::{bug, ty};
 use rustc_resolve::ParentScope;
-use rustc_session::lint::{
-    builtin::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS},
-    Lint,
-};
+use rustc_session::lint::Lint;
 use rustc_span::hygiene::{MacroKind, SyntaxContext};
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::DUMMY_SP;
@@ -37,6 +34,7 @@ use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLin
 use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::html::markdown::{markdown_links, MarkdownLink};
+use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
 use crate::passes::Pass;
 
 use super::span_of_attrs;
diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs
index 3b1508c1348..81104236314 100644
--- a/src/librustdoc/passes/doc_test_lints.rs
+++ b/src/librustdoc/passes/doc_test_lints.rs
@@ -68,8 +68,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
         return false;
     }
     let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local());
-    let (level, source) =
-        cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id);
+    let (level, source) = cx.tcx.lint_level_at_node(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id);
     level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
 }
 
@@ -91,7 +90,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
             debug!("reporting error for {:?} (hir_id={:?})", item, hir_id);
             let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
             cx.tcx.struct_span_lint_hir(
-                lint::builtin::MISSING_DOC_CODE_EXAMPLES,
+                crate::lint::MISSING_DOC_CODE_EXAMPLES,
                 hir_id,
                 sp,
                 |lint| lint.build("missing code example in this documentation").emit(),
@@ -99,7 +98,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
         }
     } else if tests.found_tests > 0 && !cx.cache.access_levels.is_public(item.def_id) {
         cx.tcx.struct_span_lint_hir(
-            lint::builtin::PRIVATE_DOC_TESTS,
+            crate::lint::PRIVATE_DOC_TESTS,
             hir_id,
             span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
             |lint| lint.build("documentation test in private item").emit(),
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index a6fe7e228d7..27e669aa44f 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -5,7 +5,6 @@ use crate::fold::DocFolder;
 use crate::html::markdown::opts;
 use core::ops::Range;
 use pulldown_cmark::{Event, Parser, Tag};
-use rustc_session::lint;
 use std::iter::Peekable;
 use std::str::CharIndices;
 
@@ -183,7 +182,7 @@ impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> {
                     Some(sp) => sp,
                     None => span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
                 };
-                cx.tcx.struct_span_lint_hir(lint::builtin::INVALID_HTML_TAGS, hir_id, sp, |lint| {
+                cx.tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
                     lint.build(msg).emit()
                 });
             };
diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs
index 9d4539a9769..09a1959fa11 100644
--- a/src/librustdoc/passes/non_autolinks.rs
+++ b/src/librustdoc/passes/non_autolinks.rs
@@ -7,7 +7,6 @@ use core::ops::Range;
 use pulldown_cmark::{Event, LinkType, Parser, Tag};
 use regex::Regex;
 use rustc_errors::Applicability;
-use rustc_session::lint;
 
 crate const CHECK_NON_AUTOLINKS: Pass = Pass {
     name: "check-non-autolinks",
@@ -74,7 +73,7 @@ impl<'a, 'tcx> DocFolder for NonAutolinksLinter<'a, 'tcx> {
                 let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs)
                     .or_else(|| span_of_attrs(&item.attrs))
                     .unwrap_or(item.source.span());
-                cx.tcx.struct_span_lint_hir(lint::builtin::NON_AUTOLINKS, hir_id, sp, |lint| {
+                cx.tcx.struct_span_lint_hir(crate::lint::NON_AUTOLINKS, hir_id, sp, |lint| {
                     lint.build(msg)
                         .span_suggestion(
                             sp,
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 96ae8953e4938d39c4173dd189f268459fff8c0
+Subproject 40618a2340ac2939b3dc320a9fe1133fa5caa34
diff --git a/src/test/assembly/asm/riscv-types.rs b/src/test/assembly/asm/riscv-types.rs
index 67dda1024fc..47518cdcf16 100644
--- a/src/test/assembly/asm/riscv-types.rs
+++ b/src/test/assembly/asm/riscv-types.rs
@@ -5,6 +5,7 @@
 //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf
 // compile-flags: -C target-feature=+d
 // needs-llvm-components: riscv
+// min-system-llvm-version: 12.0
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
@@ -99,45 +100,45 @@ macro_rules! check_reg {
 
 // CHECK-LABEL: reg_i8:
 // CHECK: #APP
-// CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // CHECK: #NO_APP
 check!(reg_i8 i8 reg "mv");
 
 // CHECK-LABEL: reg_i16:
 // CHECK: #APP
-// CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // CHECK: #NO_APP
 check!(reg_i16 i16 reg "mv");
 
 // CHECK-LABEL: reg_i32:
 // CHECK: #APP
-// CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // CHECK: #NO_APP
 check!(reg_i32 i32 reg "mv");
 
 // CHECK-LABEL: reg_f32:
 // CHECK: #APP
-// CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // CHECK: #NO_APP
 check!(reg_f32 f32 reg "mv");
 
 // riscv64-LABEL: reg_i64:
 // riscv64: #APP
-// riscv64: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // riscv64: #NO_APP
 #[cfg(riscv64)]
 check!(reg_i64 i64 reg "mv");
 
 // riscv64-LABEL: reg_f64:
 // riscv64: #APP
-// riscv64: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // riscv64: #NO_APP
 #[cfg(riscv64)]
 check!(reg_f64 f64 reg "mv");
 
 // CHECK-LABEL: reg_ptr:
 // CHECK: #APP
-// CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
+// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
 // CHECK: #NO_APP
 check!(reg_ptr ptr reg "mv");
 
@@ -155,45 +156,45 @@ check!(freg_f64 f64 freg "fmv.d");
 
 // CHECK-LABEL: a0_i8:
 // CHECK: #APP
-// CHECK: add a0, zero, a0
+// CHECK: mv a0, a0
 // CHECK: #NO_APP
 check_reg!(a0_i8 i8 "a0" "mv");
 
 // CHECK-LABEL: a0_i16:
 // CHECK: #APP
-// CHECK: add a0, zero, a0
+// CHECK: mv a0, a0
 // CHECK: #NO_APP
 check_reg!(a0_i16 i16 "a0" "mv");
 
 // CHECK-LABEL: a0_i32:
 // CHECK: #APP
-// CHECK: add a0, zero, a0
+// CHECK: mv a0, a0
 // CHECK: #NO_APP
 check_reg!(a0_i32 i32 "a0" "mv");
 
 // CHECK-LABEL: a0_f32:
 // CHECK: #APP
-// CHECK: add a0, zero, a0
+// CHECK: mv a0, a0
 // CHECK: #NO_APP
 check_reg!(a0_f32 f32 "a0" "mv");
 
 // riscv64-LABEL: a0_i64:
 // riscv64: #APP
-// riscv64: add a0, zero, a0
+// riscv64: mv a0, a0
 // riscv64: #NO_APP
 #[cfg(riscv64)]
 check_reg!(a0_i64 i64 "a0" "mv");
 
 // riscv64-LABEL: a0_f64:
 // riscv64: #APP
-// riscv64: add a0, zero, a0
+// riscv64: mv a0, a0
 // riscv64: #NO_APP
 #[cfg(riscv64)]
 check_reg!(a0_f64 f64 "a0" "mv");
 
 // CHECK-LABEL: a0_ptr:
 // CHECK: #APP
-// CHECK: add a0, zero, a0
+// CHECK: mv a0, a0
 // CHECK: #NO_APP
 check_reg!(a0_ptr ptr "a0" "mv");
 
diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs
index 3511c7c5185..a1da4faf5d8 100644
--- a/src/test/codegen/function-arguments.rs
+++ b/src/test/codegen/function-arguments.rs
@@ -1,5 +1,6 @@
 // compile-flags: -C no-prepopulate-passes
 // ignore-tidy-linelength
+// min-system-llvm-version: 12.0
 
 #![crate_type = "lib"]
 #![feature(rustc_attrs)]
@@ -73,7 +74,7 @@ pub fn _box(x: Box<i32>) -> Box<i32> {
   x
 }
 
-// CHECK: @struct_return(%S* noalias nocapture sret dereferenceable(32){{( %0)?}})
+// CHECK: @struct_return(%S* noalias nocapture sret(%S) dereferenceable(32){{( %0)?}})
 #[no_mangle]
 pub fn struct_return() -> S {
   S {
diff --git a/src/test/codegen/packed.rs b/src/test/codegen/packed.rs
index f3f5202206c..c31e8457dcd 100644
--- a/src/test/codegen/packed.rs
+++ b/src/test/codegen/packed.rs
@@ -52,7 +52,7 @@ pub struct BigPacked2 {
 #[no_mangle]
 pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
-// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
+// CHECK: call void %{{.*}}(%Array* noalias nocapture sret{{.*}} dereferenceable(32) [[ALLOCA]])
 // CHECK: call void @llvm.memcpy.{{.*}}(i8* align 1 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
@@ -64,7 +64,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
 #[no_mangle]
 pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
-// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
+// CHECK: call void %{{.*}}(%Array* noalias nocapture sret{{.*}} dereferenceable(32) [[ALLOCA]])
 // CHECK: call void @llvm.memcpy.{{.*}}(i8* align 2 %{{.*}}, i8* align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
     // check that calls whose destination is a field of a packed struct
     // go through an alloca rather than calling the function with an
diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs
index 2b8d3c8bc1d..847b94fac78 100644
--- a/src/test/codegen/repr-transparent-aggregates-1.rs
+++ b/src/test/codegen/repr-transparent-aggregates-1.rs
@@ -1,7 +1,7 @@
 // compile-flags: -C no-prepopulate-passes
 // ignore-tidy-linelength
 
-// min-system-llvm-version: 9.0
+// min-system-llvm-version: 12.0
 // ignore-arm
 // ignore-aarch64
 // ignore-mips
@@ -34,19 +34,19 @@ pub enum TeBigS {
     Variant(BigS),
 }
 
-// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
+// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
 #[no_mangle]
 pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} }
 
-// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
+// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
 #[no_mangle]
 pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
+// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
 #[no_mangle]
 pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
+// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
 #[no_mangle]
 pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
@@ -70,18 +70,18 @@ pub enum TeBigU {
     Variant(BigU),
 }
 
-// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
+// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
 #[no_mangle]
 pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
+// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
 #[no_mangle]
 pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
 
-// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
+// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
 #[no_mangle]
 pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
 
-// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
+// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
 #[no_mangle]
 pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs
index 07e5af11f35..1fb12d92bd1 100644
--- a/src/test/codegen/repr-transparent-aggregates-2.rs
+++ b/src/test/codegen/repr-transparent-aggregates-2.rs
@@ -1,5 +1,7 @@
 // compile-flags: -C no-prepopulate-passes
+// ignore-tidy-linelength
 
+// min-system-llvm-version: 12.0
 // ignore-aarch64
 // ignore-emscripten
 // ignore-mips64
@@ -36,19 +38,19 @@ pub enum TeBigS {
     Variant(BigS),
 }
 
-// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [16 x i32]
+// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
 #[no_mangle]
 pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
 
-// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
@@ -72,18 +74,18 @@ pub enum TeBigU {
     Variant(BigU),
 }
 
-// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
+// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
 #[no_mangle]
 pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
+// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
 
-// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
 
-// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
 #[no_mangle]
 pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs
index e538be68780..3381764bfc8 100644
--- a/src/test/codegen/repr-transparent-aggregates-3.rs
+++ b/src/test/codegen/repr-transparent-aggregates-3.rs
@@ -1,5 +1,7 @@
 // compile-flags: -C no-prepopulate-passes
+// ignore-tidy-linelength
 
+// min-system-llvm-version: 12.0
 // only-mips64
 // See repr-transparent.rs
 
@@ -25,19 +27,19 @@ pub enum TeBigS {
     Variant(BigS),
 }
 
-// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [8 x i64]
+// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [8 x i64]
 #[no_mangle]
 pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
 
-// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [8 x i64]
 #[no_mangle]
 pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [8 x i64]
 #[no_mangle]
 pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [8 x i64]
 #[no_mangle]
 pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
@@ -61,18 +63,18 @@ pub enum TeBigU {
     Variant(BigU),
 }
 
-// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
+// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [8 x i64]
 #[no_mangle]
 pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
+// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [8 x i64]
 #[no_mangle]
 pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
 
-// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [8 x i64]
 #[no_mangle]
 pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
 
-// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [8 x i64]
 #[no_mangle]
 pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/run-make-fulldeps/pgo-use/Makefile b/src/test/run-make-fulldeps/pgo-use/Makefile
index cb5e9e9a455..01bc211df16 100644
--- a/src/test/run-make-fulldeps/pgo-use/Makefile
+++ b/src/test/run-make-fulldeps/pgo-use/Makefile
@@ -12,12 +12,11 @@
 # `else` branch. Accordingly, we expect the function that is never called to
 # be marked as cold.
 #
-# The program is compiled with `-Copt-level=s` because this setting disables
-# LLVM's pre-inlining pass (i.e. a pass that does some inlining before it adds
-# the profiling instrumentation). Disabling this pass leads to rather
-# predictable IR which we need for this test to be stable.
+# Disable the pre-inlining pass (i.e. a pass that does some inlining before
+# it adds the profiling instrumentation). Disabling this pass leads to
+# rather predictable IR which we need for this test to be stable.
 
-COMMON_FLAGS=-Copt-level=s -Ccodegen-units=1
+COMMON_FLAGS=-Copt-level=2 -Ccodegen-units=1 -Cllvm-args=-disable-preinline
 
 # LLVM doesn't support instrumenting binaries that use SEH:
 # https://github.com/rust-lang/rust/issues/61002
diff --git a/src/test/run-make-fulldeps/split-dwarf/Makefile b/src/test/run-make-fulldeps/split-dwarf/Makefile
index e89cc1b2ede..f56b4168b2d 100644
--- a/src/test/run-make-fulldeps/split-dwarf/Makefile
+++ b/src/test/run-make-fulldeps/split-dwarf/Makefile
@@ -4,6 +4,6 @@
 # min-llvm-version: 11.0
 
 all:
-	$(RUSTC) -Z unstable-options -C split-debuginfo=packed foo.rs -g
+	$(RUSTC) -Z unstable-options -C split-debuginfo=packed -C debuginfo=2 foo.rs -g
 	rm $(TMPDIR)/foo.dwp
 	rm $(TMPDIR)/$(call BIN,foo)
diff --git a/src/test/rustdoc-ui/assoc-item-not-in-scope.rs b/src/test/rustdoc-ui/assoc-item-not-in-scope.rs
index c5bb4305db7..0976515f4a4 100644
--- a/src/test/rustdoc-ui/assoc-item-not-in-scope.rs
+++ b/src/test/rustdoc-ui/assoc-item-not-in-scope.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 #[derive(Debug)]
 /// Link to [`S::fmt`]
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 92d27179e8c..358871b5323 100644
--- a/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr
+++ b/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr
@@ -7,8 +7,8 @@ LL | /// Link to [`S::fmt`]
 note: the lint level is defined here
   --> $DIR/assoc-item-not-in-scope.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/check-attr-test.rs b/src/test/rustdoc-ui/check-attr-test.rs
index 665f330e34e..023d620bea2 100644
--- a/src/test/rustdoc-ui/check-attr-test.rs
+++ b/src/test/rustdoc-ui/check-attr-test.rs
@@ -1,6 +1,6 @@
 // compile-flags:--test
 
-#![deny(invalid_codeblock_attributes)]
+#![deny(rustdoc::invalid_codeblock_attributes)]
 
 /// foo
 ///
diff --git a/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr
index 1e067a5d21c..affd0372a1f 100644
--- a/src/test/rustdoc-ui/check-attr-test.stderr
+++ b/src/test/rustdoc-ui/check-attr-test.stderr
@@ -11,8 +11,8 @@ error: unknown attribute `compile-fail`. Did you mean `compile_fail`?
 note: the lint level is defined here
  --> $DIR/check-attr-test.rs:3:9
   |
-3 | #![deny(invalid_codeblock_attributes)]
-  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+3 | #![deny(rustdoc::invalid_codeblock_attributes)]
+  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
 error: unknown attribute `compilefail`. Did you mean `compile_fail`?
diff --git a/src/test/rustdoc-ui/check-attr.rs b/src/test/rustdoc-ui/check-attr.rs
index 9e02eab753e..763bc4c6cdd 100644
--- a/src/test/rustdoc-ui/check-attr.rs
+++ b/src/test/rustdoc-ui/check-attr.rs
@@ -1,4 +1,4 @@
-#![deny(invalid_codeblock_attributes)]
+#![deny(rustdoc::invalid_codeblock_attributes)]
 
 /// foo
 //~^ ERROR
diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr
index 919eb047eef..9312cfb76f3 100644
--- a/src/test/rustdoc-ui/check-attr.stderr
+++ b/src/test/rustdoc-ui/check-attr.stderr
@@ -13,8 +13,8 @@ LL | | /// ```
 note: the lint level is defined here
   --> $DIR/check-attr.rs:1:9
    |
-LL | #![deny(invalid_codeblock_attributes)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::invalid_codeblock_attributes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
 error: unknown attribute `compilefail`. Did you mean `compile_fail`?
diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr
index b4f255642da..9f5ccbc6687 100644
--- a/src/test/rustdoc-ui/check-fail.stderr
+++ b/src/test/rustdoc-ui/check-fail.stderr
@@ -21,7 +21,7 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
-   = note: `#[deny(missing_doc_code_examples)]` implied by `#[deny(rustdoc)]`
+   = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc)]`
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
   --> $DIR/check-fail.rs:6:1
@@ -37,7 +37,7 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
-   = note: `#[deny(invalid_codeblock_attributes)]` implied by `#[deny(rustdoc)]`
+   = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc)]`
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr
index 27e5a736148..e6ba9df9b05 100644
--- a/src/test/rustdoc-ui/check.stderr
+++ b/src/test/rustdoc-ui/check.stderr
@@ -21,6 +21,17 @@ warning: missing documentation for a function
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^
 
+warning: no documentation found for this crate's top-level module
+   |
+note: the lint level is defined here
+  --> $DIR/check.rs:7:9
+   |
+LL | #![warn(rustdoc)]
+   |         ^^^^^^^
+   = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc)]`
+   = help: The following guide may be of use:
+           https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html
+
 warning: missing code example in this documentation
   --> $DIR/check.rs:4:1
    |
@@ -37,7 +48,7 @@ note: the lint level is defined here
    |
 LL | #![warn(rustdoc)]
    |         ^^^^^^^
-   = note: `#[warn(missing_doc_code_examples)]` implied by `#[warn(rustdoc)]`
+   = note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc)]`
 
 warning: missing code example in this documentation
   --> $DIR/check.rs:9:1
@@ -45,5 +56,5 @@ warning: missing code example in this documentation
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^^^^
 
-warning: 4 warnings emitted
+warning: 5 warnings emitted
 
diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs
index 54e7689f316..09da124b162 100644
--- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 /// [v2] //~ ERROR
 pub fn foo() {}
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 9ec9dd4bc9a..67d9c3989f5 100644
--- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
@@ -7,8 +7,8 @@ LL | /// [v2]
 note: the lint level is defined here
   --> $DIR/deny-intra-link-resolution-failure.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::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/doc-attr.rs b/src/test/rustdoc-ui/doc-attr.rs
index 37c69a214b8..3519b5707b3 100644
--- a/src/test/rustdoc-ui/doc-attr.rs
+++ b/src/test/rustdoc-ui/doc-attr.rs
@@ -1,5 +1,11 @@
 #![crate_type = "lib"]
-#![doc(as_ptr)] //~ ERROR
+#![deny(unused_attributes)]
+//~^ NOTE lint level is defined here
+#![doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~| WARNING will become a hard error in a future release
 
-#[doc(as_ptr)] //~ ERROR
+#[doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~| WARNING will become a hard error in a future release
 pub fn foo() {}
diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr
index 17bc3d6a45a..9666db2b10e 100644
--- a/src/test/rustdoc-ui/doc-attr.stderr
+++ b/src/test/rustdoc-ui/doc-attr.stderr
@@ -1,14 +1,23 @@
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:4:7
+  --> $DIR/doc-attr.rs:8:7
    |
 LL | #[doc(as_ptr)]
    |       ^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/doc-attr.rs:2:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:2:8
+  --> $DIR/doc-attr.rs:4:8
    |
 LL | #![doc(as_ptr)]
    |        ^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.rs b/src/test/rustdoc-ui/doc-without-codeblock.rs
index 5ad8e8a826f..6812a454157 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.rs
+++ b/src/test/rustdoc-ui/doc-without-codeblock.rs
@@ -1,4 +1,4 @@
-#![deny(missing_doc_code_examples)] //~ ERROR missing code example in this documentation
+#![deny(rustdoc::missing_doc_code_examples)] //~ ERROR missing code example in this documentation
 
 /// Some docs.
 //~^ ERROR missing code example in this documentation
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr
index 3372304f44a..aac537e9783 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.stderr
+++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr
@@ -1,7 +1,7 @@
 error: missing code example in this documentation
   --> $DIR/doc-without-codeblock.rs:1:1
    |
-LL | / #![deny(missing_doc_code_examples)]
+LL | / #![deny(rustdoc::missing_doc_code_examples)]
 LL | |
 LL | | /// Some docs.
 LL | |
@@ -13,8 +13,8 @@ LL | | }
 note: the lint level is defined here
   --> $DIR/doc-without-codeblock.rs:1:9
    |
-LL | #![deny(missing_doc_code_examples)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing code example in this documentation
   --> $DIR/doc-without-codeblock.rs:7:1
diff --git a/src/test/rustdoc-ui/intra-doc/alias-ice.rs b/src/test/rustdoc-ui/intra-doc/alias-ice.rs
index c053e378e71..51922caeb25 100644
--- a/src/test/rustdoc-ui/intra-doc/alias-ice.rs
+++ b/src/test/rustdoc-ui/intra-doc/alias-ice.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 pub type TypeAlias = usize;
 
diff --git a/src/test/rustdoc-ui/intra-doc/alias-ice.stderr b/src/test/rustdoc-ui/intra-doc/alias-ice.stderr
index 3db5fad4cfb..5e7ffeeb8a2 100644
--- a/src/test/rustdoc-ui/intra-doc/alias-ice.stderr
+++ b/src/test/rustdoc-ui/intra-doc/alias-ice.stderr
@@ -7,8 +7,8 @@ LL | /// [broken cross-reference](TypeAlias::hoge)
 note: the lint level is defined here
   --> $DIR/alias-ice.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-doc/ambiguity.rs b/src/test/rustdoc-ui/intra-doc/ambiguity.rs
index f63435337cf..1f3dc722eff 100644
--- a/src/test/rustdoc-ui/intra-doc/ambiguity.rs
+++ b/src/test/rustdoc-ui/intra-doc/ambiguity.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/rustdoc-ui/intra-doc/ambiguity.stderr b/src/test/rustdoc-ui/intra-doc/ambiguity.stderr
index 7e967dc88bc..0f23b9b8adf 100644
--- a/src/test/rustdoc-ui/intra-doc/ambiguity.stderr
+++ b/src/test/rustdoc-ui/intra-doc/ambiguity.stderr
@@ -7,8 +7,8 @@ LL | /// [true]
 note: the lint level is defined here
   --> $DIR/ambiguity.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: to link to the module, prefix with `mod@`
    |
 LL | /// [mod@true]
diff --git a/src/test/rustdoc-ui/intra-doc/anchors.rs b/src/test/rustdoc-ui/intra-doc/anchors.rs
index ccefd2e6fab..009b291be1f 100644
--- a/src/test/rustdoc-ui/intra-doc/anchors.rs
+++ b/src/test/rustdoc-ui/intra-doc/anchors.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 // A few tests on anchors.
 
diff --git a/src/test/rustdoc-ui/intra-doc/anchors.stderr b/src/test/rustdoc-ui/intra-doc/anchors.stderr
index 5b272d960d5..97b0cea0c1e 100644
--- a/src/test/rustdoc-ui/intra-doc/anchors.stderr
+++ b/src/test/rustdoc-ui/intra-doc/anchors.stderr
@@ -7,8 +7,8 @@ LL | /// Or maybe [Foo::f#hola].
 note: the lint level is defined here
   --> $DIR/anchors.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `hello#people#!` contains multiple anchors
   --> $DIR/anchors.rs:31:28
diff --git a/src/test/rustdoc-ui/intra-doc/broken-reexport.rs b/src/test/rustdoc-ui/intra-doc/broken-reexport.rs
index ef261359ebd..862faa50b4d 100644
--- a/src/test/rustdoc-ui/intra-doc/broken-reexport.rs
+++ b/src/test/rustdoc-ui/intra-doc/broken-reexport.rs
@@ -1,7 +1,7 @@
 // aux-build:intra-doc-broken.rs
 // check-pass
 
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 extern crate intra_doc_broken;
 
diff --git a/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs
index b9c8e033b1b..596623190a3 100644
--- a/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs
+++ b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 //~^ NOTE lint level is defined
 pub enum S {}
 
diff --git a/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr
index 2f5f3daa297..5d4d4a699e4 100644
--- a/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr
+++ b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr
@@ -7,8 +7,8 @@ LL | /// Link to [struct@S]
 note: the lint level is defined here
   --> $DIR/disambiguator-mismatch.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this link resolved to an enum, which is not a struct
 
 error: incompatible link kind for `S`
diff --git a/src/test/rustdoc-ui/intra-doc/double-anchor.stderr b/src/test/rustdoc-ui/intra-doc/double-anchor.stderr
index 1cd9231eded..c0241b98b78 100644
--- a/src/test/rustdoc-ui/intra-doc/double-anchor.stderr
+++ b/src/test/rustdoc-ui/intra-doc/double-anchor.stderr
@@ -4,7 +4,7 @@ warning: `with#anchor#error` contains multiple anchors
 LL | /// docs [label][with#anchor#error]
    |                  ^^^^^^^^^^^^^^^^^ contains invalid anchor
    |
-   = note: `#[warn(broken_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
 
 warning: 1 warning emitted
 
diff --git a/src/test/rustdoc-ui/intra-doc/errors.rs b/src/test/rustdoc-ui/intra-doc/errors.rs
index 81e42643ae8..b29f7c29b5d 100644
--- a/src/test/rustdoc-ui/intra-doc/errors.rs
+++ b/src/test/rustdoc-ui/intra-doc/errors.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 //~^ NOTE lint level is defined
 
 // FIXME: this should say that it was skipped (maybe an allowed by default lint?)
diff --git a/src/test/rustdoc-ui/intra-doc/errors.stderr b/src/test/rustdoc-ui/intra-doc/errors.stderr
index 21c806108e3..06115172057 100644
--- a/src/test/rustdoc-ui/intra-doc/errors.stderr
+++ b/src/test/rustdoc-ui/intra-doc/errors.stderr
@@ -7,8 +7,8 @@ LL | /// [path::to::nonexistent::module]
 note: the lint level is defined here
   --> $DIR/errors.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unresolved link to `path::to::nonexistent::macro`
   --> $DIR/errors.rs:11:6
diff --git a/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs
index 0d1d5d1134b..3088bcd4653 100644
--- a/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs
+++ b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs
@@ -1,3 +1,3 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 //! [static@u8::MIN]
 //~^ ERROR incompatible link kind
diff --git a/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr
index ed1c10f9e0c..d4dcc493c8b 100644
--- a/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr
+++ b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr
@@ -7,8 +7,8 @@ LL | //! [static@u8::MIN]
 note: the lint level is defined here
   --> $DIR/incompatible-primitive-disambiguator.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this link resolved to an associated constant, which is not a static
 
 error: aborting due to previous error
diff --git a/src/test/rustdoc-ui/intra-doc/malformed-generics.rs b/src/test/rustdoc-ui/intra-doc/malformed-generics.rs
index 9c54092146f..15e02925ed9 100644
--- a/src/test/rustdoc-ui/intra-doc/malformed-generics.rs
+++ b/src/test/rustdoc-ui/intra-doc/malformed-generics.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 //! [Vec<] //~ ERROR
 //! [Vec<Box<T] //~ ERROR
diff --git a/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr b/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr
index 2e1b22807bc..5bc0f84e24d 100644
--- a/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr
+++ b/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr
@@ -7,8 +7,8 @@ LL | //! [Vec<]
 note: the lint level is defined here
   --> $DIR/malformed-generics.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unresolved link to `Vec<Box<T`
   --> $DIR/malformed-generics.rs:4:6
diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs
index 6785c4c43f5..75159979e88 100644
--- a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs
+++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 #![feature(intra_doc_pointers)]
 // These are links that could reasonably expected to work, but don't.
 
diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
index 174758504ae..610c8305605 100644
--- a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
+++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
@@ -7,8 +7,8 @@ LL | //! [[T]::rotate_left]
 note: the lint level is defined here
   --> $DIR/non-path-primitives.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unresolved link to `Z`
diff --git a/src/test/rustdoc-ui/intra-doc/prim-conflict.rs b/src/test/rustdoc-ui/intra-doc/prim-conflict.rs
index 85738ceae8e..2c1a8b5357a 100644
--- a/src/test/rustdoc-ui/intra-doc/prim-conflict.rs
+++ b/src/test/rustdoc-ui/intra-doc/prim-conflict.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 //~^ NOTE lint level is defined
 
 /// [char]
diff --git a/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr b/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr
index 01275f8d9af..e4bd9fd4b8f 100644
--- a/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr
+++ b/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr
@@ -7,8 +7,8 @@ LL | /// [char]
 note: the lint level is defined here
   --> $DIR/prim-conflict.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: to link to the module, prefix with `mod@`
    |
 LL | /// [mod@char]
diff --git a/src/test/rustdoc-ui/intra-doc/private.private.stderr b/src/test/rustdoc-ui/intra-doc/private.private.stderr
index 94a833fcc1a..cae5b1f20e6 100644
--- a/src/test/rustdoc-ui/intra-doc/private.private.stderr
+++ b/src/test/rustdoc-ui/intra-doc/private.private.stderr
@@ -4,7 +4,7 @@ warning: public documentation for `DocMe` links to private item `DontDocMe`
 LL | /// docs [DontDocMe] [DontDocMe::f]
    |           ^^^^^^^^^ this item is private
    |
-   = note: `#[warn(private_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link resolves only because you passed `--document-private-items`, but will break without
 
 warning: public documentation for `DocMe` links to private item `DontDocMe::f`
diff --git a/src/test/rustdoc-ui/intra-doc/private.public.stderr b/src/test/rustdoc-ui/intra-doc/private.public.stderr
index 21a60638d5e..05b202e37fb 100644
--- a/src/test/rustdoc-ui/intra-doc/private.public.stderr
+++ b/src/test/rustdoc-ui/intra-doc/private.public.stderr
@@ -4,7 +4,7 @@ warning: public documentation for `DocMe` links to private item `DontDocMe`
 LL | /// docs [DontDocMe] [DontDocMe::f]
    |           ^^^^^^^^^ this item is private
    |
-   = note: `#[warn(private_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link will resolve properly if you pass `--document-private-items`
 
 warning: public documentation for `DocMe` links to private item `DontDocMe::f`
diff --git a/src/test/rustdoc-ui/intra-doc/span-ice-55723.rs b/src/test/rustdoc-ui/intra-doc/span-ice-55723.rs
index 7764a6df6ee..041ec293259 100644
--- a/src/test/rustdoc-ui/intra-doc/span-ice-55723.rs
+++ b/src/test/rustdoc-ui/intra-doc/span-ice-55723.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 // An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to
 // attempt to slice in the middle of a multibyte character. See
diff --git a/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr
index 10ca14e850f..bf4ab9fdd18 100644
--- a/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr
+++ b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr
@@ -7,8 +7,8 @@ LL | /// (arr[i])
 note: the lint level is defined here
   --> $DIR/span-ice-55723.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::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-doc/unused-extern-crate.rs b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.rs
index 186503cf69d..9565830930f 100644
--- a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.rs
+++ b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.rs
@@ -1,5 +1,5 @@
 // compile-flags: --extern zip=whatever.rlib
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 /// See [zip] crate.
 //~^ ERROR unresolved
 pub struct ArrayZip;
diff --git a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr
index b3b57fd1318..5c0df1d1b9e 100644
--- a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr
@@ -7,8 +7,8 @@ LL | /// See [zip] crate.
 note: the lint level is defined here
   --> $DIR/unused-extern-crate.rs:2:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::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-doc/warning-crlf.stderr b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr
index 01e42820037..d46df92649d 100644
--- a/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr
+++ b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr
@@ -4,7 +4,7 @@ warning: unresolved link to `error`
 LL | /// [error]
    |      ^^^^^ no item named `error` in scope
    |
-   = note: `#[warn(broken_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error1`
diff --git a/src/test/rustdoc-ui/intra-doc/warning.stderr b/src/test/rustdoc-ui/intra-doc/warning.stderr
index 430d18165a0..135c432e053 100644
--- a/src/test/rustdoc-ui/intra-doc/warning.stderr
+++ b/src/test/rustdoc-ui/intra-doc/warning.stderr
@@ -4,7 +4,7 @@ warning: unresolved link to `Foo::baz`
 LL |        //! Test with [Foo::baz], [Bar::foo], ...
    |                       ^^^^^^^^ the struct `Foo` has no field or associated item named `baz`
    |
-   = note: `#[warn(broken_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
 
 warning: unresolved link to `Bar::foo`
   --> $DIR/warning.rs:3:35
diff --git a/src/test/rustdoc-ui/invalid-html-tags.rs b/src/test/rustdoc-ui/invalid-html-tags.rs
index 9c2fc4beb5e..cec44b6d2ca 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.rs
+++ b/src/test/rustdoc-ui/invalid-html-tags.rs
@@ -1,4 +1,4 @@
-#![deny(invalid_html_tags)]
+#![deny(rustdoc::invalid_html_tags)]
 
 //! <p>💩<p>
 //~^ ERROR unclosed HTML tag `p`
diff --git a/src/test/rustdoc-ui/invalid-html-tags.stderr b/src/test/rustdoc-ui/invalid-html-tags.stderr
index aa9ace006bd..335e100c89d 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.stderr
+++ b/src/test/rustdoc-ui/invalid-html-tags.stderr
@@ -7,8 +7,8 @@ LL | //! <p>💩<p>
 note: the lint level is defined here
   --> $DIR/invalid-html-tags.rs:1:9
    |
-LL | #![deny(invalid_html_tags)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::invalid_html_tags)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unclosed HTML tag `p`
   --> $DIR/invalid-html-tags.rs:3:9
diff --git a/src/test/rustdoc-ui/issue-58473-2.rs b/src/test/rustdoc-ui/issue-58473-2.rs
index e5f3b4daf57..000b6a329c1 100644
--- a/src/test/rustdoc-ui/issue-58473-2.rs
+++ b/src/test/rustdoc-ui/issue-58473-2.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![deny(private_doc_tests)]
+#![deny(rustdoc::private_doc_tests)]
 
 mod foo {
     /**
diff --git a/src/test/rustdoc-ui/issue-74134.private.stderr b/src/test/rustdoc-ui/issue-74134.private.stderr
index b802d7e1252..457987e2074 100644
--- a/src/test/rustdoc-ui/issue-74134.private.stderr
+++ b/src/test/rustdoc-ui/issue-74134.private.stderr
@@ -4,7 +4,7 @@ warning: public documentation for `public_item` links to private item `PrivateTy
 LL |     /// [`PrivateType`]
    |          ^^^^^^^^^^^^^ this item is private
    |
-   = note: `#[warn(private_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link resolves only because you passed `--document-private-items`, but will break without
 
 warning: 1 warning emitted
diff --git a/src/test/rustdoc-ui/issue-74134.public.stderr b/src/test/rustdoc-ui/issue-74134.public.stderr
index 40aa2ece1a3..07aebc3541f 100644
--- a/src/test/rustdoc-ui/issue-74134.public.stderr
+++ b/src/test/rustdoc-ui/issue-74134.public.stderr
@@ -4,7 +4,7 @@ warning: public documentation for `public_item` links to private item `PrivateTy
 LL |     /// [`PrivateType`]
    |          ^^^^^^^^^^^^^ this item is private
    |
-   = note: `#[warn(private_intra_doc_links)]` on by default
+   = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default
    = note: this link will resolve properly if you pass `--document-private-items`
 
 warning: 1 warning emitted
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr
index 0c111a33b65..6f8a20f7d53 100644
--- a/src/test/rustdoc-ui/lint-group.stderr
+++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
-   = note: `#[deny(missing_doc_code_examples)]` implied by `#[deny(rustdoc)]`
+   = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc)]`
 
 error: documentation test in private item
   --> $DIR/lint-group.rs:19:1
@@ -26,7 +26,7 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
-   = note: `#[deny(private_doc_tests)]` implied by `#[deny(rustdoc)]`
+   = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc)]`
 
 error: missing code example in this documentation
   --> $DIR/lint-group.rs:26:1
@@ -45,7 +45,7 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
-   = note: `#[deny(broken_intra_doc_links)]` implied by `#[deny(rustdoc)]`
+   = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc)]`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unclosed HTML tag `unknown`
@@ -59,7 +59,7 @@ note: the lint level is defined here
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
-   = note: `#[deny(invalid_html_tags)]` implied by `#[deny(rustdoc)]`
+   = note: `#[deny(rustdoc::invalid_html_tags)]` implied by `#[deny(rustdoc)]`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
index ebe7a242211..8d727b0d0b5 100644
--- a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
@@ -1,5 +1,5 @@
 #![deny(missing_docs)]
-#![deny(missing_doc_code_examples)]
+#![deny(rustdoc::missing_doc_code_examples)]
 
 //! crate level doc
 //! ```
@@ -19,7 +19,7 @@ fn test() {
 mod module1 { //~ ERROR
 }
 
-#[allow(missing_doc_code_examples)]
+#[allow(rustdoc::missing_doc_code_examples)]
 /// doc
 mod module2 {
 
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
index e02ed4a056c..370c577f85d 100644
--- a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
@@ -8,8 +8,8 @@ LL | | }
 note: the lint level is defined here
   --> $DIR/lint-missing-doc-code-example.rs:2:9
    |
-LL | #![deny(missing_doc_code_examples)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing code example in this documentation
   --> $DIR/lint-missing-doc-code-example.rs:37:3
diff --git a/src/test/rustdoc-ui/no-crate-level-doc-lint.rs b/src/test/rustdoc-ui/no-crate-level-doc-lint.rs
index 152a7cd88bc..3939ec6827a 100644
--- a/src/test/rustdoc-ui/no-crate-level-doc-lint.rs
+++ b/src/test/rustdoc-ui/no-crate-level-doc-lint.rs
@@ -1,3 +1,5 @@
-#![deny(missing_crate_level_docs)]
+// error-pattern: no documentation found
+#![deny(rustdoc::missing_crate_level_docs)]
+//^~ NOTE defined here
 
 pub fn foo() {}
diff --git a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
index 6e7e2fb3eb7..55ead1a55cf 100644
--- a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
+++ b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
@@ -1,10 +1,10 @@
 error: no documentation found for this crate's top-level module
    |
 note: the lint level is defined here
-  --> $DIR/no-crate-level-doc-lint.rs:1:9
+  --> $DIR/no-crate-level-doc-lint.rs:2:9
    |
-LL | #![deny(missing_crate_level_docs)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::missing_crate_level_docs)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: The following guide may be of use:
            https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html
 
diff --git a/src/test/rustdoc-ui/private-doc-test.rs b/src/test/rustdoc-ui/private-doc-test.rs
index 379fa45f9fa..a1f9f8dca08 100644
--- a/src/test/rustdoc-ui/private-doc-test.rs
+++ b/src/test/rustdoc-ui/private-doc-test.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![deny(private_doc_tests)]
+#![deny(rustdoc::private_doc_tests)]
 
 mod foo {
     /// private doc test
diff --git a/src/test/rustdoc-ui/private-item-doc-test.rs b/src/test/rustdoc-ui/private-item-doc-test.rs
index 2f1bddc7c75..1a3d6cc636d 100644
--- a/src/test/rustdoc-ui/private-item-doc-test.rs
+++ b/src/test/rustdoc-ui/private-item-doc-test.rs
@@ -1,4 +1,4 @@
-#![deny(private_doc_tests)]
+#![deny(rustdoc::private_doc_tests)]
 
 mod foo {
     /// private doc test
diff --git a/src/test/rustdoc-ui/private-item-doc-test.stderr b/src/test/rustdoc-ui/private-item-doc-test.stderr
index 70b6638b237..5df6132987c 100644
--- a/src/test/rustdoc-ui/private-item-doc-test.stderr
+++ b/src/test/rustdoc-ui/private-item-doc-test.stderr
@@ -11,8 +11,8 @@ LL | |     /// ```
 note: the lint level is defined here
   --> $DIR/private-item-doc-test.rs:1:9
    |
-LL | #![deny(private_doc_tests)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::private_doc_tests)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/pub-export-lint.rs b/src/test/rustdoc-ui/pub-export-lint.rs
index 3fd3f774009..f2e66b77bf3 100644
--- a/src/test/rustdoc-ui/pub-export-lint.rs
+++ b/src/test/rustdoc-ui/pub-export-lint.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 /// [aloha]
 //~^ ERROR unresolved link to `aloha`
diff --git a/src/test/rustdoc-ui/pub-export-lint.stderr b/src/test/rustdoc-ui/pub-export-lint.stderr
index c345def794c..c6be9c6a9f5 100644
--- a/src/test/rustdoc-ui/pub-export-lint.stderr
+++ b/src/test/rustdoc-ui/pub-export-lint.stderr
@@ -7,8 +7,8 @@ LL | /// [aloha]
 note: the lint level is defined here
   --> $DIR/pub-export-lint.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::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/reference-link-reports-error-once.rs b/src/test/rustdoc-ui/reference-link-reports-error-once.rs
index 7957ee373c4..71bd2c522ff 100644
--- a/src/test/rustdoc-ui/reference-link-reports-error-once.rs
+++ b/src/test/rustdoc-ui/reference-link-reports-error-once.rs
@@ -1,4 +1,4 @@
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 /// Links to [a] [link][a]
 /// And also a [third link][a]
diff --git a/src/test/rustdoc-ui/reference-link-reports-error-once.stderr b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr
index 218eb334a6f..b46a51e93fb 100644
--- a/src/test/rustdoc-ui/reference-link-reports-error-once.stderr
+++ b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr
@@ -7,8 +7,8 @@ LL | /// [a]: ref
 note: the lint level is defined here
   --> $DIR/reference-link-reports-error-once.rs:1:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unresolved link to `ref2`
diff --git a/src/test/rustdoc-ui/reference-links.rs b/src/test/rustdoc-ui/reference-links.rs
index 6e00b9f0fa1..e81e034465d 100644
--- a/src/test/rustdoc-ui/reference-links.rs
+++ b/src/test/rustdoc-ui/reference-links.rs
@@ -1,5 +1,5 @@
 // Test that errors point to the reference, not to the title text.
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 //! Links to [a] [link][a]
 //!
 //! [a]: std::process::Comman
diff --git a/src/test/rustdoc-ui/reference-links.stderr b/src/test/rustdoc-ui/reference-links.stderr
index 3df89df21b4..c98a2fd7ce6 100644
--- a/src/test/rustdoc-ui/reference-links.stderr
+++ b/src/test/rustdoc-ui/reference-links.stderr
@@ -7,8 +7,8 @@ LL | //! [a]: std::process::Comman
 note: the lint level is defined here
   --> $DIR/reference-links.rs:2:9
    |
-LL | #![deny(broken_intra_doc_links)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.rs b/src/test/rustdoc-ui/renamed-lint-still-applies.rs
new file mode 100644
index 00000000000..6d4bad16aad
--- /dev/null
+++ b/src/test/rustdoc-ui/renamed-lint-still-applies.rs
@@ -0,0 +1,5 @@
+// compile-args: --crate-type lib
+#![deny(broken_intra_doc_links)]
+//~^ WARNING renamed
+//! [x]
+//~^ ERROR unresolved link
diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
new file mode 100644
index 00000000000..e14cbfa1726
--- /dev/null
+++ b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
@@ -0,0 +1,23 @@
+warning: lint `broken_intra_doc_links` has been renamed to `rustdoc::broken_intra_doc_links`
+  --> $DIR/renamed-lint-still-applies.rs:2:9
+   |
+LL | #![deny(broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links`
+   |
+   = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+error: unresolved link to `x`
+  --> $DIR/renamed-lint-still-applies.rs:4:6
+   |
+LL | //! [x]
+   |      ^ no item named `x` in scope
+   |
+note: the lint level is defined here
+  --> $DIR/renamed-lint-still-applies.rs:2:9
+   |
+LL | #![deny(broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/rustdoc-ui/unknown-renamed-lints.rs b/src/test/rustdoc-ui/unknown-renamed-lints.rs
index 7faa82ea429..d2c78bc4774 100644
--- a/src/test/rustdoc-ui/unknown-renamed-lints.rs
+++ b/src/test/rustdoc-ui/unknown-renamed-lints.rs
@@ -4,5 +4,14 @@
 //~^ NOTE lint level is defined
 #![deny(x)]
 //~^ ERROR unknown lint
+#![deny(rustdoc::x)]
+//~^ ERROR unknown lint: `rustdoc::x`
 #![deny(intra_doc_link_resolution_failure)]
-//~^ ERROR lint `intra_doc_link_resolution_failure` has been renamed
+//~^ ERROR renamed to `rustdoc::broken_intra_doc_links`
+
+#![deny(non_autolinks)]
+//~^ ERROR renamed to `rustdoc::non_autolinks`
+
+// Explicitly don't try to handle this case, it was never valid
+#![deny(rustdoc::intra_doc_link_resolution_failure)]
+//~^ ERROR unknown lint
diff --git a/src/test/rustdoc-ui/unknown-renamed-lints.stderr b/src/test/rustdoc-ui/unknown-renamed-lints.stderr
index f0917f194bb..0f31673fb47 100644
--- a/src/test/rustdoc-ui/unknown-renamed-lints.stderr
+++ b/src/test/rustdoc-ui/unknown-renamed-lints.stderr
@@ -10,11 +10,17 @@ note: the lint level is defined here
 LL | #![deny(unknown_lints)]
    |         ^^^^^^^^^^^^^
 
-error: lint `intra_doc_link_resolution_failure` has been renamed to `broken_intra_doc_links`
+error: unknown lint: `rustdoc::x`
   --> $DIR/unknown-renamed-lints.rs:7:9
    |
+LL | #![deny(rustdoc::x)]
+   |         ^^^^^^^^^^
+
+error: lint `intra_doc_link_resolution_failure` has been renamed to `rustdoc::broken_intra_doc_links`
+  --> $DIR/unknown-renamed-lints.rs:9:9
+   |
 LL | #![deny(intra_doc_link_resolution_failure)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `broken_intra_doc_links`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links`
    |
 note: the lint level is defined here
   --> $DIR/unknown-renamed-lints.rs:3:9
@@ -22,7 +28,19 @@ note: the lint level is defined here
 LL | #![deny(renamed_and_removed_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: lint `non_autolinks` has been renamed to `rustdoc::non_autolinks`
+  --> $DIR/unknown-renamed-lints.rs:12:9
+   |
+LL | #![deny(non_autolinks)]
+   |         ^^^^^^^^^^^^^ help: use the new name: `rustdoc::non_autolinks`
+
+error: unknown lint: `rustdoc::intra_doc_link_resolution_failure`
+  --> $DIR/unknown-renamed-lints.rs:16:9
+   |
+LL | #![deny(rustdoc::intra_doc_link_resolution_failure)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: Compilation failed, aborting rustdoc
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/test/rustdoc-ui/url-improvements.rs b/src/test/rustdoc-ui/url-improvements.rs
index 8531583d38a..d0b43de2f0e 100644
--- a/src/test/rustdoc-ui/url-improvements.rs
+++ b/src/test/rustdoc-ui/url-improvements.rs
@@ -1,4 +1,4 @@
-#![deny(non_autolinks)]
+#![deny(rustdoc::non_autolinks)]
 
 /// [http://aa.com](http://aa.com)
 //~^ ERROR unneeded long form for URL
@@ -59,7 +59,7 @@ pub fn c() {}
 /// [should_not.lint](should_not.lint)
 pub fn everything_is_fine_here() {}
 
-#[allow(non_autolinks)]
+#[allow(rustdoc::non_autolinks)]
 pub mod foo {
     /// https://somewhere.com/a?hello=12&bye=11#xyz
     pub fn bar() {}
diff --git a/src/test/rustdoc-ui/url-improvements.stderr b/src/test/rustdoc-ui/url-improvements.stderr
index 70ad4b06a51..f377973656a 100644
--- a/src/test/rustdoc-ui/url-improvements.stderr
+++ b/src/test/rustdoc-ui/url-improvements.stderr
@@ -7,8 +7,8 @@ LL | /// [http://aa.com](http://aa.com)
 note: the lint level is defined here
   --> $DIR/url-improvements.rs:1:9
    |
-LL | #![deny(non_autolinks)]
-   |         ^^^^^^^^^^^^^
+LL | #![deny(rustdoc::non_autolinks)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: unneeded long form for URL
   --> $DIR/url-improvements.rs:5:5
diff --git a/src/test/rustdoc/extern-links.rs b/src/test/rustdoc/extern-links.rs
index 991f869138d..0383ccf7db6 100644
--- a/src/test/rustdoc/extern-links.rs
+++ b/src/test/rustdoc/extern-links.rs
@@ -3,7 +3,7 @@
 
 #![crate_name = "foo"]
 
-extern crate extern_links;
+pub extern crate extern_links;
 
 // @!has foo/index.html '//a' 'extern_links'
 #[doc(no_inline)]
diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs
index 48c667ef2d1..ffa02b0c635 100644
--- a/src/test/rustdoc/intra-doc/non-path-primitives.rs
+++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs
@@ -1,7 +1,7 @@
 // ignore-tidy-linelength
 #![crate_name = "foo"]
 #![feature(intra_doc_pointers)]
-#![deny(broken_intra_doc_links)]
+#![deny(rustdoc::broken_intra_doc_links)]
 
 // @has foo/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'slice::rotate_left'
 //! [slice::rotate_left]
diff --git a/src/test/rustdoc/issue-28927.rs b/src/test/rustdoc/issue-28927.rs
index 7b535f33bf7..38a520850b6 100644
--- a/src/test/rustdoc/issue-28927.rs
+++ b/src/test/rustdoc/issue-28927.rs
@@ -2,5 +2,5 @@
 // aux-build:issue-28927-1.rs
 // ignore-cross-compile
 
-extern crate issue_28927_1 as inner1;
+pub extern crate issue_28927_1 as inner1;
 pub use inner1 as foo;
diff --git a/src/test/ui/attributes/const-stability-on-macro.rs b/src/test/ui/attributes/const-stability-on-macro.rs
new file mode 100644
index 00000000000..3fc60f7ce48
--- /dev/null
+++ b/src/test/ui/attributes/const-stability-on-macro.rs
@@ -0,0 +1,13 @@
+#[rustc_const_stable(feature = "foo", since = "0")]
+//~^ ERROR macros cannot have const stability attributes
+macro_rules! foo {
+    () => {};
+}
+
+#[rustc_const_unstable(feature = "bar", issue="none")]
+//~^ ERROR macros cannot have const stability attributes
+macro_rules! bar {
+    () => {};
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/const-stability-on-macro.stderr b/src/test/ui/attributes/const-stability-on-macro.stderr
new file mode 100644
index 00000000000..ef24e44d190
--- /dev/null
+++ b/src/test/ui/attributes/const-stability-on-macro.stderr
@@ -0,0 +1,20 @@
+error: macros cannot have const stability attributes
+  --> $DIR/const-stability-on-macro.rs:1:1
+   |
+LL | #[rustc_const_stable(feature = "foo", since = "0")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
+LL |
+LL | macro_rules! foo {
+   | ---------------- const stability attribute affects this macro
+
+error: macros cannot have const stability attributes
+  --> $DIR/const-stability-on-macro.rs:7:1
+   |
+LL | #[rustc_const_unstable(feature = "bar", issue="none")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute
+LL |
+LL | macro_rules! bar {
+   | ---------------- const stability attribute affects this macro
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/attributes/doc-attr.rs b/src/test/ui/attributes/doc-attr.rs
index 37c69a214b8..3519b5707b3 100644
--- a/src/test/ui/attributes/doc-attr.rs
+++ b/src/test/ui/attributes/doc-attr.rs
@@ -1,5 +1,11 @@
 #![crate_type = "lib"]
-#![doc(as_ptr)] //~ ERROR
+#![deny(unused_attributes)]
+//~^ NOTE lint level is defined here
+#![doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~| WARNING will become a hard error in a future release
 
-#[doc(as_ptr)] //~ ERROR
+#[doc(as_ptr)]
+//~^ ERROR unknown `doc` attribute
+//~| WARNING will become a hard error in a future release
 pub fn foo() {}
diff --git a/src/test/ui/attributes/doc-attr.stderr b/src/test/ui/attributes/doc-attr.stderr
index 17bc3d6a45a..9666db2b10e 100644
--- a/src/test/ui/attributes/doc-attr.stderr
+++ b/src/test/ui/attributes/doc-attr.stderr
@@ -1,14 +1,23 @@
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:4:7
+  --> $DIR/doc-attr.rs:8:7
    |
 LL | #[doc(as_ptr)]
    |       ^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/doc-attr.rs:2:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: unknown `doc` attribute `as_ptr`
-  --> $DIR/doc-attr.rs:2:8
+  --> $DIR/doc-attr.rs:4:8
    |
 LL | #![doc(as_ptr)]
    |        ^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/deprecation/deprecation-in-staged-api.rs b/src/test/ui/deprecation/deprecation-in-staged-api.rs
index f667de83b56..910bfd1b5e4 100644
--- a/src/test/ui/deprecation/deprecation-in-staged-api.rs
+++ b/src/test/ui/deprecation/deprecation-in-staged-api.rs
@@ -1,8 +1,4 @@
-// #[deprecated] cannot be used in staged API
-
 #![feature(staged_api)]
-
 #![stable(feature = "stable_test_feature", since = "1.0.0")]
-
-#[deprecated]
-fn main() { } //~ ERROR `#[deprecated]` cannot be used in staged API
+#[deprecated] //~ ERROR `#[deprecated]` cannot be used in staged API
+fn main() {}
diff --git a/src/test/ui/deprecation/deprecation-in-staged-api.stderr b/src/test/ui/deprecation/deprecation-in-staged-api.stderr
index c6881d5a573..cf977fa4b7b 100644
--- a/src/test/ui/deprecation/deprecation-in-staged-api.stderr
+++ b/src/test/ui/deprecation/deprecation-in-staged-api.stderr
@@ -1,8 +1,10 @@
-error: `#[deprecated]` cannot be used in staged API; use `#[rustc_deprecated]` instead
-  --> $DIR/deprecation-in-staged-api.rs:8:1
+error: `#[deprecated]` cannot be used in staged API
+  --> $DIR/deprecation-in-staged-api.rs:3:1
    |
-LL | fn main() { }
-   | ^^^^^^^^^^^^^
+LL | #[deprecated]
+   | ^^^^^^^^^^^^^ use `#[rustc_deprecated]` instead
+LL | fn main() {}
+   | ------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-81584.fixed b/src/test/ui/issues/issue-81584.fixed
new file mode 100644
index 00000000000..1cad59f1062
--- /dev/null
+++ b/src/test/ui/issues/issue-81584.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+        let _ = vec![vec![0, 1], vec![2]]
+            .into_iter()
+            .map(|y| y.iter().map(|x| x + 1).collect::<Vec<_>>())
+                  //~^ ERROR cannot return value referencing function parameter `y`
+            .collect::<Vec<_>>();
+}
diff --git a/src/test/ui/issues/issue-81584.rs b/src/test/ui/issues/issue-81584.rs
new file mode 100644
index 00000000000..452288db08b
--- /dev/null
+++ b/src/test/ui/issues/issue-81584.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+        let _ = vec![vec![0, 1], vec![2]]
+            .into_iter()
+            .map(|y| y.iter().map(|x| x + 1))
+                  //~^ ERROR cannot return value referencing function parameter `y`
+            .collect::<Vec<_>>();
+}
diff --git a/src/test/ui/issues/issue-81584.stderr b/src/test/ui/issues/issue-81584.stderr
new file mode 100644
index 00000000000..d57f1b778df
--- /dev/null
+++ b/src/test/ui/issues/issue-81584.stderr
@@ -0,0 +1,14 @@
+error[E0515]: cannot return value referencing function parameter `y`
+  --> $DIR/issue-81584.rs:5:22
+   |
+LL |             .map(|y| y.iter().map(|x| x + 1))
+   |                      -^^^^^^^^^^^^^^^^^^^^^^
+   |                      |
+   |                      returns a value referencing data owned by the current function
+   |                      `y` is borrowed here
+   |
+   = help: use `.collect()` to allocate the iterator
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs b/src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs
new file mode 100644
index 00000000000..cc29f9de7fb
--- /dev/null
+++ b/src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs
@@ -0,0 +1,16 @@
+#[derive(Eq, PartialEq)]
+struct Test {
+    a: &'b str,
+    //~^ ERROR use of undeclared lifetime name `'b`
+    //~| ERROR use of undeclared lifetime name `'b`
+}
+
+trait T {
+    fn foo(&'static self) {}
+}
+
+impl T for Test {
+    fn foo(&'b self) {} //~ ERROR use of undeclared lifetime name `'b`
+}
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr b/src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr
new file mode 100644
index 00000000000..30142e24cd5
--- /dev/null
+++ b/src/test/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr
@@ -0,0 +1,40 @@
+error[E0261]: use of undeclared lifetime name `'b`
+  --> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:13:13
+   |
+LL |     fn foo(&'b self) {}
+   |             ^^ undeclared lifetime
+   |
+   = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
+help: consider introducing lifetime `'b` here
+   |
+LL | impl<'b> T for Test {
+   |     ^^^^
+help: consider introducing lifetime `'b` here
+   |
+LL |     fn foo<'b>(&'b self) {}
+   |           ^^^^
+
+error[E0261]: use of undeclared lifetime name `'b`
+  --> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
+   |
+LL | struct Test {
+   |            - help: consider introducing lifetime `'b` here: `<'b>`
+LL |     a: &'b str,
+   |         ^^ undeclared lifetime
+   |
+   = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
+
+error[E0261]: use of undeclared lifetime name `'b`
+  --> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
+   |
+LL | #[derive(Eq, PartialEq)]
+   |          -- lifetime `'b` is missing in item created through this procedural macro
+LL | struct Test {
+LL |     a: &'b str,
+   |         ^^ undeclared lifetime
+   |
+   = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/src/test/ui/lint/auxiliary/lint_stability_fields.rs b/src/test/ui/lint/auxiliary/lint_stability_fields.rs
index 0efe7686ef7..3cbb48c4a6b 100644
--- a/src/test/ui/lint/auxiliary/lint_stability_fields.rs
+++ b/src/test/ui/lint/auxiliary/lint_stability_fields.rs
@@ -3,20 +3,35 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stable {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub inherit: u8, // it's a lie (stable doesn't inherit)
+    pub inherit: u8,
     #[unstable(feature = "unstable_test_feature", issue = "none")]
     pub override1: u8,
     #[rustc_deprecated(since = "1.0.0", reason = "text")]
     #[unstable(feature = "unstable_test_feature", issue = "none")]
     pub override2: u8,
+    #[stable(feature = "rust2", since = "2.0.0")]
+    pub override3: u8,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8,
+pub struct Stable2(#[stable(feature = "rust2", since = "2.0.0")] pub u8,
                    #[unstable(feature = "unstable_test_feature", issue = "none")] pub u8,
                    #[unstable(feature = "unstable_test_feature", issue = "none")]
-                   #[rustc_deprecated(since = "1.0.0", reason = "text")] pub u8);
+                   #[rustc_deprecated(since = "1.0.0", reason = "text")] pub u8,
+                   pub u8);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Stable3 {
+    Inherit(u8),
+    InheritOverride(#[stable(feature = "rust2", since = "2.0.0")] u8),
+    #[stable(feature = "rust2", since = "2.0.0")]
+    Override1,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    Override2,
+    #[rustc_deprecated(since = "1.0.0", reason = "text")]
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    Override3,
+}
 
 #[unstable(feature = "unstable_test_feature", issue = "none")]
 pub struct Unstable {
diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.rs b/src/test/ui/lint/lint-stability-fields-deprecated.rs
index 14c6383806f..2024cf15ab0 100644
--- a/src/test/ui/lint/lint-stability-fields-deprecated.rs
+++ b/src/test/ui/lint/lint-stability-fields-deprecated.rs
@@ -17,33 +17,38 @@ mod cross_crate {
             override1: 2,
             override2: 3,
             //~^ ERROR use of deprecated field
+            override3: 4,
         };
 
         let _ = x.inherit;
         let _ = x.override1;
         let _ = x.override2;
         //~^ ERROR use of deprecated field
+        let _ = x.override3;
 
         let Stable {
             inherit: _,
             override1: _,
-            override2: _
+            override2: _,
             //~^ ERROR use of deprecated field
+            override3: _,
         } = x;
         // all fine
         let Stable { .. } = x;
 
-        let x = Stable2(1, 2, 3);
+        let x = Stable2(1, 2, 3, 4);
 
         let _ = x.0;
         let _ = x.1;
         let _ = x.2;
         //~^ ERROR use of deprecated field
+        let _ = x.3;
 
         let Stable2(_,
                    _,
+                   _,
+                   //~^ ERROR use of deprecated field
                    _)
-            //~^ ERROR use of deprecated field
             = x;
         // all fine
         let Stable2(..) = x;
diff --git a/src/test/ui/lint/lint-stability-fields-deprecated.stderr b/src/test/ui/lint/lint-stability-fields-deprecated.stderr
index ec786786023..151b3e59b91 100644
--- a/src/test/ui/lint/lint-stability-fields-deprecated.stderr
+++ b/src/test/ui/lint/lint-stability-fields-deprecated.stderr
@@ -1,5 +1,5 @@
 error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:94:17
+  --> $DIR/lint-stability-fields-deprecated.rs:99:17
    |
 LL |         let x = Deprecated {
    |                 ^^^^^^^^^^
@@ -11,67 +11,67 @@ LL | #![deny(deprecated)]
    |         ^^^^^^^^^^
 
 error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:111:13
+  --> $DIR/lint-stability-fields-deprecated.rs:116:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
 
 error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:121:13
+  --> $DIR/lint-stability-fields-deprecated.rs:126:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
 
 error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:126:17
+  --> $DIR/lint-stability-fields-deprecated.rs:131:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
 
 error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:136:13
+  --> $DIR/lint-stability-fields-deprecated.rs:141:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
 error: use of deprecated struct `cross_crate::lint_stability_fields::Deprecated2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:145:13
+  --> $DIR/lint-stability-fields-deprecated.rs:150:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
 error: use of deprecated struct `this_crate::Deprecated`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:281:17
+  --> $DIR/lint-stability-fields-deprecated.rs:286:17
    |
 LL |         let x = Deprecated {
    |                 ^^^^^^^^^^
 
 error: use of deprecated struct `this_crate::Deprecated`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:298:13
+  --> $DIR/lint-stability-fields-deprecated.rs:303:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
 
 error: use of deprecated struct `this_crate::Deprecated`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:308:13
+  --> $DIR/lint-stability-fields-deprecated.rs:313:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
 
 error: use of deprecated tuple struct `this_crate::Deprecated2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:313:17
+  --> $DIR/lint-stability-fields-deprecated.rs:318:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
 
 error: use of deprecated tuple struct `this_crate::Deprecated2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:323:13
+  --> $DIR/lint-stability-fields-deprecated.rs:328:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
 
 error: use of deprecated tuple struct `this_crate::Deprecated2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:332:13
+  --> $DIR/lint-stability-fields-deprecated.rs:337:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
@@ -83,295 +83,295 @@ LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:24:17
+  --> $DIR/lint-stability-fields-deprecated.rs:25:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Stable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:30:13
+  --> $DIR/lint-stability-fields-deprecated.rs:32:13
    |
-LL |             override2: _
+LL |             override2: _,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:40:17
+  --> $DIR/lint-stability-fields-deprecated.rs:43:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Stable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:45:20
+  --> $DIR/lint-stability-fields-deprecated.rs:49:20
    |
-LL |                    _)
+LL |                    _,
    |                    ^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:55:13
+  --> $DIR/lint-stability-fields-deprecated.rs:60:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:61:17
+  --> $DIR/lint-stability-fields-deprecated.rs:66:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Unstable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:67:13
+  --> $DIR/lint-stability-fields-deprecated.rs:72:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:80:17
+  --> $DIR/lint-stability-fields-deprecated.rs:85:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Unstable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:86:14
+  --> $DIR/lint-stability-fields-deprecated.rs:91:14
    |
 LL |              _)
    |              ^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:96:13
+  --> $DIR/lint-stability-fields-deprecated.rs:101:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:98:13
+  --> $DIR/lint-stability-fields-deprecated.rs:103:13
    |
 LL |             override1: 2,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:100:13
+  --> $DIR/lint-stability-fields-deprecated.rs:105:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:104:17
+  --> $DIR/lint-stability-fields-deprecated.rs:109:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:106:17
+  --> $DIR/lint-stability-fields-deprecated.rs:111:17
    |
 LL |         let _ = x.override1;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:108:17
+  --> $DIR/lint-stability-fields-deprecated.rs:113:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::inherit`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:113:13
+  --> $DIR/lint-stability-fields-deprecated.rs:118:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:115:13
+  --> $DIR/lint-stability-fields-deprecated.rs:120:13
    |
 LL |             override1: _,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:117:13
+  --> $DIR/lint-stability-fields-deprecated.rs:122:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:129:17
+  --> $DIR/lint-stability-fields-deprecated.rs:134:17
    |
 LL |         let _ = x.0;
    |                 ^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:131:17
+  --> $DIR/lint-stability-fields-deprecated.rs:136:17
    |
 LL |         let _ = x.1;
    |                 ^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:133:17
+  --> $DIR/lint-stability-fields-deprecated.rs:138:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::0`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:138:14
+  --> $DIR/lint-stability-fields-deprecated.rs:143:14
    |
 LL |             (_,
    |              ^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:140:14
+  --> $DIR/lint-stability-fields-deprecated.rs:145:14
    |
 LL |              _,
    |              ^
 
 error: use of deprecated field `cross_crate::lint_stability_fields::Deprecated2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:142:14
+  --> $DIR/lint-stability-fields-deprecated.rs:147:14
    |
 LL |              _)
    |              ^
 
 error: use of deprecated field `this_crate::Stable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:205:13
+  --> $DIR/lint-stability-fields-deprecated.rs:210:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Stable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:211:17
+  --> $DIR/lint-stability-fields-deprecated.rs:216:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Stable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:217:13
+  --> $DIR/lint-stability-fields-deprecated.rs:222:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Stable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:227:17
+  --> $DIR/lint-stability-fields-deprecated.rs:232:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
 error: use of deprecated field `this_crate::Stable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:232:20
+  --> $DIR/lint-stability-fields-deprecated.rs:237:20
    |
 LL |                    _)
    |                    ^
 
 error: use of deprecated field `this_crate::Unstable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:242:13
+  --> $DIR/lint-stability-fields-deprecated.rs:247:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Unstable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:248:17
+  --> $DIR/lint-stability-fields-deprecated.rs:253:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Unstable::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:254:13
+  --> $DIR/lint-stability-fields-deprecated.rs:259:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Unstable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:267:17
+  --> $DIR/lint-stability-fields-deprecated.rs:272:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
 error: use of deprecated field `this_crate::Unstable2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:273:14
+  --> $DIR/lint-stability-fields-deprecated.rs:278:14
    |
 LL |              _)
    |              ^
 
 error: use of deprecated field `this_crate::Deprecated::inherit`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:283:13
+  --> $DIR/lint-stability-fields-deprecated.rs:288:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::override1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:285:13
+  --> $DIR/lint-stability-fields-deprecated.rs:290:13
    |
 LL |             override1: 2,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:287:13
+  --> $DIR/lint-stability-fields-deprecated.rs:292:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::inherit`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:291:17
+  --> $DIR/lint-stability-fields-deprecated.rs:296:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::override1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:293:17
+  --> $DIR/lint-stability-fields-deprecated.rs:298:17
    |
 LL |         let _ = x.override1;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:295:17
+  --> $DIR/lint-stability-fields-deprecated.rs:300:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::inherit`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:300:13
+  --> $DIR/lint-stability-fields-deprecated.rs:305:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::override1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:302:13
+  --> $DIR/lint-stability-fields-deprecated.rs:307:13
    |
 LL |             override1: _,
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated::override2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:304:13
+  --> $DIR/lint-stability-fields-deprecated.rs:309:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
 
 error: use of deprecated field `this_crate::Deprecated2::0`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:316:17
+  --> $DIR/lint-stability-fields-deprecated.rs:321:17
    |
 LL |         let _ = x.0;
    |                 ^^^
 
 error: use of deprecated field `this_crate::Deprecated2::1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:318:17
+  --> $DIR/lint-stability-fields-deprecated.rs:323:17
    |
 LL |         let _ = x.1;
    |                 ^^^
 
 error: use of deprecated field `this_crate::Deprecated2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:320:17
+  --> $DIR/lint-stability-fields-deprecated.rs:325:17
    |
 LL |         let _ = x.2;
    |                 ^^^
 
 error: use of deprecated field `this_crate::Deprecated2::0`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:325:14
+  --> $DIR/lint-stability-fields-deprecated.rs:330:14
    |
 LL |             (_,
    |              ^
 
 error: use of deprecated field `this_crate::Deprecated2::1`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:327:14
+  --> $DIR/lint-stability-fields-deprecated.rs:332:14
    |
 LL |              _,
    |              ^
 
 error: use of deprecated field `this_crate::Deprecated2::2`: text
-  --> $DIR/lint-stability-fields-deprecated.rs:329:14
+  --> $DIR/lint-stability-fields-deprecated.rs:334:14
    |
 LL |              _)
    |              ^
diff --git a/src/test/ui/lint/lint-stability-fields.rs b/src/test/ui/lint/lint-stability-fields.rs
index c5de5748aa3..40836489848 100644
--- a/src/test/ui/lint/lint-stability-fields.rs
+++ b/src/test/ui/lint/lint-stability-fields.rs
@@ -20,29 +20,34 @@ mod cross_crate {
             inherit: 1,
             override1: 2, //~ ERROR use of unstable
             override2: 3, //~ ERROR use of unstable
+            override3: 4,
         };
 
         let _ = x.inherit;
         let _ = x.override1; //~ ERROR use of unstable
         let _ = x.override2; //~ ERROR use of unstable
+        let _ = x.override3;
 
         let Stable {
             inherit: _,
             override1: _, //~ ERROR use of unstable
-            override2: _ //~ ERROR use of unstable
+            override2: _, //~ ERROR use of unstable
+            override3: _
         } = x;
         // all fine
         let Stable { .. } = x;
 
-        let x = Stable2(1, 2, 3);
+        let x = Stable2(1, 2, 3, 4);
 
         let _ = x.0;
         let _ = x.1; //~ ERROR use of unstable
         let _ = x.2; //~ ERROR use of unstable
+        let _ = x.3;
 
         let Stable2(_,
                    _, //~ ERROR use of unstable
-                   _) //~ ERROR use of unstable
+                   _, //~ ERROR use of unstable
+                   _)
             = x;
         // all fine
         let Stable2(..) = x;
@@ -133,11 +138,13 @@ mod this_crate {
         #[rustc_deprecated(since = "1.0.0", reason = "text")]
         #[unstable(feature = "unstable_test_feature", issue = "none")]
         override2: u8,
+        #[stable(feature = "rust2", since = "2.0.0")]
+        override3: u8,
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
     struct Stable2(u8,
-                   #[stable(feature = "rust1", since = "1.0.0")] u8,
+                   #[stable(feature = "rust2", since = "2.0.0")] u8,
                    #[unstable(feature = "unstable_test_feature", issue = "none")]
                    #[rustc_deprecated(since = "1.0.0", reason = "text")] u8);
 
@@ -178,16 +185,19 @@ mod this_crate {
             inherit: 1,
             override1: 2,
             override2: 3,
+            override3: 4,
         };
 
         let _ = x.inherit;
         let _ = x.override1;
         let _ = x.override2;
+        let _ = x.override3;
 
         let Stable {
             inherit: _,
             override1: _,
-            override2: _
+            override2: _,
+            override3: _
         } = x;
         // all fine
         let Stable { .. } = x;
diff --git a/src/test/ui/lint/lint-stability-fields.stderr b/src/test/ui/lint/lint-stability-fields.stderr
index b6a08186b5f..3d2e73c1e8e 100644
--- a/src/test/ui/lint/lint-stability-fields.stderr
+++ b/src/test/ui/lint/lint-stability-fields.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:51:17
+  --> $DIR/lint-stability-fields.rs:56:17
    |
 LL |         let x = Unstable {
    |                 ^^^^^^^^
@@ -7,7 +7,7 @@ LL |         let x = Unstable {
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:61:13
+  --> $DIR/lint-stability-fields.rs:66:13
    |
 LL |         let Unstable {
    |             ^^^^^^^^
@@ -15,7 +15,7 @@ LL |         let Unstable {
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:67:13
+  --> $DIR/lint-stability-fields.rs:72:13
    |
 LL |         let Unstable
    |             ^^^^^^^^
@@ -23,7 +23,7 @@ LL |         let Unstable
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:72:17
+  --> $DIR/lint-stability-fields.rs:77:17
    |
 LL |         let x = reexport::Unstable2(1, 2, 3);
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -31,7 +31,7 @@ LL |         let x = reexport::Unstable2(1, 2, 3);
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:74:17
+  --> $DIR/lint-stability-fields.rs:79:17
    |
 LL |         let x = Unstable2(1, 2, 3);
    |                 ^^^^^^^^^
@@ -39,7 +39,7 @@ LL |         let x = Unstable2(1, 2, 3);
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:80:13
+  --> $DIR/lint-stability-fields.rs:85:13
    |
 LL |         let Unstable2
    |             ^^^^^^^^^
@@ -47,7 +47,7 @@ LL |         let Unstable2
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:85:13
+  --> $DIR/lint-stability-fields.rs:90:13
    |
 LL |         let Unstable2
    |             ^^^^^^^^^
@@ -55,7 +55,7 @@ LL |         let Unstable2
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:90:17
+  --> $DIR/lint-stability-fields.rs:95:17
    |
 LL |         let x = Deprecated {
    |                 ^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |         let x = Deprecated {
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:100:13
+  --> $DIR/lint-stability-fields.rs:105:13
    |
 LL |         let Deprecated {
    |             ^^^^^^^^^^
@@ -71,7 +71,7 @@ LL |         let Deprecated {
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:106:13
+  --> $DIR/lint-stability-fields.rs:111:13
    |
 LL |         let Deprecated
    |             ^^^^^^^^^^
@@ -79,7 +79,7 @@ LL |         let Deprecated
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:110:17
+  --> $DIR/lint-stability-fields.rs:115:17
    |
 LL |         let x = Deprecated2(1, 2, 3);
    |                 ^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL |         let x = Deprecated2(1, 2, 3);
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:116:13
+  --> $DIR/lint-stability-fields.rs:121:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL |         let Deprecated2
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:121:13
+  --> $DIR/lint-stability-fields.rs:126:13
    |
 LL |         let Deprecated2
    |             ^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL |             override2: 3,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:26:17
+  --> $DIR/lint-stability-fields.rs:27:17
    |
 LL |         let _ = x.override1;
    |                 ^^^^^^^^^^^
@@ -127,7 +127,7 @@ LL |         let _ = x.override1;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:27:17
+  --> $DIR/lint-stability-fields.rs:28:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |         let _ = x.override2;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:31:13
+  --> $DIR/lint-stability-fields.rs:33:13
    |
 LL |             override1: _,
    |             ^^^^^^^^^^^^
@@ -143,15 +143,15 @@ LL |             override1: _,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:32:13
+  --> $DIR/lint-stability-fields.rs:34:13
    |
-LL |             override2: _
+LL |             override2: _,
    |             ^^^^^^^^^^^^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:40:17
+  --> $DIR/lint-stability-fields.rs:43:17
    |
 LL |         let _ = x.1;
    |                 ^^^
@@ -159,7 +159,7 @@ LL |         let _ = x.1;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:41:17
+  --> $DIR/lint-stability-fields.rs:44:17
    |
 LL |         let _ = x.2;
    |                 ^^^
@@ -167,7 +167,7 @@ LL |         let _ = x.2;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:44:20
+  --> $DIR/lint-stability-fields.rs:48:20
    |
 LL |                    _,
    |                    ^
@@ -175,15 +175,15 @@ LL |                    _,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:45:20
+  --> $DIR/lint-stability-fields.rs:49:20
    |
-LL |                    _)
+LL |                    _,
    |                    ^
    |
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:52:13
+  --> $DIR/lint-stability-fields.rs:57:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
@@ -191,7 +191,7 @@ LL |             inherit: 1,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:54:13
+  --> $DIR/lint-stability-fields.rs:59:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |             override2: 3,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:57:17
+  --> $DIR/lint-stability-fields.rs:62:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
@@ -207,7 +207,7 @@ LL |         let _ = x.inherit;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:59:17
+  --> $DIR/lint-stability-fields.rs:64:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
@@ -215,7 +215,7 @@ LL |         let _ = x.override2;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:62:13
+  --> $DIR/lint-stability-fields.rs:67:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
@@ -223,7 +223,7 @@ LL |             inherit: _,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:64:13
+  --> $DIR/lint-stability-fields.rs:69:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
@@ -231,7 +231,7 @@ LL |             override2: _
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:76:17
+  --> $DIR/lint-stability-fields.rs:81:17
    |
 LL |         let _ = x.0;
    |                 ^^^
@@ -239,7 +239,7 @@ LL |         let _ = x.0;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:78:17
+  --> $DIR/lint-stability-fields.rs:83:17
    |
 LL |         let _ = x.2;
    |                 ^^^
@@ -247,7 +247,7 @@ LL |         let _ = x.2;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:81:14
+  --> $DIR/lint-stability-fields.rs:86:14
    |
 LL |             (_,
    |              ^
@@ -255,7 +255,7 @@ LL |             (_,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:83:14
+  --> $DIR/lint-stability-fields.rs:88:14
    |
 LL |              _)
    |              ^
@@ -263,7 +263,7 @@ LL |              _)
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:91:13
+  --> $DIR/lint-stability-fields.rs:96:13
    |
 LL |             inherit: 1,
    |             ^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |             inherit: 1,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:93:13
+  --> $DIR/lint-stability-fields.rs:98:13
    |
 LL |             override2: 3,
    |             ^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL |             override2: 3,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:96:17
+  --> $DIR/lint-stability-fields.rs:101:17
    |
 LL |         let _ = x.inherit;
    |                 ^^^^^^^^^
@@ -287,7 +287,7 @@ LL |         let _ = x.inherit;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:98:17
+  --> $DIR/lint-stability-fields.rs:103:17
    |
 LL |         let _ = x.override2;
    |                 ^^^^^^^^^^^
@@ -295,7 +295,7 @@ LL |         let _ = x.override2;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:101:13
+  --> $DIR/lint-stability-fields.rs:106:13
    |
 LL |             inherit: _,
    |             ^^^^^^^^^^
@@ -303,7 +303,7 @@ LL |             inherit: _,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:103:13
+  --> $DIR/lint-stability-fields.rs:108:13
    |
 LL |             override2: _
    |             ^^^^^^^^^^^^
@@ -311,7 +311,7 @@ LL |             override2: _
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:112:17
+  --> $DIR/lint-stability-fields.rs:117:17
    |
 LL |         let _ = x.0;
    |                 ^^^
@@ -319,7 +319,7 @@ LL |         let _ = x.0;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:114:17
+  --> $DIR/lint-stability-fields.rs:119:17
    |
 LL |         let _ = x.2;
    |                 ^^^
@@ -327,7 +327,7 @@ LL |         let _ = x.2;
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:117:14
+  --> $DIR/lint-stability-fields.rs:122:14
    |
 LL |             (_,
    |              ^
@@ -335,7 +335,7 @@ LL |             (_,
    = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'unstable_test_feature'
-  --> $DIR/lint-stability-fields.rs:119:14
+  --> $DIR/lint-stability-fields.rs:124:14
    |
 LL |              _)
    |              ^
diff --git a/src/test/ui/lint/noop-method-call.rs b/src/test/ui/lint/noop-method-call.rs
new file mode 100644
index 00000000000..9870c813572
--- /dev/null
+++ b/src/test/ui/lint/noop-method-call.rs
@@ -0,0 +1,54 @@
+// check-pass
+
+#![allow(unused)]
+#![warn(noop_method_call)]
+
+use std::borrow::Borrow;
+use std::ops::Deref;
+
+struct PlainType<T>(T);
+
+#[derive(Clone)]
+struct CloneType<T>(T);
+
+fn main() {
+    let non_clone_type_ref = &PlainType(1u32);
+    let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
+    //~^ WARNING call to `.clone()` on a reference in this situation does nothing
+
+    let clone_type_ref = &CloneType(1u32);
+    let clone_type_ref_clone: CloneType<u32> = clone_type_ref.clone();
+
+    // Calling clone on a double reference doesn't warn since the method call itself
+    // peels the outer reference off
+    let clone_type_ref = &&CloneType(1u32);
+    let clone_type_ref_clone: &CloneType<u32> = clone_type_ref.clone();
+
+    let non_deref_type = &PlainType(1u32);
+    let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
+    //~^ WARNING call to `.deref()` on a reference in this situation does nothing
+
+    // Dereferencing a &&T does not warn since it has collapsed the double reference
+    let non_deref_type = &&PlainType(1u32);
+    let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
+
+    let non_borrow_type = &PlainType(1u32);
+    let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
+    //~^ WARNING call to `.borrow()` on a reference in this situation does nothing
+
+    // Borrowing a &&T does not warn since it has collapsed the double reference
+    let non_borrow_type = &&PlainType(1u32);
+    let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
+
+    let xs = ["a", "b", "c"];
+    let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // ok, but could use `*x` instead
+}
+
+fn generic<T>(non_clone_type: &PlainType<T>) {
+    non_clone_type.clone();
+}
+
+fn non_generic(non_clone_type: &PlainType<u32>) {
+    non_clone_type.clone();
+    //~^ WARNING call to `.clone()` on a reference in this situation does nothing
+}
diff --git a/src/test/ui/lint/noop-method-call.stderr b/src/test/ui/lint/noop-method-call.stderr
new file mode 100644
index 00000000000..7f6f96bf1d1
--- /dev/null
+++ b/src/test/ui/lint/noop-method-call.stderr
@@ -0,0 +1,39 @@
+warning: call to `.clone()` on a reference in this situation does nothing
+  --> $DIR/noop-method-call.rs:16:71
+   |
+LL |     let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
+   |                                                                       ^^^^^^^^ unnecessary method call
+   |
+note: the lint level is defined here
+  --> $DIR/noop-method-call.rs:4:9
+   |
+LL | #![warn(noop_method_call)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
+
+warning: call to `.deref()` on a reference in this situation does nothing
+  --> $DIR/noop-method-call.rs:28:63
+   |
+LL |     let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
+   |                                                               ^^^^^^^^ unnecessary method call
+   |
+   = note: the type `&PlainType<u32>` which `deref` is being called on is the same as the type returned from `deref`, so the method call does not do anything and can be removed
+
+warning: call to `.borrow()` on a reference in this situation does nothing
+  --> $DIR/noop-method-call.rs:36:66
+   |
+LL |     let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
+   |                                                                  ^^^^^^^^^ unnecessary method call
+   |
+   = note: the type `&PlainType<u32>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed
+
+warning: call to `.clone()` on a reference in this situation does nothing
+  --> $DIR/noop-method-call.rs:52:19
+   |
+LL |     non_clone_type.clone();
+   |                   ^^^^^^^^ unnecessary method call
+   |
+   = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed
+
+warning: 4 warnings emitted
+
diff --git a/src/test/ui/lint/rustdoc-renamed.rs b/src/test/ui/lint/rustdoc-renamed.rs
new file mode 100644
index 00000000000..71e88bd7f54
--- /dev/null
+++ b/src/test/ui/lint/rustdoc-renamed.rs
@@ -0,0 +1,14 @@
+#![crate_type = "lib"]
+
+#![deny(unknown_lints)]
+#![deny(renamed_and_removed_lints)]
+//~^ NOTE lint level is defined
+
+// both allowed, since the compiler doesn't yet know what rustdoc lints are valid
+#![deny(rustdoc::x)]
+#![deny(rustdoc::intra_doc_link_resolution_failure)]
+
+#![deny(intra_doc_link_resolution_failure)]
+//~^ ERROR removed: use `rustdoc::broken_intra_doc_links`
+#![deny(non_autolinks)]
+//~^ ERROR removed: use `rustdoc::non_autolinks`
diff --git a/src/test/ui/lint/rustdoc-renamed.stderr b/src/test/ui/lint/rustdoc-renamed.stderr
new file mode 100644
index 00000000000..a7fe3e29d5b
--- /dev/null
+++ b/src/test/ui/lint/rustdoc-renamed.stderr
@@ -0,0 +1,20 @@
+error: lint `intra_doc_link_resolution_failure` has been removed: use `rustdoc::broken_intra_doc_links` instead
+  --> $DIR/rustdoc-renamed.rs:11:9
+   |
+LL | #![deny(intra_doc_link_resolution_failure)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/rustdoc-renamed.rs:4:9
+   |
+LL | #![deny(renamed_and_removed_lints)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: lint `non_autolinks` has been removed: use `rustdoc::non_autolinks` instead
+  --> $DIR/rustdoc-renamed.rs:13:9
+   |
+LL | #![deny(non_autolinks)]
+   |         ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/pub/pub-reexport-priv-extern-crate.rs b/src/test/ui/pub/pub-reexport-priv-extern-crate.rs
index e95d6924026..dd5cd420fa5 100644
--- a/src/test/ui/pub/pub-reexport-priv-extern-crate.rs
+++ b/src/test/ui/pub/pub-reexport-priv-extern-crate.rs
@@ -1,5 +1,3 @@
-#![allow(unused)]
-
 extern crate core;
 pub use core as reexported_core; //~ ERROR `core` is private, and cannot be re-exported
                                  //~^ WARN this was previously accepted
@@ -9,16 +7,14 @@ mod foo1 {
 }
 
 mod foo2 {
-    use foo1::core; //~ ERROR `core` is private, and cannot be re-exported
-                    //~^ WARN this was previously accepted
+    use foo1::core; //~ ERROR crate import `core` is private
     pub mod bar {
         extern crate core;
     }
 }
 
 mod baz {
-    pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be re-exported
-                             //~^ WARN this was previously accepted
+    pub use foo2::bar::core; //~ ERROR crate import `core` is private
 }
 
 fn main() {}
diff --git a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
index 0b44c5a6525..e4d73c6475d 100644
--- a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
+++ b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
@@ -1,30 +1,37 @@
-error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
-  --> $DIR/pub-reexport-priv-extern-crate.rs:4:9
+error[E0603]: crate import `core` is private
+  --> $DIR/pub-reexport-priv-extern-crate.rs:10:15
    |
-LL | pub use core as reexported_core;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+LL |     use foo1::core;
+   |               ^^^^ private crate import
    |
-   = note: `#[deny(pub_use_of_private_extern_crate)]` 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
+note: the crate import `core` is defined here
+  --> $DIR/pub-reexport-priv-extern-crate.rs:6:5
+   |
+LL |     extern crate core;
+   |     ^^^^^^^^^^^^^^^^^^
 
-error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
-  --> $DIR/pub-reexport-priv-extern-crate.rs:12:9
+error[E0603]: crate import `core` is private
+  --> $DIR/pub-reexport-priv-extern-crate.rs:17:24
    |
-LL |     use foo1::core;
-   |         ^^^^^^^^^^
+LL |     pub use foo2::bar::core;
+   |                        ^^^^ private crate import
    |
-   = 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
+note: the crate import `core` is defined here
+  --> $DIR/pub-reexport-priv-extern-crate.rs:12:9
+   |
+LL |         extern crate core;
+   |         ^^^^^^^^^^^^^^^^^^
 
 error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
-  --> $DIR/pub-reexport-priv-extern-crate.rs:20:13
+  --> $DIR/pub-reexport-priv-extern-crate.rs:2:9
    |
-LL |     pub use foo2::bar::core;
-   |             ^^^^^^^^^^^^^^^
+LL | pub use core as reexported_core;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
+   = note: `#[deny(pub_use_of_private_extern_crate)]` 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs b/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs
index 0b243bb5211..3f4fdfd0180 100644
--- a/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs
+++ b/src/test/ui/stability-attribute/stability-attribute-issue-43027.rs
@@ -1,10 +1,15 @@
+// check-pass
 #![feature(staged_api)]
 #![stable(feature = "test", since = "0")]
 
 #[stable(feature = "test", since = "0")]
-pub struct Reverse<T>(pub T); //~ ERROR field has missing stability attribute
+pub struct A<T>(pub T);
+
+#[stable(feature = "test", since = "0")]
+pub struct B<T>(#[stable(feature = "test", since = "0")] pub T);
 
 fn main() {
     // Make sure the field is used to fill the stability cache
-    Reverse(0).0;
+    A(0).0;
+    B(0).0;
 }
diff --git a/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr b/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr
deleted file mode 100644
index 280c72acccb..00000000000
--- a/src/test/ui/stability-attribute/stability-attribute-issue-43027.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: field has missing stability attribute
-  --> $DIR/stability-attribute-issue-43027.rs:5:23
-   |
-LL | pub struct Reverse<T>(pub T);
-   |                       ^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.rs b/src/test/ui/stability-attribute/stability-attribute-sanity.rs
index 0c40f8ae1c6..9f8ecc26281 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.rs
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.rs
@@ -57,17 +57,16 @@ fn multiple2() { }
 #[stable(feature = "a", since = "b")] //~ ERROR multiple stability levels [E0544]
 fn multiple3() { }
 
-#[stable(feature = "a", since = "b")]
+#[stable(feature = "a", since = "b")] //~ ERROR invalid stability version found
 #[rustc_deprecated(since = "b", reason = "text")]
 #[rustc_deprecated(since = "b", reason = "text")] //~ ERROR multiple deprecated attributes
 #[rustc_const_unstable(feature = "c", issue = "none")]
 #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
 pub const fn multiple4() { }
-//~^ ERROR Invalid stability version found
 
-#[stable(feature = "a", since = "1.0.0")]
+#[stable(feature = "a", since = "1.0.0")] //~ ERROR invalid deprecation version found
 #[rustc_deprecated(since = "invalid", reason = "text")]
-fn invalid_deprecation_version() {} //~ ERROR Invalid deprecation version found
+fn invalid_deprecation_version() {}
 
 #[rustc_deprecated(since = "a", reason = "text")]
 fn deprecated_without_unstable_or_stable() { }
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
index 03fb80bb90a..ddf65f3a7ee 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -96,20 +96,26 @@ error[E0544]: multiple stability levels
 LL | #[rustc_const_unstable(feature = "d", issue = "none")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: Invalid stability version found
-  --> $DIR/stability-attribute-sanity.rs:65:1
+error: invalid stability version found
+  --> $DIR/stability-attribute-sanity.rs:60:1
    |
+LL | #[stable(feature = "a", since = "b")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid stability version
+...
 LL | pub const fn multiple4() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ---------------------------- the stability attribute annotates this item
 
-error: Invalid deprecation version found
-  --> $DIR/stability-attribute-sanity.rs:70:1
+error: invalid deprecation version found
+  --> $DIR/stability-attribute-sanity.rs:67:1
    |
+LL | #[stable(feature = "a", since = "1.0.0")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid deprecation version
+LL | #[rustc_deprecated(since = "invalid", reason = "text")]
 LL | fn invalid_deprecation_version() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ----------------------------------- the stability attribute annotates this item
 
 error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
-  --> $DIR/stability-attribute-sanity.rs:72:1
+  --> $DIR/stability-attribute-sanity.rs:71:1
    |
 LL | #[rustc_deprecated(since = "a", reason = "text")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/static/static-reference-to-fn-2.stderr b/src/test/ui/static/static-reference-to-fn-2.stderr
index 028e11a60ce..ff15884bd44 100644
--- a/src/test/ui/static/static-reference-to-fn-2.stderr
+++ b/src/test/ui/static/static-reference-to-fn-2.stderr
@@ -40,6 +40,8 @@ LL | |         statefn: &id(state1 as StateMachineFunc)
    | |                   ------------------------------ temporary value created here
 LL | |     }
    | |_____^ returns a value referencing data owned by the current function
+   |
+   = help: use `.collect()` to allocate the iterator
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/underscore-imports/hygiene-2.rs b/src/test/ui/underscore-imports/hygiene-2.rs
index bea61eae6b5..510d91d0d46 100644
--- a/src/test/ui/underscore-imports/hygiene-2.rs
+++ b/src/test/ui/underscore-imports/hygiene-2.rs
@@ -29,5 +29,6 @@ m!(y);
 
 fn main() {
     use crate::y::*;
+    #[allow(noop_method_call)]
     (&()).deref();
 }
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 1ab560ac09d..f61d61e8f9d 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -10,7 +10,7 @@ diff = "0.1.10"
 unified-diff = "0.2.1"
 getopts = "0.2"
 tracing = "0.1"
-tracing-subscriber = { version = "0.2.13", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
+tracing-subscriber = { version = "0.2", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
 regex = "1.0"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 651b478e794..06dc16f7676 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -133,6 +133,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
     "parking_lot_core",
     "pathdiff",
     "perf-event-open-sys",
+    "pin-project-lite",
     "pkg-config",
     "polonius-engine",
     "ppv-lite86",