about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock315
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs50
-rw-r--r--compiler/rustc_data_structures/src/lib.rs23
-rw-r--r--compiler/rustc_data_structures/src/sorted_map/index_map.rs42
-rw-r--r--compiler/rustc_data_structures/src/sorted_map/tests.rs6
-rw-r--r--compiler/rustc_data_structures/src/vec_map.rs41
-rw-r--r--compiler/rustc_expand/src/base.rs6
-rw-r--r--compiler/rustc_expand/src/expand.rs53
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_infer/src/traits/util.rs6
-rw-r--r--compiler/rustc_lint/src/context.rs10
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/locator.rs7
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs2
-rw-r--r--compiler/rustc_middle/src/ty/error.rs65
-rw-r--r--compiler/rustc_middle/src/ty/vtable.rs58
-rw-r--r--compiler/rustc_mir/src/borrow_check/type_check/mod.rs140
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs14
-rw-r--r--compiler/rustc_passes/src/dead.rs8
-rw-r--r--compiler/rustc_session/src/session.rs10
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs27
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs377
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs9
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs13
-rw-r--r--compiler/rustc_typeck/src/hir_wf_check.rs3
-rw-r--r--config.toml.example2
-rw-r--r--library/alloc/src/collections/btree/map.rs1
-rw-r--r--library/alloc/src/collections/btree/set.rs1
-rw-r--r--library/alloc/src/lib.rs4
-rw-r--r--library/core/src/iter/traits/iterator.rs13
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/std/src/collections/hash/map.rs1
-rw-r--r--library/std/src/collections/hash/set.rs1
-rw-r--r--library/std/src/env.rs7
-rw-r--r--library/std/src/io/buffered/bufwriter.rs24
-rw-r--r--library/std/src/io/buffered/mod.rs6
-rw-r--r--library/std/src/sys/unix/thread.rs34
-rw-r--r--src/bootstrap/compile.rs2
-rw-r--r--src/bootstrap/config.rs23
-rwxr-xr-xsrc/bootstrap/configure.py3
-rw-r--r--src/bootstrap/dist.rs10
-rw-r--r--src/bootstrap/flags.rs9
-rw-r--r--src/bootstrap/job.rs20
-rw-r--r--src/bootstrap/lib.rs4
-rw-r--r--src/bootstrap/native.rs9
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/librustdoc/doctest.rs22
-rw-r--r--src/librustdoc/html/render/print_item.rs5
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css3
-rw-r--r--src/librustdoc/markdown.rs13
-rw-r--r--src/test/rustdoc-gui/module-items-font.goml4
-rw-r--r--src/test/rustdoc/toggle-item-contents.rs6
-rw-r--r--src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs1
-rw-r--r--src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr8
-rw-r--r--src/test/ui/associated-types/issue-87261.rs99
-rw-r--r--src/test/ui/associated-types/issue-87261.stderr238
-rw-r--r--src/test/ui/async-await/issue-86507.rs25
-rw-r--r--src/test/ui/async-await/issue-86507.stderr23
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr16
-rw-r--r--src/test/ui/bastion-of-the-turbofish.rs3
-rw-r--r--src/test/ui/borrowck/borrowck-assign-to-subfield.rs1
-rw-r--r--src/test/ui/const-generics/issues/auxiliary/impl-const.rs (renamed from src/test/ui/const-generics/auxiliary/impl-const.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-61522-array-len-succ.full.stderr (renamed from src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-61522-array-len-succ.min.stderr (renamed from src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-61522-array-len-succ.rs (renamed from src/test/ui/const-generics/issue-61522-array-len-succ.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-66596-impl-trait-for-str-const-arg.min.stderr (renamed from src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-66596-impl-trait-for-str-const-arg.rs (renamed from src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67375.full.stderr (renamed from src/test/ui/const-generics/issue-67375.full.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67375.min.stderr (renamed from src/test/ui/const-generics/issue-67375.min.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67375.rs (renamed from src/test/ui/const-generics/issue-67375.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-1.full.stderr (renamed from src/test/ui/const-generics/issue-67945-1.full.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-1.min.stderr (renamed from src/test/ui/const-generics/issue-67945-1.min.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-1.rs (renamed from src/test/ui/const-generics/issue-67945-1.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-2.full.stderr (renamed from src/test/ui/const-generics/issue-67945-2.full.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-2.min.stderr (renamed from src/test/ui/const-generics/issue-67945-2.min.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-2.rs (renamed from src/test/ui/const-generics/issue-67945-2.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-3.full.stderr (renamed from src/test/ui/const-generics/issue-67945-3.full.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-3.min.stderr (renamed from src/test/ui/const-generics/issue-67945-3.min.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-67945-3.rs (renamed from src/test/ui/const-generics/issue-67945-3.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-68104-print-stack-overflow.rs (renamed from src/test/ui/const-generics/issue-68104-print-stack-overflow.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-70180-1-stalled_on.rs (renamed from src/test/ui/const-generics/issue-70180-1-stalled_on.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-70180-2-stalled_on.rs (renamed from src/test/ui/const-generics/issue-70180-2-stalled_on.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-71202.rs (renamed from src/test/ui/const-generics/issue-71202.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-71986.rs (renamed from src/test/ui/const-generics/issue-71986.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-73899.rs (renamed from src/test/ui/const-generics/issue-73899.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-74906.rs (renamed from src/test/ui/const-generics/issue-74906.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-75763.rs (renamed from src/test/ui/const-generics/issue-75763.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-79518-default_trait_method_normalization.rs (renamed from src/test/ui/const-generics/issue-79518-default_trait_method_normalization.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-79518-default_trait_method_normalization.stderr (renamed from src/test/ui/const-generics/issue-79518-default_trait_method_normalization.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-80561-incorrect-param-env.rs (renamed from src/test/ui/const-generics/issue-80561-incorrect-param-env.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-86820.rs (renamed from src/test/ui/const-generics/issue-86820.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-86820.stderr (renamed from src/test/ui/const-generics/issue-86820.stderr)0
-rw-r--r--src/test/ui/const-generics/issues/issue-87076.rs20
-rw-r--r--src/test/ui/crate-loading/missing-std.rs1
-rw-r--r--src/test/ui/crate-loading/missing-std.stderr2
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.rs1
-rw-r--r--src/test/ui/impl-trait/auto-trait-leak.stderr34
-rw-r--r--src/test/ui/impl-trait/issue-86465.rs10
-rw-r--r--src/test/ui/impl-trait/issue-86465.stderr14
-rw-r--r--src/test/ui/impl-trait/issues/issue-54600.rs7
-rw-r--r--src/test/ui/impl-trait/issues/issue-54600.stderr9
-rw-r--r--src/test/ui/impl-trait/issues/issue-54840.rs7
-rw-r--r--src/test/ui/impl-trait/issues/issue-54840.stderr9
-rw-r--r--src/test/ui/impl-trait/issues/issue-58504.rs12
-rw-r--r--src/test/ui/impl-trait/issues/issue-58504.stderr9
-rw-r--r--src/test/ui/impl-trait/issues/issue-58956.rs14
-rw-r--r--src/test/ui/impl-trait/issues/issue-58956.stderr15
-rw-r--r--src/test/ui/impl-trait/issues/issue-70971.rs4
-rw-r--r--src/test/ui/impl-trait/issues/issue-70971.stderr9
-rw-r--r--src/test/ui/impl-trait/issues/issue-79099.rs10
-rw-r--r--src/test/ui/impl-trait/issues/issue-79099.stderr20
-rw-r--r--src/test/ui/impl-trait/issues/issue-84919.rs9
-rw-r--r--src/test/ui/impl-trait/issues/issue-84919.stderr9
-rw-r--r--src/test/ui/impl-trait/issues/issue-86201.rs13
-rw-r--r--src/test/ui/impl-trait/issues/issue-86201.stderr21
-rw-r--r--src/test/ui/impl-trait/issues/issue-86642.rs8
-rw-r--r--src/test/ui/impl-trait/issues/issue-86642.stderr9
-rw-r--r--src/test/ui/impl-trait/issues/issue-87295.rs18
-rw-r--r--src/test/ui/impl-trait/issues/issue-87295.stderr9
-rw-r--r--src/test/ui/issues/issue-19380.stderr4
-rw-r--r--src/test/ui/issues/issue-37131.stderr2
-rw-r--r--src/test/ui/issues/issue-49851/compiler-builtins-error.stderr2
-rw-r--r--src/test/ui/lint/dead-code/self-assign.rs2
-rw-r--r--src/test/ui/lint/dead-code/write-only-field.rs69
-rw-r--r--src/test/ui/lint/dead-code/write-only-field.stderr44
-rw-r--r--src/test/ui/lint/inert-attr-macro.rs20
-rw-r--r--src/test/ui/lint/inert-attr-macro.stderr44
-rw-r--r--src/test/ui/repr/repr-no-niche.rs14
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr4
-rw-r--r--src/test/ui/traits/vtable/vtable-diamond.rs39
-rw-r--r--src/test/ui/traits/vtable/vtable-diamond.stderr35
-rw-r--r--src/test/ui/traits/vtable/vtable-multi-level.rs122
-rw-r--r--src/test/ui/traits/vtable/vtable-multi-level.stderr214
-rw-r--r--src/test/ui/traits/vtable/vtable-multiple.rs31
-rw-r--r--src/test/ui/traits/vtable/vtable-multiple.stderr33
-rw-r--r--src/test/ui/traits/vtable/vtable-vacant.rs28
-rw-r--r--src/test/ui/traits/vtable/vtable-vacant.stderr20
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr49
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr49
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.stderr13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761-2.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761-2.stderr34
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr17
-rw-r--r--src/test/ui/wf/wf-in-fn-type-arg.stderr4
-rw-r--r--src/test/ui/wf/wf-in-fn-type-ret.stderr4
-rw-r--r--src/test/ui/wf/wf-in-obj-type-trait.stderr4
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.stderr4
m---------src/tools/rls0
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml10
-rw-r--r--src/tools/tidy/src/deps.rs24
-rw-r--r--src/version2
169 files changed, 2341 insertions, 978 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5441542d84e..553d9d05e57 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -73,7 +73,7 @@ version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -82,7 +82,7 @@ version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -111,7 +111,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
 dependencies = [
  "hermit-abi",
  "libc",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -186,7 +186,7 @@ dependencies = [
  "serde_json",
  "time",
  "toml",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -243,9 +243,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
 
 [[package]]
 name = "bytes"
-version = "0.5.6"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
+checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
 
 [[package]]
 name = "bytesize"
@@ -310,7 +310,7 @@ dependencies = [
  "unicode-xid",
  "url 2.2.2",
  "walkdir",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -339,7 +339,7 @@ name = "cargo-credential-wincred"
 version = "0.1.0"
 dependencies = [
  "cargo-credential",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -398,12 +398,12 @@ dependencies = [
  "jobserver",
  "libc",
  "log",
- "miow 0.3.7",
+ "miow",
  "same-file",
  "shell-escape",
  "tempfile",
  "walkdir",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -521,7 +521,7 @@ dependencies = [
  "num-integer",
  "num-traits",
  "time",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -623,7 +623,7 @@ checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
 dependencies = [
  "atty",
  "lazy_static",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -664,7 +664,7 @@ dependencies = [
  "glob",
  "lazy_static",
  "libc",
- "miow 0.3.7",
+ "miow",
  "regex",
  "rustfix 0.6.0",
  "serde",
@@ -673,7 +673,7 @@ dependencies = [
  "tracing-subscriber",
  "unified-diff",
  "walkdir",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -688,7 +688,7 @@ dependencies = [
  "lazy_static",
  "libc",
  "log",
- "miow 0.3.7",
+ "miow",
  "regex",
  "rustfix 0.5.1",
  "serde",
@@ -696,7 +696,7 @@ dependencies = [
  "serde_json",
  "tempfile",
  "tester",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -831,7 +831,7 @@ dependencies = [
  "commoncrypto",
  "hex 0.3.2",
  "openssl",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -866,7 +866,7 @@ dependencies = [
  "openssl-sys",
  "schannel",
  "socket2",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -882,7 +882,7 @@ dependencies = [
  "openssl-sys",
  "pkg-config",
  "vcpkg",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -980,7 +980,7 @@ checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
 dependencies = [
  "libc",
  "redox_users",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -991,7 +991,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
 dependencies = [
  "libc",
  "redox_users",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -1148,7 +1148,7 @@ dependencies = [
  "cfg-if 1.0.0",
  "libc",
  "redox_syscall",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -1230,22 +1230,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f"
 
 [[package]]
-name = "fuchsia-zircon"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
-dependencies = [
- "bitflags",
- "fuchsia-zircon-sys",
-]
-
-[[package]]
-name = "fuchsia-zircon-sys"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-
-[[package]]
 name = "futf"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1351,7 +1335,7 @@ dependencies = [
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project-lite 0.2.4",
+ "pin-project-lite",
  "pin-utils",
  "proc-macro-hack",
  "proc-macro-nested",
@@ -1572,7 +1556,7 @@ version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -1694,7 +1678,7 @@ dependencies = [
  "remove_dir_all",
  "tar",
  "walkdir",
- "winapi 0.3.9",
+ "winapi",
  "xz2",
 ]
 
@@ -1705,15 +1689,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
 
 [[package]]
-name = "iovec"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
-dependencies = [
- "libc",
-]
-
-[[package]]
 name = "itertools"
 version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1789,9 +1764,9 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-client-transports"
-version = "17.0.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15b6c6ad01c7354d60de493148c30ac8a82b759e22ae678c8705e9b8e0c566a4"
+checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a"
 dependencies = [
  "derive_more",
  "futures 0.3.12",
@@ -1808,11 +1783,13 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-core"
-version = "17.0.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07569945133257ff557eb37b015497104cea61a2c9edaf126c1cbd6e8332397f"
+checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb"
 dependencies = [
  "futures 0.3.12",
+ "futures-executor",
+ "futures-util",
  "log",
  "serde",
  "serde_derive",
@@ -1821,9 +1798,9 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-core-client"
-version = "17.0.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ac9d56dc729912796637c30f475bbf834594607b27740dfea6e5fa7ba40d1f1"
+checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0"
 dependencies = [
  "futures 0.3.12",
  "jsonrpc-client-transports",
@@ -1831,9 +1808,9 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-derive"
-version = "17.0.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b68ba7e76e5c7796cfa4d2a30e83986550c34404c6d40551c902ca6f7bd4a137"
+checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",
@@ -1843,9 +1820,9 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-ipc-server"
-version = "17.0.1"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c4cd89e5ea7e7f0884e828fc35bb83591a371b92439675eae28efa66c24a97"
+checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845"
 dependencies = [
  "futures 0.3.12",
  "jsonrpc-core",
@@ -1858,9 +1835,9 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-pubsub"
-version = "17.0.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c48dbebce7a9c88ab272a4db7d6478aa4c6d9596e6c086366e89efc4e9ed89e"
+checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011"
 dependencies = [
  "futures 0.3.12",
  "jsonrpc-core",
@@ -1873,9 +1850,9 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-server-utils"
-version = "17.0.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4207cce738bf713a82525065b750a008f28351324f438f56b33d698ada95bb4"
+checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4"
 dependencies = [
  "bytes",
  "futures 0.3.12",
@@ -1884,21 +1861,12 @@ dependencies = [
  "lazy_static",
  "log",
  "tokio",
+ "tokio-stream",
  "tokio-util",
  "unicase",
 ]
 
 [[package]]
-name = "kernel32-sys"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
-[[package]]
 name = "lazy_static"
 version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2018,9 +1986,9 @@ dependencies = [
 
 [[package]]
 name = "lsp-codec"
-version = "0.2.0"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d33c83e320715a1e7e0466a53db2238becb2e5c446deff5506abc81aeacc5ec4"
+checksum = "aa939d0b62476a5a19fb7fcb423a5c6ce8c7e09b851d37531e2fe3e0e6d9d257"
 dependencies = [
  "bytes",
  "serde_json",
@@ -2240,56 +2208,15 @@ dependencies = [
 
 [[package]]
 name = "mio"
-version = "0.6.22"
+version = "0.7.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
+checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
 dependencies = [
- "cfg-if 0.1.10",
- "fuchsia-zircon",
- "fuchsia-zircon-sys",
- "iovec",
- "kernel32-sys",
  "libc",
  "log",
- "miow 0.2.2",
- "net2",
- "slab",
- "winapi 0.2.8",
-]
-
-[[package]]
-name = "mio-named-pipes"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
-dependencies = [
- "log",
- "mio",
- "miow 0.3.7",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "mio-uds"
-version = "0.6.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
-dependencies = [
- "iovec",
- "libc",
- "mio",
-]
-
-[[package]]
-name = "miow"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
-dependencies = [
- "kernel32-sys",
- "net2",
- "winapi 0.2.8",
- "ws2_32-sys",
+ "miow",
+ "ntapi",
+ "winapi",
 ]
 
 [[package]]
@@ -2298,7 +2225,7 @@ version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -2321,23 +2248,21 @@ dependencies = [
 ]
 
 [[package]]
-name = "net2"
-version = "0.2.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7cf75f38f16cb05ea017784dc6dbfd354f76c223dba37701734c4f5a9337d02"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
 name = "new_debug_unreachable"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
 
 [[package]]
+name = "ntapi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "num-integer"
 version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2412,7 +2337,7 @@ version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7c283bf0114efea9e42f1a60edea9859e8c47528eae09d01df4b29c1e489cc48"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -2422,7 +2347,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4ea3ebcd72a54701f56345f16785a6d3ac2df7e986d273eb4395c0b01db17952"
 dependencies = [
  "bstr",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -2480,7 +2405,7 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -2518,18 +2443,16 @@ dependencies = [
 
 [[package]]
 name = "parity-tokio-ipc"
-version = "0.8.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd7f6c69d7687501b2205fe51ade1d7b8797bb3aa141fe5bf13dd78c0483bc89"
+checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6"
 dependencies = [
  "futures 0.3.12",
  "libc",
  "log",
- "mio-named-pipes",
- "miow 0.3.7",
  "rand 0.7.3",
  "tokio",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -2554,7 +2477,7 @@ dependencies = [
  "libc",
  "redox_syscall",
  "smallvec",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -2677,12 +2600,6 @@ dependencies = [
 
 [[package]]
 name = "pin-project-lite"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
-
-[[package]]
-name = "pin-project-lite"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
@@ -3095,7 +3012,7 @@ version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3140,6 +3057,7 @@ dependencies = [
  "serde_json",
  "tempfile",
  "tokio",
+ "tokio-stream",
  "tokio-util",
  "toml",
  "url 2.2.2",
@@ -3303,7 +3221,7 @@ dependencies = [
  "stacker",
  "tempfile",
  "tracing",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3323,7 +3241,7 @@ dependencies = [
  "termize",
  "tracing",
  "unicode-width",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3576,7 +3494,7 @@ dependencies = [
  "smallvec",
  "syn",
  "url 2.2.2",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3778,7 +3696,7 @@ dependencies = [
  "stacker",
  "tempfile",
  "tracing",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3811,7 +3729,7 @@ dependencies = [
  "tracing",
  "tracing-subscriber",
  "tracing-tree",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3833,7 +3751,7 @@ dependencies = [
  "termize",
  "tracing",
  "unicode-width",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -3989,7 +3907,7 @@ dependencies = [
  "smallvec",
  "tempfile",
  "tracing",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -4077,7 +3995,7 @@ dependencies = [
  "smallvec",
  "snap",
  "tracing",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -4637,7 +4555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
 dependencies = [
  "lazy_static",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -4880,7 +4798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
 dependencies = [
  "libc",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -4899,7 +4817,7 @@ dependencies = [
  "cfg-if 0.1.10",
  "libc",
  "psm",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5066,7 +4984,7 @@ dependencies = [
  "rand 0.8.3",
  "redox_syscall",
  "remove_dir_all",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5102,7 +5020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5"
 dependencies = [
  "dirs",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5113,7 +5031,7 @@ checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
 dependencies = [
  "dirs-next",
  "rustversion",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5132,7 +5050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1706be6b564323ce7092f5f7e6b118a14c8ef7ed0e69c8c5329c914a9f101295"
 dependencies = [
  "libc",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5243,7 +5161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
 dependencies = [
  "libc",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5254,49 +5172,44 @@ checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
 
 [[package]]
 name = "tokio"
-version = "0.2.24"
+version = "1.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48"
+checksum = "c2602b8af3767c285202012822834005f596c811042315fa7e9f5b12b2a43207"
 dependencies = [
+ "autocfg",
  "bytes",
- "futures-core",
- "iovec",
- "lazy_static",
  "libc",
  "memchr",
  "mio",
- "mio-named-pipes",
- "mio-uds",
  "num_cpus",
- "pin-project-lite 0.1.11",
+ "once_cell",
+ "pin-project-lite",
  "signal-hook-registry",
- "slab",
- "tokio-macros",
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
-name = "tokio-macros"
-version = "0.2.6"
+name = "tokio-stream"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
+checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
 ]
 
 [[package]]
 name = "tokio-util"
-version = "0.3.1"
+version = "0.6.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
+checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
 dependencies = [
  "bytes",
  "futures-core",
  "futures-sink",
  "log",
- "pin-project-lite 0.1.11",
+ "pin-project-lite",
  "tokio",
 ]
 
@@ -5322,7 +5235,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
 dependencies = [
  "cfg-if 1.0.0",
- "pin-project-lite 0.2.4",
+ "pin-project-lite",
  "tracing-attributes",
  "tracing-core",
 ]
@@ -5619,7 +5532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
 dependencies = [
  "same-file",
- "winapi 0.3.9",
+ "winapi",
  "winapi-util",
 ]
 
@@ -5636,12 +5549,6 @@ dependencies = [
 
 [[package]]
 name = "winapi"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-
-[[package]]
-name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
@@ -5651,12 +5558,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "winapi-build"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
-
-[[package]]
 name = "winapi-i686-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5668,7 +5569,7 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
 
 [[package]]
@@ -5678,16 +5579,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
-name = "ws2_32-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
-[[package]]
 name = "xattr"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5749,5 +5640,5 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
 dependencies = [
- "winapi 0.3.9",
+ "winapi",
 ]
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 9f9d41c3f3d..880692516e9 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1373,50 +1373,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
         itctx: ImplTraitContext<'_, 'hir>,
     ) -> GenericsCtor<'hir> {
         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
-        // FIXME: this could probably be done with less rightward drift. It also looks like two
-        // control paths where `report_error` is called are the only paths that advance to after the
-        // match statement, so the error reporting could probably just be moved there.
         let mut add_bounds: NodeMap<Vec<_>> = Default::default();
         for pred in &generics.where_clause.predicates {
             if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
                 'next_bound: for bound in &bound_pred.bounds {
                     if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
-                        let report_error = |this: &mut Self| {
-                            this.diagnostic().span_err(
-                                bound_pred.bounded_ty.span,
-                                "`?Trait` bounds are only permitted at the \
-                                 point where a type parameter is declared",
-                            );
-                        };
                         // Check if the where clause type is a plain type parameter.
-                        match bound_pred.bounded_ty.kind {
-                            TyKind::Path(None, ref path)
-                                if path.segments.len() == 1
-                                    && bound_pred.bound_generic_params.is_empty() =>
+                        match self
+                            .resolver
+                            .get_partial_res(bound_pred.bounded_ty.id)
+                            .map(|d| (d.base_res(), d.unresolved_segments()))
+                        {
+                            Some((Res::Def(DefKind::TyParam, def_id), 0))
+                                if bound_pred.bound_generic_params.is_empty() =>
                             {
-                                if let Some(Res::Def(DefKind::TyParam, def_id)) = self
-                                    .resolver
-                                    .get_partial_res(bound_pred.bounded_ty.id)
-                                    .map(|d| d.base_res())
-                                {
-                                    if let Some(def_id) = def_id.as_local() {
-                                        for param in &generics.params {
-                                            if let GenericParamKind::Type { .. } = param.kind {
-                                                if def_id == self.resolver.local_def_id(param.id) {
-                                                    add_bounds
-                                                        .entry(param.id)
-                                                        .or_default()
-                                                        .push(bound.clone());
-                                                    continue 'next_bound;
-                                                }
-                                            }
-                                        }
+                                for param in &generics.params {
+                                    if def_id == self.resolver.local_def_id(param.id).to_def_id() {
+                                        add_bounds.entry(param.id).or_default().push(bound.clone());
+                                        continue 'next_bound;
                                     }
                                 }
-                                report_error(self)
                             }
-                            _ => report_error(self),
+                            _ => {}
                         }
+                        self.diagnostic().span_err(
+                            bound_pred.bounded_ty.span,
+                            "`?Trait` bounds are only permitted at the \
+                                 point where a type parameter is declared",
+                        );
                     }
                 }
             }
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 16151e9dca5..041d52aa20a 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -7,23 +7,26 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(allow_internal_unstable)]
 #![feature(array_windows)]
+#![feature(associated_type_bounds)]
+#![feature(auto_traits)]
+#![feature(bool_to_option)]
+#![feature(const_panic)]
 #![feature(control_flow_enum)]
+#![feature(core_intrinsics)]
+#![feature(extend_one)]
+#![feature(hash_raw_entry)]
 #![feature(in_band_lifetimes)]
+#![feature(iter_map_while)]
+#![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
-#![feature(auto_traits)]
+#![feature(min_type_alias_impl_trait)]
+#![feature(new_uninit)]
 #![feature(nll)]
-#![feature(allow_internal_unstable)]
-#![feature(hash_raw_entry)]
-#![feature(core_intrinsics)]
+#![feature(once_cell)]
 #![feature(test)]
-#![feature(associated_type_bounds)]
 #![feature(thread_id_value)]
-#![feature(extend_one)]
-#![feature(const_panic)]
-#![feature(new_uninit)]
-#![feature(once_cell)]
-#![feature(maybe_uninit_uninit_array)]
 #![allow(rustc::default_hash_types)]
 #![deny(unaligned_references)]
 
diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
index 65689ab769c..e92db9ea128 100644
--- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
@@ -1,6 +1,5 @@
 //! A variant of `SortedMap` that preserves insertion order.
 
-use std::borrow::Borrow;
 use std::hash::{Hash, Hasher};
 use std::iter::FromIterator;
 
@@ -76,11 +75,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
     ///
     /// If there are multiple items that are equivalent to `key`, they will be yielded in
     /// insertion order.
-    pub fn get_by_key<Q: 'a>(&'a self, key: &Q) -> impl 'a + Iterator<Item = &'a V>
-    where
-        Q: Ord + ?Sized,
-        K: Borrow<Q>,
-    {
+    pub fn get_by_key(&'a self, key: K) -> impl 'a + Iterator<Item = &'a V> {
         self.get_by_key_enumerated(key).map(|(_, v)| v)
     }
 
@@ -89,35 +84,12 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
     ///
     /// If there are multiple items that are equivalent to `key`, they will be yielded in
     /// insertion order.
-    pub fn get_by_key_enumerated<Q>(&self, key: &Q) -> impl '_ + Iterator<Item = (I, &V)>
-    where
-        Q: Ord + ?Sized,
-        K: Borrow<Q>,
-    {
-        match self.binary_search_idx(key) {
-            Err(_) => self.idxs_to_items_enumerated(&[]),
-
-            Ok(idx) => {
-                let start = self.idx_sorted_by_item_key[..idx]
-                    .partition_point(|&i| self.items[i].0.borrow() != key);
-                let end = idx
-                    + self.idx_sorted_by_item_key[idx..]
-                        .partition_point(|&i| self.items[i].0.borrow() == key);
-                self.idxs_to_items_enumerated(&self.idx_sorted_by_item_key[start..end])
-            }
-        }
-    }
-
-    fn binary_search_idx<Q>(&self, key: &Q) -> Result<usize, usize>
-    where
-        Q: Ord + ?Sized,
-        K: Borrow<Q>,
-    {
-        self.idx_sorted_by_item_key.binary_search_by(|&idx| self.items[idx].0.borrow().cmp(key))
-    }
-
-    fn idxs_to_items_enumerated(&'a self, idxs: &'a [I]) -> impl 'a + Iterator<Item = (I, &'a V)> {
-        idxs.iter().map(move |&idx| (idx, &self.items[idx].1))
+    pub fn get_by_key_enumerated(&'a self, key: K) -> impl '_ + Iterator<Item = (I, &V)> {
+        let lower_bound = self.idx_sorted_by_item_key.partition_point(|&i| self.items[i].0 < key);
+        self.idx_sorted_by_item_key[lower_bound..].iter().map_while(move |&i| {
+            let (k, v) = &self.items[i];
+            (k == &key).then_some((i, v))
+        })
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/sorted_map/tests.rs b/compiler/rustc_data_structures/src/sorted_map/tests.rs
index 7d91e1fdcef..1e977d709f1 100644
--- a/compiler/rustc_data_structures/src/sorted_map/tests.rs
+++ b/compiler/rustc_data_structures/src/sorted_map/tests.rs
@@ -14,11 +14,11 @@ fn test_sorted_index_multi_map() {
     }
 
     // `get_by_key` works.
-    assert_eq!(set.get_by_key(&3).copied().collect::<Vec<_>>(), vec![0]);
-    assert!(set.get_by_key(&4).next().is_none());
+    assert_eq!(set.get_by_key(3).copied().collect::<Vec<_>>(), vec![0]);
+    assert!(set.get_by_key(4).next().is_none());
 
     // `get_by_key` returns items in insertion order.
-    let twos: Vec<_> = set.get_by_key_enumerated(&2).collect();
+    let twos: Vec<_> = set.get_by_key_enumerated(2).collect();
     let idxs: Vec<usize> = twos.iter().map(|(i, _)| *i).collect();
     let values: Vec<usize> = twos.iter().map(|(_, &v)| v).collect();
 
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
index 1786fa340cc..cc7ec9432fa 100644
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ b/compiler/rustc_data_structures/src/vec_map.rs
@@ -1,6 +1,7 @@
 use std::borrow::Borrow;
+use std::fmt::Debug;
 use std::iter::FromIterator;
-use std::slice::{Iter, IterMut};
+use std::slice::Iter;
 use std::vec::IntoIter;
 
 use crate::stable_hasher::{HashStable, StableHasher};
@@ -12,7 +13,8 @@ pub struct VecMap<K, V>(Vec<(K, V)>);
 
 impl<K, V> VecMap<K, V>
 where
-    K: PartialEq,
+    K: Debug + PartialEq,
+    V: Debug,
 {
     pub fn new() -> Self {
         VecMap(Default::default())
@@ -37,14 +39,31 @@ where
         self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1)
     }
 
-    /// Returns the value corresponding to the supplied predicate filter.
+    /// Returns the any value corresponding to the supplied predicate filter.
     ///
     /// The supplied predicate will be applied to each (key, value) pair and it will return a
     /// reference to the values where the predicate returns `true`.
-    pub fn get_by(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
+    pub fn any_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
         self.0.iter().find(|kv| predicate(kv)).map(|elem| &elem.1)
     }
 
+    /// Returns the value corresponding to the supplied predicate filter. It crashes if there's
+    /// more than one matching element.
+    ///
+    /// The supplied predicate will be applied to each (key, value) pair and it will return a
+    /// reference to the value where the predicate returns `true`.
+    pub fn get_value_matching(&self, mut predicate: impl FnMut(&(K, V)) -> bool) -> Option<&V> {
+        let mut filter = self.0.iter().filter(|kv| predicate(kv));
+        let (_, value) = filter.next()?;
+        // This should return just one element, otherwise it's a bug
+        assert!(
+            filter.next().is_none(),
+            "Collection {:?} should have just one matching element",
+            self
+        );
+        Some(value)
+    }
+
     /// Returns `true` if the map contains a value for the specified key.
     ///
     /// The key may be any borrowed form of the map's key type,
@@ -67,9 +86,13 @@ where
         self.into_iter()
     }
 
-    pub fn iter_mut(&mut self) -> IterMut<'_, (K, V)> {
+    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
         self.into_iter()
     }
+
+    pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) {
+        self.0.retain(f)
+    }
 }
 
 impl<K, V> Default for VecMap<K, V> {
@@ -108,12 +131,12 @@ impl<'a, K, V> IntoIterator for &'a VecMap<K, V> {
 }
 
 impl<'a, K, V> IntoIterator for &'a mut VecMap<K, V> {
-    type Item = &'a mut (K, V);
-    type IntoIter = IterMut<'a, (K, V)>;
+    type Item = (&'a K, &'a mut V);
+    type IntoIter = impl Iterator<Item = Self::Item>;
 
     #[inline]
     fn into_iter(self) -> Self::IntoIter {
-        self.0.iter_mut()
+        self.0.iter_mut().map(|(k, v)| (&*k, v))
     }
 }
 
@@ -127,7 +150,7 @@ impl<K, V> IntoIterator for VecMap<K, V> {
     }
 }
 
-impl<K: PartialEq, V> Extend<(K, V)> for VecMap<K, V> {
+impl<K: PartialEq + Debug, V: Debug> Extend<(K, V)> for VecMap<K, V> {
     fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
         for (k, v) in iter {
             self.insert(k, v);
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 8c6aef80635..3d5bc770c4f 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1,6 +1,7 @@
 use crate::expand::{self, AstFragment, Invocation};
 use crate::module::DirOwnership;
 
+use rustc_ast::attr::MarkedAttrs;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Nonterminal};
 use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
@@ -951,6 +952,10 @@ pub struct ExtCtxt<'a> {
     ///
     /// `Ident` is the module name.
     pub(super) extern_mod_loaded: OnExternModLoaded<'a>,
+    /// When we 'expand' an inert attribute, we leave it
+    /// in the AST, but insert it here so that we know
+    /// not to expand it again.
+    pub(super) expanded_inert_attrs: MarkedAttrs,
 }
 
 impl<'a> ExtCtxt<'a> {
@@ -977,6 +982,7 @@ impl<'a> ExtCtxt<'a> {
             },
             force_mode: false,
             expansions: FxHashMap::default(),
+            expanded_inert_attrs: MarkedAttrs::new(),
         }
     }
 
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index dcd871c9d20..c72b1b33dbc 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -12,7 +12,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::token;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
-use rustc_ast::{AstLike, Block, Inline, ItemKind, Local, MacArgs};
+use rustc_ast::{AstLike, Block, Inline, ItemKind, Local, MacArgs, MacCall};
 use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, ModKind, NestedMetaItem};
 use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe};
 use rustc_ast_pretty::pprust;
@@ -26,7 +26,7 @@ use rustc_parse::parser::{
     AttemptLocalParseRecovery, ForceCollect, Parser, RecoverColon, RecoverComma,
 };
 use rustc_parse::validate_attr;
-use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
+use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::parse::{feature_err, ParseSess};
 use rustc_session::Limit;
@@ -754,7 +754,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     }
                 }
                 SyntaxExtensionKind::NonMacroAttr { mark_used } => {
-                    self.cx.sess.mark_attr_known(&attr);
+                    self.cx.expanded_inert_attrs.mark(&attr);
                     if *mark_used {
                         self.cx.sess.mark_attr_used(&attr);
                     }
@@ -1040,7 +1040,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         item.visit_attrs(|attrs| {
             attr = attrs
                 .iter()
-                .position(|a| !self.cx.sess.is_attr_known(a) && !is_builtin_attr(a))
+                .position(|a| !self.cx.expanded_inert_attrs.is_marked(a) && !is_builtin_attr(a))
                 .map(|attr_pos| {
                     let attr = attrs.remove(attr_pos);
                     let following_derives = attrs[attr_pos..]
@@ -1070,7 +1070,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
 
     // Detect use of feature-gated or invalid attributes on macro invocations
     // since they will not be detected after macro expansion.
-    fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
+    fn check_attributes(&mut self, attrs: &[ast::Attribute], call: &MacCall) {
         let features = self.cx.ecfg.features.unwrap();
         let mut attrs = attrs.iter().peekable();
         let mut span: Option<Span> = None;
@@ -1085,14 +1085,31 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                 continue;
             }
 
-            if attr.doc_str().is_some() {
+            if attr.is_doc_comment() {
                 self.cx.sess.parse_sess.buffer_lint_with_diagnostic(
                     &UNUSED_DOC_COMMENTS,
                     current_span,
-                    ast::CRATE_NODE_ID,
+                    self.cx.current_expansion.lint_node_id,
                     "unused doc comment",
                     BuiltinLintDiagnostics::UnusedDocComment(attr.span),
                 );
+            } else if rustc_attr::is_builtin_attr(attr) {
+                let attr_name = attr.ident().unwrap().name;
+                // `#[cfg]` and `#[cfg_attr]` are special - they are
+                // eagerly evaluated.
+                if attr_name != sym::cfg && attr_name != sym::cfg_attr {
+                    self.cx.sess.parse_sess.buffer_lint_with_diagnostic(
+                        &UNUSED_ATTRIBUTES,
+                        attr.span,
+                        self.cx.current_expansion.lint_node_id,
+                        &format!("unused attribute `{}`", attr_name),
+                        BuiltinLintDiagnostics::UnusedBuiltinAttribute {
+                            attr_name,
+                            macro_name: pprust::path_to_string(&call.path),
+                            invoc_span: call.path.span,
+                        },
+                    );
+                }
             }
         }
     }
@@ -1152,7 +1169,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
             }
 
             if let ast::ExprKind::MacCall(mac) = expr.kind {
-                self.check_attributes(&expr.attrs);
+                self.check_attributes(&expr.attrs, &mac);
                 self.collect_bang(mac, expr.span, AstFragmentKind::Expr).make_expr().into_inner()
             } else {
                 assign_id!(self, &mut expr.id, || {
@@ -1253,7 +1270,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
             }
 
             if let ast::ExprKind::MacCall(mac) = expr.kind {
-                self.check_attributes(&expr.attrs);
+                self.check_attributes(&expr.attrs, &mac);
                 self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr)
                     .make_opt_expr()
                     .map(|expr| expr.into_inner())
@@ -1296,7 +1313,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
 
         if let StmtKind::MacCall(mac) = stmt.kind {
             let MacCallStmt { mac, style, attrs, tokens: _ } = mac.into_inner();
-            self.check_attributes(&attrs);
+            self.check_attributes(&attrs, &mac);
             let mut placeholder =
                 self.collect_bang(mac, stmt.span, AstFragmentKind::Stmts).make_stmts();
 
@@ -1344,9 +1361,9 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         let span = item.span;
 
         match item.kind {
-            ast::ItemKind::MacCall(..) => {
+            ast::ItemKind::MacCall(ref mac) => {
+                self.check_attributes(&attrs, &mac);
                 item.attrs = attrs;
-                self.check_attributes(&item.attrs);
                 item.and_then(|item| match item.kind {
                     ItemKind::MacCall(mac) => {
                         self.collect_bang(mac, span, AstFragmentKind::Items).make_items()
@@ -1455,8 +1472,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
 
         match item.kind {
-            ast::AssocItemKind::MacCall(..) => {
-                self.check_attributes(&item.attrs);
+            ast::AssocItemKind::MacCall(ref mac) => {
+                self.check_attributes(&item.attrs, &mac);
                 item.and_then(|item| match item.kind {
                     ast::AssocItemKind::MacCall(mac) => self
                         .collect_bang(mac, item.span, AstFragmentKind::TraitItems)
@@ -1480,8 +1497,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
 
         match item.kind {
-            ast::AssocItemKind::MacCall(..) => {
-                self.check_attributes(&item.attrs);
+            ast::AssocItemKind::MacCall(ref mac) => {
+                self.check_attributes(&item.attrs, &mac);
                 item.and_then(|item| match item.kind {
                     ast::AssocItemKind::MacCall(mac) => self
                         .collect_bang(mac, item.span, AstFragmentKind::ImplItems)
@@ -1526,8 +1543,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
 
         match foreign_item.kind {
-            ast::ForeignItemKind::MacCall(..) => {
-                self.check_attributes(&foreign_item.attrs);
+            ast::ForeignItemKind::MacCall(ref mac) => {
+                self.check_attributes(&foreign_item.attrs, &mac);
                 foreign_item.and_then(|item| match item.kind {
                     ast::ForeignItemKind::MacCall(mac) => self
                         .collect_bang(mac, item.span, AstFragmentKind::ForeignItems)
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index b1c725ecd85..36d035cdfd3 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -603,6 +603,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(TEST, rustc_dump_program_clauses, AssumedUsed, template!(Word)),
     rustc_attr!(TEST, rustc_dump_env_program_clauses, AssumedUsed, template!(Word)),
     rustc_attr!(TEST, rustc_object_lifetime_default, AssumedUsed, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_vtable, AssumedUsed, template!(Word)),
     rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)),
     gated!(
         omit_gdb_pretty_printer_section, AssumedUsed, template!(Word),
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 1cde4802a40..ce1445f8a47 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -14,17 +14,17 @@ pub fn anonymize_predicate<'tcx>(
     tcx.reuse_or_mk_predicate(pred, new)
 }
 
-struct PredicateSet<'tcx> {
+pub struct PredicateSet<'tcx> {
     tcx: TyCtxt<'tcx>,
     set: FxHashSet<ty::Predicate<'tcx>>,
 }
 
 impl PredicateSet<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>) -> Self {
+    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
         Self { tcx, set: Default::default() }
     }
 
-    fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
+    pub fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
         // We have to be careful here because we want
         //
         //    for<'a> Foo<&'a i32>
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index f448acd24fc..31ce77375e5 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -734,6 +734,16 @@ pub trait LintContext: Sized {
                         Applicability::MachineApplicable,
                     );
                 }
+                BuiltinLintDiagnostics::UnusedBuiltinAttribute {
+                    attr_name,
+                    macro_name,
+                    invoc_span
+                } => {
+                    db.span_note(
+                        invoc_span,
+                        &format!("the built-in attribute `{attr_name}` will be ignored, since it's applied to the macro invocation `{macro_name}`")
+                    );
+                }
             }
             // Rewrap `db`, and pass control to the user.
             decorate(LintDiagnosticBuilder::new(db));
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index c9478016140..1786f1e7034 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -32,6 +32,7 @@
 #![feature(box_syntax)]
 #![feature(box_patterns)]
 #![feature(crate_visibility_modifier)]
+#![feature(format_args_capture)]
 #![feature(iter_order_by)]
 #![feature(iter_zip)]
 #![feature(never_type)]
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 4190e769976..ec17e7a6b03 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -296,6 +296,7 @@ pub enum BuiltinLintDiagnostics {
     DeprecatedMacro(Option<Symbol>, Span),
     MissingAbi(Span, Abi),
     UnusedDocComment(Span),
+    UnusedBuiltinAttribute { attr_name: Symbol, macro_name: String, invoc_span: Span },
     PatternsInFnsWithoutBody(Span, Ident),
     LegacyDeriveHelpers(Span),
     ExternDepSpec(String, ExternDepSpec),
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 028104fd6b5..4936b22c7b9 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -1080,7 +1080,10 @@ impl CrateError {
                                 locator.triple
                             ));
                         }
-                        if missing_core && std::env::var("RUSTUP_HOME").is_ok() {
+                        // NOTE: this suggests using rustup, even though the user may not have it installed.
+                        // That's because they could choose to install it; or this may give them a hint which
+                        // target they need to install from their distro.
+                        if missing_core {
                             err.help(&format!(
                                 "consider downloading the target with `rustup target add {}`",
                                 locator.triple
@@ -1097,7 +1100,7 @@ impl CrateError {
                                 current_crate
                             ));
                         }
-                        if sess.is_nightly_build() && std::env::var("CARGO").is_ok() {
+                        if sess.is_nightly_build() {
                             err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
                         }
                     } else if Some(crate_name)
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index d005f63ed43..2d177551664 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -124,7 +124,7 @@ impl<'tcx> AssocItems<'tcx> {
         &self,
         name: Symbol,
     ) -> impl '_ + Iterator<Item = &ty::AssocItem> {
-        self.items.get_by_key(&name).copied()
+        self.items.get_by_key(name).copied()
     }
 
     /// Returns an iterator over all associated items with the given name.
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 96aae3bd70c..f1c7c1ea852 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -628,6 +628,7 @@ impl<T> Trait<T> for X {
                             assoc_substs,
                             ty,
                             msg,
+                            false,
                         ) {
                             return true;
                         }
@@ -646,6 +647,7 @@ impl<T> Trait<T> for X {
                             assoc_substs,
                             ty,
                             msg,
+                            false,
                         );
                     }
                 }
@@ -771,13 +773,24 @@ fn foo(&self) -> Self::T { String::new() }
     ) -> bool {
         let assoc = self.associated_item(proj_ty.item_def_id);
         if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
-            self.constrain_associated_type_structured_suggestion(
+            let opaque_local_def_id = def_id.expect_local();
+            let opaque_hir_id = self.hir().local_def_id_to_hir_id(opaque_local_def_id);
+            let opaque_hir_ty = match &self.hir().expect_item(opaque_hir_id).kind {
+                hir::ItemKind::OpaqueTy(opaque_hir_ty) => opaque_hir_ty,
+                _ => bug!("The HirId comes from a `ty::Opaque`"),
+            };
+
+            let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
+
+            self.constrain_generic_bound_associated_type_structured_suggestion(
                 db,
-                self.def_span(def_id),
-                &assoc,
-                proj_ty.trait_ref_and_own_substs(self).1,
+                &trait_ref,
+                opaque_hir_ty.bounds,
+                assoc,
+                assoc_substs,
                 ty,
-                &msg,
+                msg,
+                true,
             )
         } else {
             false
@@ -899,6 +912,11 @@ fn foo(&self) -> Self::T { String::new() }
 
     /// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
     /// requirement, provide a structured suggestion to constrain it to a given type `ty`.
+    ///
+    /// `is_bound_surely_present` indicates whether we know the bound we're looking for is
+    /// inside `bounds`. If that's the case then we can consider `bounds` containing only one
+    /// trait bound as the one we're looking for. This can help in cases where the associated
+    /// type is defined on a supertrait of the one present in the bounds.
     fn constrain_generic_bound_associated_type_structured_suggestion(
         self,
         db: &mut DiagnosticBuilder<'_>,
@@ -908,23 +926,30 @@ fn foo(&self) -> Self::T { String::new() }
         assoc_substs: &[ty::GenericArg<'tcx>],
         ty: Ty<'tcx>,
         msg: &str,
+        is_bound_surely_present: bool,
     ) -> bool {
         // FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
-        bounds.iter().any(|bound| match bound {
-            hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => {
-                // Relate the type param against `T` in `<A as T>::Foo`.
-                ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id)
-                    && self.constrain_associated_type_structured_suggestion(
-                        db,
-                        ptr.span,
-                        assoc,
-                        assoc_substs,
-                        ty,
-                        msg,
-                    )
-            }
-            _ => false,
-        })
+
+        let trait_bounds = bounds.iter().filter_map(|bound| match bound {
+            hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr),
+            _ => None,
+        });
+
+        let matching_trait_bounds = trait_bounds
+            .clone()
+            .filter(|ptr| ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id))
+            .collect::<Vec<_>>();
+
+        let span = match &matching_trait_bounds[..] {
+            &[ptr] => ptr.span,
+            &[] if is_bound_surely_present => match &trait_bounds.collect::<Vec<_>>()[..] {
+                &[ptr] => ptr.span,
+                _ => return false,
+            },
+            _ => return false,
+        };
+
+        self.constrain_associated_type_structured_suggestion(db, span, assoc, assoc_substs, ty, msg)
     }
 
     /// Given a span corresponding to a bound, provide a structured suggestion to set an
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index 78109fc7b57..5904f133e78 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -1,17 +1,39 @@
 use std::convert::TryFrom;
+use std::fmt;
 
 use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar, ScalarMaybeUninit};
-use crate::ty::fold::TypeFoldable;
-use crate::ty::{self, DefId, SubstsRef, Ty, TyCtxt};
+use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
 use rustc_ast::Mutability;
 
-#[derive(Clone, Copy, Debug, PartialEq, HashStable)]
+#[derive(Clone, Copy, PartialEq, HashStable)]
 pub enum VtblEntry<'tcx> {
+    /// destructor of this type (used in vtable header)
     MetadataDropInPlace,
+    /// layout size of this type (used in vtable header)
     MetadataSize,
+    /// layout align of this type (used in vtable header)
     MetadataAlign,
+    /// non-dispatchable associated function that is excluded from trait object
     Vacant,
-    Method(DefId, SubstsRef<'tcx>),
+    /// dispatchable associated function
+    Method(Instance<'tcx>),
+    /// pointer to a separate supertrait vtable, can be used by trait upcasting coercion
+    TraitVPtr(PolyTraitRef<'tcx>),
+}
+
+impl<'tcx> fmt::Debug for VtblEntry<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // We want to call `Display` on `Instance` and `PolyTraitRef`,
+        // so we implement this manually.
+        match self {
+            VtblEntry::MetadataDropInPlace => write!(f, "MetadataDropInPlace"),
+            VtblEntry::MetadataSize => write!(f, "MetadataSize"),
+            VtblEntry::MetadataAlign => write!(f, "MetadataAlign"),
+            VtblEntry::Vacant => write!(f, "Vacant"),
+            VtblEntry::Method(instance) => write!(f, "Method({})", instance),
+            VtblEntry::TraitVPtr(trait_ref) => write!(f, "TraitVPtr({})", trait_ref),
+        }
+    }
 }
 
 pub const COMMON_VTABLE_ENTRIES: &[VtblEntry<'_>] =
@@ -36,11 +58,6 @@ impl<'tcx> TyCtxt<'tcx> {
         }
         drop(vtables_cache);
 
-        // See https://github.com/rust-lang/rust/pull/86475#discussion_r655162674
-        assert!(
-            !ty.needs_subst() && !poly_trait_ref.map_or(false, |trait_ref| trait_ref.needs_subst())
-        );
-        let param_env = ty::ParamEnv::reveal_all();
         let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
             let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
             let trait_ref = tcx.erase_regions(trait_ref);
@@ -50,8 +67,9 @@ impl<'tcx> TyCtxt<'tcx> {
             COMMON_VTABLE_ENTRIES
         };
 
-        let layout =
-            tcx.layout_of(param_env.and(ty)).expect("failed to build vtable representation");
+        let layout = tcx
+            .layout_of(ty::ParamEnv::reveal_all().and(ty))
+            .expect("failed to build vtable representation");
         assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
         let size = layout.size.bytes();
         let align = layout.align.abi.bytes();
@@ -79,19 +97,21 @@ impl<'tcx> TyCtxt<'tcx> {
                 VtblEntry::MetadataSize => Scalar::from_uint(size, ptr_size).into(),
                 VtblEntry::MetadataAlign => Scalar::from_uint(align, ptr_size).into(),
                 VtblEntry::Vacant => continue,
-                VtblEntry::Method(def_id, substs) => {
-                    // See https://github.com/rust-lang/rust/pull/86475#discussion_r655162674
-                    assert!(!substs.needs_subst());
-
+                VtblEntry::Method(instance) => {
                     // Prepare the fn ptr we write into the vtable.
-                    let instance =
-                        ty::Instance::resolve_for_vtable(tcx, param_env, *def_id, substs)
-                            .expect("resolution failed during building vtable representation")
-                            .polymorphize(tcx);
+                    let instance = instance.polymorphize(tcx);
                     let fn_alloc_id = tcx.create_fn_alloc(instance);
                     let fn_ptr = Pointer::from(fn_alloc_id);
                     ScalarMaybeUninit::from_pointer(fn_ptr, &tcx)
                 }
+                VtblEntry::TraitVPtr(trait_ref) => {
+                    let super_trait_ref = trait_ref.map_bound(|trait_ref| {
+                        ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+                    });
+                    let supertrait_alloc_id = self.vtable_allocation(ty, Some(super_trait_ref));
+                    let vptr = Pointer::from(supertrait_alloc_id);
+                    ScalarMaybeUninit::from_pointer(vptr, &tcx)
+                }
             };
             vtable
                 .write_scalar(&tcx, alloc_range(ptr_size * idx, ptr_size), scalar)
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 aa3ff98f7ff..3fb06cd2f5f 100644
--- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs
@@ -26,7 +26,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts};
+use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
 use rustc_middle::ty::{
     self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
     ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness,
@@ -60,7 +60,6 @@ use crate::borrow_check::{
         LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
     },
     region_infer::{ClosureRegionRequirementsExt, TypeTest},
-    renumber,
     type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
     universal_regions::{DefiningTy, UniversalRegions},
     Upvar,
@@ -180,7 +179,54 @@ pub(crate) fn type_check<'mir, 'tcx>(
             liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
 
             translate_outlives_facts(&mut cx);
-            cx.opaque_type_values
+            let mut opaque_type_values = cx.opaque_type_values;
+
+            for (_, revealed_ty) in &mut opaque_type_values {
+                *revealed_ty = infcx.resolve_vars_if_possible(*revealed_ty);
+                if revealed_ty.has_infer_types_or_consts() {
+                    infcx.tcx.sess.delay_span_bug(
+                        body.span,
+                        &format!("could not resolve {:#?}", revealed_ty.kind()),
+                    );
+                    *revealed_ty = infcx.tcx.ty_error();
+                }
+            }
+
+            opaque_type_values.retain(|(opaque_type_key, resolved_ty)| {
+                let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
+                    *def_id == opaque_type_key.def_id
+                } else {
+                    false
+                };
+
+                if concrete_is_opaque {
+                    // We're using an opaque `impl Trait` type without
+                    // 'revealing' it. For example, code like this:
+                    //
+                    // type Foo = impl Debug;
+                    // fn foo1() -> Foo { ... }
+                    // fn foo2() -> Foo { foo1() }
+                    //
+                    // In `foo2`, we're not revealing the type of `Foo` - we're
+                    // just treating it as the opaque type.
+                    //
+                    // When this occurs, we do *not* want to try to equate
+                    // the concrete type with the underlying defining type
+                    // of the opaque type - this will always fail, since
+                    // the defining type of an opaque type is always
+                    // some other type (e.g. not itself)
+                    // Essentially, none of the normal obligations apply here -
+                    // we're just passing around some unknown opaque type,
+                    // without actually looking at the underlying type it
+                    // gets 'revealed' into
+                    debug!(
+                        "eq_opaque_type_and_type: non-defining use of {:?}",
+                        opaque_type_key.def_id,
+                    );
+                }
+                !concrete_is_opaque
+            });
+            opaque_type_values
         },
     );
 
@@ -1239,14 +1285,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             return Ok(());
         }
 
-        let infcx = self.infcx;
-        let tcx = infcx.tcx;
         let param_env = self.param_env;
         let body = self.body;
         let mir_def_id = body.source.def_id().expect_local();
 
-        // the "concrete opaque types" maps
-        let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types;
         let mut opaque_type_values = VecMap::new();
 
         debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
@@ -1296,88 +1338,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             .eq(output_ty, revealed_ty)?,
                     );
 
-                    // For each opaque type `Foo<T>` inferred by this value, we want to equate
-                    // the inference variable `?T` with the revealed type that was computed
-                    // earlier by type check.
                     for &(opaque_type_key, opaque_decl) in &opaque_type_map {
-                        let resolved_ty = infcx.resolve_vars_if_possible(opaque_decl.concrete_ty);
-                        let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() {
-                            *def_id == opaque_type_key.def_id
-                        } else {
-                            false
-                        };
-
-                        // The revealed type computed by the earlier phase of type check.
-                        // In our example, this would be `(U, u32)`. Note that this references
-                        // the type parameter `U` from the definition of `Foo`.
-                        let concrete_ty = match concrete_opaque_types
-                            .get_by(|(key, _)| key.def_id == opaque_type_key.def_id)
-                        {
-                            None => {
-                                if !concrete_is_opaque {
-                                    tcx.sess.delay_span_bug(
-                                        body.span,
-                                        &format!(
-                                            "Non-defining use of {:?} with revealed type",
-                                            opaque_type_key.def_id,
-                                        ),
-                                    );
-                                }
-                                continue;
-                            }
-                            Some(concrete_ty) => concrete_ty,
-                        };
-                        debug!("concrete_ty = {:?}", concrete_ty);
-
-                        // Apply the substitution, in this case `[U -> T]`, so that the
-                        // concrete type becomes `Foo<(T, u32)>`
-                        let subst_opaque_defn_ty = concrete_ty.subst(tcx, opaque_type_key.substs);
-
-                        // "Renumber" this, meaning that we replace all the regions
-                        // with fresh inference variables. Not relevant to our example.
-                        let renumbered_opaque_defn_ty =
-                            renumber::renumber_regions(infcx, subst_opaque_defn_ty);
-
-                        debug!(
-                            "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
-                            concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
-                        );
-
-                        if !concrete_is_opaque {
-                            // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`,
-                            // in our example) with the renumbered version that we took from
-                            // the type check results (`Foo<(T, u32)>`).
-                            obligations.add(
-                                infcx
-                                    .at(&ObligationCause::dummy(), param_env)
-                                    .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
-                            );
-                            opaque_type_values.insert(opaque_type_key, renumbered_opaque_defn_ty);
-                        } else {
-                            // We're using an opaque `impl Trait` type without
-                            // 'revealing' it. For example, code like this:
-                            //
-                            // type Foo = impl Debug;
-                            // fn foo1() -> Foo { ... }
-                            // fn foo2() -> Foo { foo1() }
-                            //
-                            // In `foo2`, we're not revealing the type of `Foo` - we're
-                            // just treating it as the opaque type.
-                            //
-                            // When this occurs, we do *not* want to try to equate
-                            // the concrete type with the underlying defining type
-                            // of the opaque type - this will always fail, since
-                            // the defining type of an opaque type is always
-                            // some other type (e.g. not itself)
-                            // Essentially, none of the normal obligations apply here -
-                            // we're just passing around some unknown opaque type,
-                            // without actually looking at the underlying type it
-                            // gets 'revealed' into
-                            debug!(
-                                "eq_opaque_type_and_type: non-defining use of {:?}",
-                                opaque_type_key.def_id,
-                            );
-                        }
+                        opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty);
                     }
 
                     debug!("eq_opaque_type_and_type: equated");
@@ -1405,7 +1367,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     locations,
                     ConstraintCategory::OpaqueType,
                     CustomTypeOp::new(
-                        |_cx| {
+                        |infcx| {
                             infcx.constrain_opaque_type(
                                 opaque_type_key,
                                 &opaque_decl,
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs
index 2ce7cf71116..95c4237f383 100644
--- a/compiler/rustc_mir/src/monomorphize/collector.rs
+++ b/compiler/rustc_mir/src/monomorphize/collector.rs
@@ -1116,13 +1116,13 @@ fn create_mono_items_for_vtable_methods<'tcx>(
                     | VtblEntry::MetadataSize
                     | VtblEntry::MetadataAlign
                     | VtblEntry::Vacant => None,
-                    VtblEntry::Method(def_id, substs) => ty::Instance::resolve_for_vtable(
-                        tcx,
-                        ty::ParamEnv::reveal_all(),
-                        *def_id,
-                        substs,
-                    )
-                    .filter(|instance| should_codegen_locally(tcx, instance)),
+                    VtblEntry::TraitVPtr(_) => {
+                        // all super trait items already covered, so skip them.
+                        None
+                    }
+                    VtblEntry::Method(instance) => {
+                        Some(*instance).filter(|instance| should_codegen_locally(tcx, instance))
+                    }
                 })
                 .map(|item| create_fn_mono_item(tcx, item, source));
             output.extend(methods);
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 713d572b93a..b71ec700f81 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -134,6 +134,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
     }
 
+    #[allow(dead_code)] // FIXME(81658): should be used + lint reinstated after #83171 relands.
     fn handle_assign(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if self
             .typeck_results()
@@ -150,6 +151,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
     }
 
+    #[allow(dead_code)] // FIXME(81658): should be used + lint reinstated after #83171 relands.
     fn check_for_self_assign(&mut self, assign: &'tcx hir::Expr<'tcx>) {
         fn check_for_self_assign_helper(
             tcx: TyCtxt<'tcx>,
@@ -338,12 +340,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
             hir::ExprKind::MethodCall(..) => {
                 self.lookup_and_handle_method(expr.hir_id);
             }
-            hir::ExprKind::Assign(ref left, ref right, ..) => {
-                self.handle_assign(left);
-                self.check_for_self_assign(expr);
-                self.visit_expr(right);
-                return;
-            }
             hir::ExprKind::Field(ref lhs, ..) => {
                 self.handle_field_access(&lhs, expr.hir_id);
             }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 86d495c3353..369af437c43 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -219,7 +219,6 @@ pub struct Session {
     /// Set of enabled features for the current target.
     pub target_features: FxHashSet<Symbol>,
 
-    known_attrs: Lock<MarkedAttrs>,
     used_attrs: Lock<MarkedAttrs>,
 
     /// `Span`s for `if` conditions that we have suggested turning into `if let`.
@@ -1076,14 +1075,6 @@ impl Session {
             == config::InstrumentCoverage::ExceptUnusedFunctions
     }
 
-    pub fn mark_attr_known(&self, attr: &Attribute) {
-        self.known_attrs.lock().mark(attr)
-    }
-
-    pub fn is_attr_known(&self, attr: &Attribute) -> bool {
-        self.known_attrs.lock().is_marked(attr)
-    }
-
     pub fn mark_attr_used(&self, attr: &Attribute) {
         self.used_attrs.lock().mark(attr)
     }
@@ -1389,7 +1380,6 @@ pub fn build_session(
         miri_unleashed_features: Lock::new(Default::default()),
         asm_arch,
         target_features: FxHashSet::default(),
-        known_attrs: Lock::new(MarkedAttrs::new()),
         used_attrs: Lock::new(MarkedAttrs::new()),
         if_let_suggestions: Default::default(),
     };
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a8f969782b2..c0f63f40853 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1047,6 +1047,7 @@ symbols! {
         rustc_dump_env_program_clauses,
         rustc_dump_program_clauses,
         rustc_dump_user_substs,
+        rustc_dump_vtable,
         rustc_error,
         rustc_evaluate_where_clauses,
         rustc_expected_cgu_reuse,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0185132ee36..ad84e07edfb 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -802,6 +802,7 @@ supported_targets! {
     ("armv6-unknown-freebsd", armv6_unknown_freebsd),
     ("armv7-unknown-freebsd", armv7_unknown_freebsd),
     ("i686-unknown-freebsd", i686_unknown_freebsd),
+    ("powerpc-unknown-freebsd", powerpc_unknown_freebsd),
     ("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
     ("powerpc64le-unknown-freebsd", powerpc64le_unknown_freebsd),
     ("x86_64-unknown-freebsd", x86_64_unknown_freebsd),
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
new file mode 100644
index 00000000000..e11318027d5
--- /dev/null
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
@@ -0,0 +1,27 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::freebsd_base::opts();
+    base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string());
+    // Extra hint to linker that we are generating secure-PLT code.
+    base.pre_link_args
+        .entry(LinkerFlavor::Gcc)
+        .or_default()
+        .push("--target=powerpc-unknown-freebsd13.0".to_string());
+    base.max_atomic_width = Some(32);
+
+    Target {
+        llvm_target: "powerpc-unknown-freebsd13.0".to_string(),
+        pointer_width: 32,
+        data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
+        arch: "powerpc".to_string(),
+        options: TargetOptions {
+            endian: Endian::Big,
+            features: "+secure-plt".to_string(),
+            relocation_model: RelocModel::Pic,
+            mcount: "_mcount".to_string(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index e932b1bca7c..017a7c45bbf 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -31,6 +31,8 @@ extern crate rustc_data_structures;
 extern crate tracing;
 #[macro_use]
 extern crate rustc_middle;
+#[macro_use]
+extern crate smallvec;
 
 pub mod autoderef;
 pub mod infer;
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 39013a317fd..95c81c5c729 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -83,6 +83,7 @@ pub struct OpaqueTypeDecl<'tcx> {
 }
 
 /// Whether member constraints should be generated for all opaque types
+#[derive(Debug)]
 pub enum GenerateMemberConstraints {
     /// The default, used by typeck
     WhenRequired,
@@ -354,8 +355,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         opaque_types: &OpaqueTypeMap<'tcx>,
         free_region_relations: &FRR,
     ) {
-        debug!("constrain_opaque_types()");
-
         for &(opaque_type_key, opaque_defn) in opaque_types {
             self.constrain_opaque_type(
                 opaque_type_key,
@@ -367,6 +366,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     }
 
     /// See `constrain_opaque_types` for documentation.
+    #[instrument(level = "debug", skip(self, free_region_relations))]
     fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
@@ -376,15 +376,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     ) {
         let def_id = opaque_type_key.def_id;
 
-        debug!("constrain_opaque_type()");
-        debug!("constrain_opaque_type: def_id={:?}", def_id);
-        debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn);
-
         let tcx = self.tcx;
 
         let concrete_ty = self.resolve_vars_if_possible(opaque_defn.concrete_ty);
 
-        debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);
+        debug!(?concrete_ty);
 
         let first_own_region = match opaque_defn.origin {
             hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
@@ -397,7 +393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 // type foo::<'p0..'pn>::Foo<'q0..'qm>
                 // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
                 //
-                // For these types we onlt iterate over `'l0..lm` below.
+                // For these types we only iterate over `'l0..lm` below.
                 tcx.generics_of(def_id).parent_count
             }
             // These opaque type inherit all lifetime parameters from their
@@ -410,10 +406,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         // If there are required region bounds, we can use them.
         if opaque_defn.has_required_region_bounds {
             let bounds = tcx.explicit_item_bounds(def_id);
-            debug!("constrain_opaque_type: predicates: {:#?}", bounds);
+            debug!("{:#?}", bounds);
             let bounds: Vec<_> =
                 bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_type_key.substs)).collect();
-            debug!("constrain_opaque_type: bounds={:#?}", bounds);
+            debug!("{:#?}", bounds);
             let opaque_type = tcx.mk_opaque(def_id, opaque_type_key.substs);
 
             let required_region_bounds =
@@ -452,8 +448,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             };
 
             // Compute the least upper bound of it with the other regions.
-            debug!("constrain_opaque_types: least_region={:?}", least_region);
-            debug!("constrain_opaque_types: subst_region={:?}", subst_region);
+            debug!(?least_region);
+            debug!(?subst_region);
             match least_region {
                 None => least_region = Some(subst_region),
                 Some(lr) => {
@@ -484,7 +480,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         }
 
         let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
-        debug!("constrain_opaque_types: least_region={:?}", least_region);
+        debug!(?least_region);
 
         if let GenerateMemberConstraints::IfNoStaticBound = mode {
             if least_region != tcx.lifetimes.re_static {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 1c6a83b5783..9a33875d6e4 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1857,12 +1857,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 }
             }
             GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
+                // `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync`
+                let refers_to_non_sync = match target_ty.kind() {
+                    ty::Ref(_, ref_ty, _) => match self.evaluate_obligation(&obligation) {
+                        Ok(eval) if !eval.may_apply() => Some(ref_ty),
+                        _ => None,
+                    },
+                    _ => None,
+                };
+
+                let (span_label, span_note) = match refers_to_non_sync {
+                    // if `target_ty` is `&T` and `T` fails to impl `Sync`,
+                    // include suggestions to make `T: Sync` so that `&T: Send`
+                    Some(ref_ty) => (
+                        format!(
+                            "has type `{}` which {}, because `{}` is not `Sync`",
+                            target_ty, trait_explanation, ref_ty
+                        ),
+                        format!(
+                            "captured value {} because `&` references cannot be sent unless their referent is `Sync`",
+                            trait_explanation
+                        ),
+                    ),
+                    None => (
+                        format!("has type `{}` which {}", target_ty, trait_explanation),
+                        format!("captured value {}", trait_explanation),
+                    ),
+                };
+
                 let mut span = MultiSpan::from_span(upvar_span);
-                span.push_span_label(
-                    upvar_span,
-                    format!("has type `{}` which {}", target_ty, trait_explanation),
-                );
-                err.span_note(span, &format!("captured value {}", trait_explanation));
+                span.push_span_label(upvar_span, span_label);
+                err.span_note(span, &span_note);
             }
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 3a80e720e8c..693384602a7 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -34,9 +34,11 @@ use rustc_middle::ty::{
     self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry, WithConstness,
     COMMON_VTABLE_ENTRIES,
 };
-use rustc_span::Span;
+use rustc_span::{sym, Span};
+use smallvec::SmallVec;
 
 use std::fmt::Debug;
+use std::ops::ControlFlow;
 
 pub use self::FulfillmentErrorCode::*;
 pub use self::ImplSource::*;
@@ -454,6 +456,174 @@ fn subst_and_check_impossible_predicates<'tcx>(
     result
 }
 
+#[derive(Clone, Debug)]
+enum VtblSegment<'tcx> {
+    MetadataDSA,
+    TraitOwnEntries { trait_ref: ty::PolyTraitRef<'tcx>, emit_vptr: bool },
+}
+
+/// Prepare the segments for a vtable
+fn prepare_vtable_segments<'tcx, T>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::PolyTraitRef<'tcx>,
+    mut segment_visitor: impl FnMut(VtblSegment<'tcx>) -> ControlFlow<T>,
+) -> Option<T> {
+    // The following constraints holds for the final arrangement.
+    // 1. The whole virtual table of the first direct super trait is included as the
+    //    the prefix. If this trait doesn't have any super traits, then this step
+    //    consists of the dsa metadata.
+    // 2. Then comes the proper pointer metadata(vptr) and all own methods for all
+    //    other super traits except those already included as part of the first
+    //    direct super trait virtual table.
+    // 3. finally, the own methods of this trait.
+
+    // This has the advantage that trait upcasting to the first direct super trait on each level
+    // is zero cost, and to another trait includes only replacing the pointer with one level indirection,
+    // while not using too much extra memory.
+
+    // For a single inheritance relationship like this,
+    //   D --> C --> B --> A
+    // The resulting vtable will consists of these segments:
+    //  DSA, A, B, C, D
+
+    // For a multiple inheritance relationship like this,
+    //   D --> C --> A
+    //           \-> B
+    // The resulting vtable will consists of these segments:
+    //  DSA, A, B, B-vptr, C, D
+
+    // For a diamond inheritance relationship like this,
+    //   D --> B --> A
+    //     \-> C -/
+    // The resulting vtable will consists of these segments:
+    //  DSA, A, B, C, C-vptr, D
+
+    // For a more complex inheritance relationship like this:
+    //   O --> G --> C --> A
+    //     \     \     \-> B
+    //     |     |-> F --> D
+    //     |           \-> E
+    //     |-> N --> J --> H
+    //           \     \-> I
+    //           |-> M --> K
+    //                 \-> L
+    // The resulting vtable will consists of these segments:
+    //  DSA, A, B, B-vptr, C, D, D-vptr, E, E-vptr, F, F-vptr, G,
+    //  H, H-vptr, I, I-vptr, J, J-vptr, K, K-vptr, L, L-vptr, M, M-vptr,
+    //  N, N-vptr, O
+
+    // emit dsa segment first.
+    if let ControlFlow::Break(v) = (segment_visitor)(VtblSegment::MetadataDSA) {
+        return Some(v);
+    }
+
+    let mut emit_vptr_on_new_entry = false;
+    let mut visited = util::PredicateSet::new(tcx);
+    let predicate = trait_ref.without_const().to_predicate(tcx);
+    let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> =
+        smallvec![(trait_ref, emit_vptr_on_new_entry, None)];
+    visited.insert(predicate);
+
+    // the main traversal loop:
+    // basically we want to cut the inheritance directed graph into a few non-overlapping slices of nodes
+    // that each node is emited after all its descendents have been emitted.
+    // so we convert the directed graph into a tree by skipping all previously visted nodes using a visited set.
+    // this is done on the fly.
+    // Each loop run emits a slice - it starts by find a "childless" unvisited node, backtracking upwards, and it
+    // stops after it finds a node that has a next-sibling node.
+    // This next-sibling node will used as the starting point of next slice.
+
+    // Example:
+    // For a diamond inheritance relationship like this,
+    //   D#1 --> B#0 --> A#0
+    //     \-> C#1 -/
+
+    // Starting point 0 stack [D]
+    // Loop run #0: Stack after diving in is [D B A], A is "childless"
+    // after this point, all newly visited nodes won't have a vtable that equals to a prefix of this one.
+    // Loop run #0: Emiting the slice [B A] (in reverse order), B has a next-sibling node, so this slice stops here.
+    // Loop run #0: Stack after exiting out is [D C], C is the next starting point.
+    // Loop run #1: Stack after diving in is [D C], C is "childless", since its child A is skipped(already emitted).
+    // Loop run #1: Emiting the slice [D C] (in reverse order). No one has a next-sibling node.
+    // Loop run #1: Stack after exiting out is []. Now the function exits.
+
+    loop {
+        // dive deeper into the stack, recording the path
+        'diving_in: loop {
+            if let Some((inner_most_trait_ref, _, _)) = stack.last() {
+                let inner_most_trait_ref = *inner_most_trait_ref;
+                let mut direct_super_traits_iter = tcx
+                    .super_predicates_of(inner_most_trait_ref.def_id())
+                    .predicates
+                    .into_iter()
+                    .filter_map(move |(pred, _)| {
+                        pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_ref()
+                    });
+
+                'diving_in_skip_visited_traits: loop {
+                    if let Some(next_super_trait) = direct_super_traits_iter.next() {
+                        if visited.insert(next_super_trait.to_predicate(tcx)) {
+                            stack.push((
+                                next_super_trait.value,
+                                emit_vptr_on_new_entry,
+                                Some(direct_super_traits_iter),
+                            ));
+                            break 'diving_in_skip_visited_traits;
+                        } else {
+                            continue 'diving_in_skip_visited_traits;
+                        }
+                    } else {
+                        break 'diving_in;
+                    }
+                }
+            }
+        }
+
+        // Other than the left-most path, vptr should be emitted for each trait.
+        emit_vptr_on_new_entry = true;
+
+        // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
+        'exiting_out: loop {
+            if let Some((inner_most_trait_ref, emit_vptr, siblings_opt)) = stack.last_mut() {
+                if let ControlFlow::Break(v) = (segment_visitor)(VtblSegment::TraitOwnEntries {
+                    trait_ref: *inner_most_trait_ref,
+                    emit_vptr: *emit_vptr,
+                }) {
+                    return Some(v);
+                }
+
+                'exiting_out_skip_visited_traits: loop {
+                    if let Some(siblings) = siblings_opt {
+                        if let Some(next_inner_most_trait_ref) = siblings.next() {
+                            if visited.insert(next_inner_most_trait_ref.to_predicate(tcx)) {
+                                *inner_most_trait_ref = next_inner_most_trait_ref.value;
+                                *emit_vptr = emit_vptr_on_new_entry;
+                                break 'exiting_out;
+                            } else {
+                                continue 'exiting_out_skip_visited_traits;
+                            }
+                        }
+                    }
+                    stack.pop();
+                    continue 'exiting_out;
+                }
+            }
+            // all done
+            return None;
+        }
+    }
+}
+
+fn dump_vtable_entries<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    sp: Span,
+    trait_ref: ty::PolyTraitRef<'tcx>,
+    entries: &[VtblEntry<'tcx>],
+) {
+    let msg = format!("Vtable entries for `{}`: {:#?}", trait_ref, entries);
+    tcx.sess.struct_span_err(sp, &msg).emit();
+}
+
 /// Given a trait `trait_ref`, iterates the vtable entries
 /// that come from `trait_ref`, including its supertraits.
 fn vtable_entries<'tcx>(
@@ -462,57 +632,86 @@ fn vtable_entries<'tcx>(
 ) -> &'tcx [VtblEntry<'tcx>] {
     debug!("vtable_entries({:?})", trait_ref);
 
-    let entries = COMMON_VTABLE_ENTRIES.iter().cloned().chain(
-        supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
-            let trait_methods = tcx
-                .associated_items(trait_ref.def_id())
-                .in_definition_order()
-                .filter(|item| item.kind == ty::AssocKind::Fn);
-
-            // Now list each method's DefId and InternalSubsts (for within its trait).
-            // If the method can never be called from this object, produce `Vacant`.
-            trait_methods.map(move |trait_method| {
-                debug!("vtable_entries: trait_method={:?}", trait_method);
-                let def_id = trait_method.def_id;
-
-                // Some methods cannot be called on an object; skip those.
-                if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) {
-                    debug!("vtable_entries: not vtable safe");
-                    return VtblEntry::Vacant;
-                }
+    let mut entries = vec![];
 
-                // The method may have some early-bound lifetimes; add regions for those.
-                let substs = trait_ref.map_bound(|trait_ref| {
-                    InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind {
-                        GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
-                        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
-                            trait_ref.substs[param.index as usize]
-                        }
-                    })
+    let vtable_segment_callback = |segment| -> ControlFlow<()> {
+        match segment {
+            VtblSegment::MetadataDSA => {
+                entries.extend(COMMON_VTABLE_ENTRIES);
+            }
+            VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
+                let trait_methods = tcx
+                    .associated_items(trait_ref.def_id())
+                    .in_definition_order()
+                    .filter(|item| item.kind == ty::AssocKind::Fn);
+                // Now list each method's DefId and InternalSubsts (for within its trait).
+                // If the method can never be called from this object, produce `Vacant`.
+                let own_entries = trait_methods.map(move |trait_method| {
+                    debug!("vtable_entries: trait_method={:?}", trait_method);
+                    let def_id = trait_method.def_id;
+
+                    // Some methods cannot be called on an object; skip those.
+                    if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) {
+                        debug!("vtable_entries: not vtable safe");
+                        return VtblEntry::Vacant;
+                    }
+
+                    // The method may have some early-bound lifetimes; add regions for those.
+                    let substs = trait_ref.map_bound(|trait_ref| {
+                        InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind {
+                            GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
+                            GenericParamDefKind::Type { .. }
+                            | GenericParamDefKind::Const { .. } => {
+                                trait_ref.substs[param.index as usize]
+                            }
+                        })
+                    });
+
+                    // The trait type may have higher-ranked lifetimes in it;
+                    // erase them if they appear, so that we get the type
+                    // at some particular call site.
+                    let substs = tcx
+                        .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), substs);
+
+                    // It's possible that the method relies on where-clauses that
+                    // do not hold for this particular set of type parameters.
+                    // Note that this method could then never be called, so we
+                    // do not want to try and codegen it, in that case (see #23435).
+                    let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
+                    if impossible_predicates(tcx, predicates.predicates) {
+                        debug!("vtable_entries: predicates do not hold");
+                        return VtblEntry::Vacant;
+                    }
+
+                    let instance = ty::Instance::resolve_for_vtable(
+                        tcx,
+                        ty::ParamEnv::reveal_all(),
+                        def_id,
+                        substs,
+                    )
+                    .expect("resolution failed during building vtable representation");
+                    VtblEntry::Method(instance)
                 });
 
-                // The trait type may have higher-ranked lifetimes in it;
-                // erase them if they appear, so that we get the type
-                // at some particular call site.
-                let substs =
-                    tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), substs);
-
-                // It's possible that the method relies on where-clauses that
-                // do not hold for this particular set of type parameters.
-                // Note that this method could then never be called, so we
-                // do not want to try and codegen it, in that case (see #23435).
-                let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
-                if impossible_predicates(tcx, predicates.predicates) {
-                    debug!("vtable_entries: predicates do not hold");
-                    return VtblEntry::Vacant;
+                entries.extend(own_entries);
+
+                if emit_vptr {
+                    entries.push(VtblEntry::TraitVPtr(trait_ref));
                 }
+            }
+        }
 
-                VtblEntry::Method(def_id, substs)
-            })
-        }),
-    );
+        ControlFlow::Continue(())
+    };
+
+    let _ = prepare_vtable_segments(tcx, trait_ref, vtable_segment_callback);
+
+    if tcx.has_attr(trait_ref.def_id(), sym::rustc_dump_vtable) {
+        let sp = tcx.def_span(trait_ref.def_id());
+        dump_vtable_entries(tcx, sp, trait_ref, &entries);
+    }
 
-    tcx.arena.alloc_from_iter(entries)
+    tcx.arena.alloc_from_iter(entries.into_iter())
 }
 
 /// Find slot base for trait methods within vtable entries of another trait
@@ -525,20 +724,82 @@ fn vtable_trait_first_method_offset<'tcx>(
 ) -> usize {
     let (trait_to_be_found, trait_owning_vtable) = key;
 
-    let mut supertraits = util::supertraits(tcx, trait_owning_vtable);
+    let vtable_segment_callback = {
+        let mut vtable_base = 0;
+
+        move |segment| {
+            match segment {
+                VtblSegment::MetadataDSA => {
+                    vtable_base += COMMON_VTABLE_ENTRIES.len();
+                }
+                VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
+                    if trait_ref == trait_to_be_found {
+                        return ControlFlow::Break(vtable_base);
+                    }
+                    vtable_base += util::count_own_vtable_entries(tcx, trait_ref);
+                    if emit_vptr {
+                        vtable_base += 1;
+                    }
+                }
+            }
+            ControlFlow::Continue(())
+        }
+    };
+
+    if let Some(vtable_base) =
+        prepare_vtable_segments(tcx, trait_owning_vtable, vtable_segment_callback)
+    {
+        vtable_base
+    } else {
+        bug!("Failed to find info for expected trait in vtable");
+    }
+}
+
+/// Find slot offset for trait vptr within vtable entries of another trait
+/// FIXME: This function is not yet used. Remove `#[allow(dead_code)]` when it's used in upcoming pr.
+#[allow(dead_code)]
+fn vtable_trait_vptr_slot_offset<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    key: (
+        ty::PolyTraitRef<'tcx>, // trait_to_be_found
+        ty::PolyTraitRef<'tcx>, // trait_owning_vtable
+    ),
+) -> Option<usize> {
+    let (trait_to_be_found, trait_owning_vtable) = key;
+
+    let vtable_segment_callback = {
+        let mut vptr_offset = 0;
+        move |segment| {
+            match segment {
+                VtblSegment::MetadataDSA => {
+                    vptr_offset += COMMON_VTABLE_ENTRIES.len();
+                }
+                VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
+                    vptr_offset += util::count_own_vtable_entries(tcx, trait_ref);
+                    if trait_ref == trait_to_be_found {
+                        if emit_vptr {
+                            return ControlFlow::Break(Some(vptr_offset));
+                        } else {
+                            return ControlFlow::Break(None);
+                        }
+                    }
 
-    // For each of the non-matching predicates that
-    // we pass over, we sum up the set of number of vtable
-    // entries, so that we can compute the offset for the selected
-    // trait.
-    let vtable_base = ty::COMMON_VTABLE_ENTRIES.len()
-        + supertraits
-            .by_ref()
-            .take_while(|t| *t != trait_to_be_found)
-            .map(|t| util::count_own_vtable_entries(tcx, t))
-            .sum::<usize>();
+                    if emit_vptr {
+                        vptr_offset += 1;
+                    }
+                }
+            }
+            ControlFlow::Continue(())
+        }
+    };
 
-    vtable_base
+    if let Some(vptr_offset) =
+        prepare_vtable_segments(tcx, trait_owning_vtable, vtable_segment_callback)
+    {
+        vptr_offset
+    } else {
+        bug!("Failed to find info for expected trait in vtable");
+    }
 }
 
 pub fn provide(providers: &mut ty::query::Providers) {
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 98980c65bc8..e33cc603b5e 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -523,8 +523,7 @@ fn check_type_defn<'tcx, F>(
                 fcx.register_wf_obligation(
                     field.ty.into(),
                     field.span,
-                    // We don't have an HIR id for the field
-                    ObligationCauseCode::WellFormed(None),
+                    ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))),
                 )
             }
 
@@ -1467,6 +1466,7 @@ struct AdtVariant<'tcx> {
 
 struct AdtField<'tcx> {
     ty: Ty<'tcx>,
+    def_id: LocalDefId,
     span: Span,
 }
 
@@ -1477,11 +1477,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .fields()
             .iter()
             .map(|field| {
-                let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id));
+                let def_id = self.tcx.hir().local_def_id(field.hir_id);
+                let field_ty = self.tcx.type_of(def_id);
                 let field_ty = self.normalize_associated_types_in(field.ty.span, field_ty);
                 let field_ty = self.resolve_vars_if_possible(field_ty);
                 debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty);
-                AdtField { ty: field_ty, span: field.ty.span }
+                AdtField { ty: field_ty, span: field.ty.span, def_id }
             })
             .collect();
         AdtVariant { fields, explicit_discr: None }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 15469cb0066..50e4ba4fe6c 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -364,7 +364,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     let concrete_ty = tcx
                         .mir_borrowck(owner.expect_local())
                         .concrete_opaque_types
-                        .get_by(|(key, _)| key.def_id == def_id.to_def_id())
+                        .get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
                         .map(|concrete_ty| *concrete_ty)
                         .unwrap_or_else(|| {
                             tcx.sess.delay_span_bug(
@@ -512,8 +512,15 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
 
     struct ConstraintLocator<'tcx> {
         tcx: TyCtxt<'tcx>,
+
+        /// def_id of the opaque type whose defining uses are being checked
         def_id: DefId,
-        // (first found type span, actual type)
+
+        /// as we walk the defining uses, we are checking that all of them
+        /// define the same hidden type. This variable is set to `Some`
+        /// with the first type that we find, and then later types are
+        /// checked against it (we also carry the span of that first
+        /// type).
         found: Option<(Span, Ty<'tcx>)>,
     }
 
@@ -531,7 +538,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
                 .tcx
                 .typeck(def_id)
                 .concrete_opaque_types
-                .get_by(|(key, _)| key.def_id == self.def_id)
+                .any_value_matching(|(key, _)| key.def_id == self.def_id)
                 .is_none()
             {
                 debug!("no constraints in typeck results");
diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs
index c1af10f5ce4..e7503d3d71c 100644
--- a/compiler/rustc_typeck/src/hir_wf_check.rs
+++ b/compiler/rustc_typeck/src/hir_wf_check.rs
@@ -25,7 +25,7 @@ fn diagnostic_hir_wf_check<'tcx>(
         WellFormedLoc::Ty(def_id) => def_id,
         WellFormedLoc::Param { function, param_idx: _ } => function,
     };
-    let hir_id = HirId::make_owner(def_id);
+    let hir_id = hir.local_def_id_to_hir_id(def_id);
 
     // HIR wfcheck should only ever happen as part of improving an existing error
     tcx.sess
@@ -140,6 +140,7 @@ fn diagnostic_hir_wf_check<'tcx>(
                 }
                 ref item => bug!("Unexpected item {:?}", item),
             },
+            hir::Node::Field(field) => Some(field.ty),
             ref node => bug!("Unexpected node {:?}", node),
         },
         WellFormedLoc::Param { function: _, param_idx } => {
diff --git a/config.toml.example b/config.toml.example
index 9a820f0803f..775133f2ab3 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -38,7 +38,7 @@ changelog-seen = 2
 # This is false by default so that distributions don't unexpectedly download
 # LLVM from the internet.
 #
-# All tier 1 targets are currently supported; set this to `"if-supported"` if
+# All tier 1 targets are currently supported; set this to `"if-available"` if
 # you are not sure whether you're on a tier 1 target.
 #
 # We also currently only support this when building LLVM for the build triple.
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index dfd693d13b3..79042ab739c 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -935,6 +935,7 @@ impl<K, V> BTreeMap<K, V> {
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+    /// The elements are visited in ascending key order.
     ///
     /// # Examples
     ///
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index be740b05fb8..9711214aea6 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -846,6 +846,7 @@ impl<T> BTreeSet<T> {
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    /// The elements are visited in ascending order.
     ///
     /// # Examples
     ///
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index e8bd4bcb01f..fa1f361a5b6 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -56,6 +56,10 @@
 //! [`Rc`]: rc
 //! [`RefCell`]: core::cell
 
+// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 #![allow(unused_attributes)]
 #![stable(feature = "alloc", since = "1.36.0")]
 #![doc(
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 8cb7aad28aa..16efd2f0eaf 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -333,21 +333,22 @@ pub trait Iterator {
     /// regardless of the step given.
     ///
     /// Note 2: The time at which ignored elements are pulled is not fixed.
-    /// `StepBy` behaves like the sequence `next(), nth(step-1), nth(step-1), …`,
-    /// but is also free to behave like the sequence
-    /// `advance_n_and_return_first(step), advance_n_and_return_first(step), …`
+    /// `StepBy` behaves like the sequence `self.next()`, `self.nth(step-1)`,
+    /// `self.nth(step-1)`, …, but is also free to behave like the sequence
+    /// `advance_n_and_return_first(&mut self, step)`,
+    /// `advance_n_and_return_first(&mut self, step)`, …
     /// Which way is used may change for some iterators for performance reasons.
     /// The second way will advance the iterator earlier and may consume more items.
     ///
     /// `advance_n_and_return_first` is the equivalent of:
     /// ```
-    /// fn advance_n_and_return_first<I>(iter: &mut I, total_step: usize) -> Option<I::Item>
+    /// fn advance_n_and_return_first<I>(iter: &mut I, n: usize) -> Option<I::Item>
     /// where
     ///     I: Iterator,
     /// {
     ///     let next = iter.next();
-    ///     if total_step > 1 {
-    ///         iter.nth(total_step-2);
+    ///     if n > 1 {
+    ///         iter.nth(n - 2);
     ///     }
     ///     next
     /// }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 540cdf124ee..6d87a7ab055 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -49,6 +49,10 @@
 //
 // This cfg won't affect doc tests.
 #![cfg(not(test))]
+// To run libcore tests without x.py without ending up with two copies of libcore, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 #![stable(feature = "core", since = "1.6.0")]
 #![doc(
     html_playground_url = "https://play.rust-lang.org/",
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index fac285c96f0..4a5efab9055 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -934,6 +934,7 @@ where
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+    /// The elements are visited in unsorted (and unspecified) order.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 272e1c2be2b..1a2a8afac8b 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -912,6 +912,7 @@ where
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    /// The elements are visited in unsorted (and unspecified) order.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 64f88c1aba6..5709d97d643 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -294,7 +294,7 @@ impl Error for VarError {
     }
 }
 
-/// Sets the environment variable `k` to the value `v` for the currently running
+/// Sets the environment variable `key` to the value `value` for the currently running
 /// process.
 ///
 /// Note that while concurrent access to environment variables is safe in Rust,
@@ -310,9 +310,8 @@ impl Error for VarError {
 ///
 /// # Panics
 ///
-/// This function may panic if `key` is empty, contains an ASCII equals sign
-/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
-/// character.
+/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
+/// or the NUL character `'\0'`, or when `value` contains the NUL character.
 ///
 /// # Examples
 ///
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index ef2769d431f..c98244132be 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -68,7 +68,7 @@ use crate::ptr;
 /// [`flush`]: BufWriter::flush
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufWriter<W: Write> {
-    inner: Option<W>,
+    inner: W,
     // The buffer. Avoid using this like a normal `Vec` in common code paths.
     // That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
     // methods that require bounds checking or the like. This makes an enormous
@@ -112,7 +112,7 @@ impl<W: Write> BufWriter<W> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
-        BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false }
+        BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
     }
 
     /// Send data in our local buffer into the inner writer, looping as
@@ -161,10 +161,9 @@ impl<W: Write> BufWriter<W> {
         }
 
         let mut guard = BufGuard::new(&mut self.buf);
-        let inner = self.inner.as_mut().unwrap();
         while !guard.done() {
             self.panicked = true;
-            let r = inner.write(guard.remaining());
+            let r = self.inner.write(guard.remaining());
             self.panicked = false;
 
             match r {
@@ -212,7 +211,7 @@ impl<W: Write> BufWriter<W> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &W {
-        self.inner.as_ref().unwrap()
+        &self.inner
     }
 
     /// Gets a mutable reference to the underlying writer.
@@ -232,7 +231,7 @@ impl<W: Write> BufWriter<W> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut W {
-        self.inner.as_mut().unwrap()
+        &mut self.inner
     }
 
     /// Returns a reference to the internally buffered data.
@@ -308,7 +307,7 @@ impl<W: Write> BufWriter<W> {
     pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
         match self.flush_buf() {
             Err(e) => Err(IntoInnerError::new(self, e)),
-            Ok(()) => Ok(self.inner.take().unwrap()),
+            Ok(()) => Ok(self.into_raw_parts().0),
         }
     }
 
@@ -339,7 +338,12 @@ impl<W: Write> BufWriter<W> {
     pub fn into_raw_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
         let buf = mem::take(&mut self.buf);
         let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
-        (self.inner.take().unwrap(), buf)
+
+        // SAFETY: forget(self) prevents double dropping inner
+        let inner = unsafe { ptr::read(&mut self.inner) };
+        mem::forget(self);
+
+        (inner, buf)
     }
 
     // Ensure this function does not get inlined into `write`, so that it
@@ -643,7 +647,7 @@ where
 {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.debug_struct("BufWriter")
-            .field("writer", &self.inner.as_ref().unwrap())
+            .field("writer", &self.inner)
             .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
             .finish()
     }
@@ -663,7 +667,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Drop for BufWriter<W> {
     fn drop(&mut self) {
-        if self.inner.is_some() && !self.panicked {
+        if !self.panicked {
             // dtors should not panic, so we ignore a failed flush
             let _r = self.flush_buf();
         }
diff --git a/library/std/src/io/buffered/mod.rs b/library/std/src/io/buffered/mod.rs
index 65497817f81..38076ab3a2b 100644
--- a/library/std/src/io/buffered/mod.rs
+++ b/library/std/src/io/buffered/mod.rs
@@ -133,7 +133,6 @@ impl<W> IntoInnerError<W> {
     ///
     /// # Example
     /// ```
-    /// #![feature(io_into_inner_error_parts)]
     /// use std::io::{BufWriter, ErrorKind, Write};
     ///
     /// let mut not_enough_space = [0u8; 10];
@@ -143,7 +142,7 @@ impl<W> IntoInnerError<W> {
     /// let err = into_inner_err.into_error();
     /// assert_eq!(err.kind(), ErrorKind::WriteZero);
     /// ```
-    #[unstable(feature = "io_into_inner_error_parts", issue = "79704")]
+    #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
     pub fn into_error(self) -> Error {
         self.1
     }
@@ -156,7 +155,6 @@ impl<W> IntoInnerError<W> {
     ///
     /// # Example
     /// ```
-    /// #![feature(io_into_inner_error_parts)]
     /// use std::io::{BufWriter, ErrorKind, Write};
     ///
     /// let mut not_enough_space = [0u8; 10];
@@ -167,7 +165,7 @@ impl<W> IntoInnerError<W> {
     /// assert_eq!(err.kind(), ErrorKind::WriteZero);
     /// assert_eq!(recovered_writer.buffer(), b"t be actually written");
     /// ```
-    #[unstable(feature = "io_into_inner_error_parts", issue = "79704")]
+    #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
     pub fn into_parts(self) -> (Error, W) {
         (self.1, self.0)
     }
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 879d7160524..1488bf94841 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -16,6 +16,23 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 #[cfg(target_os = "vxworks")]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 256 * 1024;
 
+#[cfg(target_os = "fuchsia")]
+mod zircon {
+    type zx_handle_t = u32;
+    type zx_status_t = i32;
+    pub const ZX_PROP_NAME: u32 = 3;
+
+    extern "C" {
+        pub fn zx_object_set_property(
+            handle: zx_handle_t,
+            property: u32,
+            value: *const libc::c_void,
+            value_size: libc::size_t,
+        ) -> zx_status_t;
+        pub fn zx_thread_self() -> zx_handle_t;
+    }
+}
+
 pub struct Thread {
     id: libc::pthread_t,
 }
@@ -134,6 +151,19 @@ impl Thread {
         }
     }
 
+    #[cfg(target_os = "fuchsia")]
+    pub fn set_name(name: &CStr) {
+        use self::zircon::*;
+        unsafe {
+            zx_object_set_property(
+                zx_thread_self(),
+                ZX_PROP_NAME,
+                name.as_ptr() as *const libc::c_void,
+                name.to_bytes().len(),
+            );
+        }
+    }
+
     #[cfg(any(
         target_env = "newlib",
         target_os = "haiku",
@@ -145,10 +175,6 @@ impl Thread {
     pub fn set_name(_name: &CStr) {
         // Newlib, Haiku, Emscripten, and VxWorks have no way to set a thread name.
     }
-    #[cfg(target_os = "fuchsia")]
-    pub fn set_name(_name: &CStr) {
-        // FIXME: determine whether Fuchsia has a way to set a thread name.
-    }
 
     pub fn sleep(dur: Duration) {
         let mut secs = dur.as_secs();
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 77d2684b5d2..78c9a252622 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -3,7 +3,7 @@
 //!
 //! This module contains some of the real meat in the rustbuild build system
 //! which is where Cargo is used to compile the standard library, libtest, and
-//! compiler. This module is also responsible for assembling the sysroot as it
+//! the compiler. This module is also responsible for assembling the sysroot as it
 //! goes along from the output of the previous stage.
 
 use std::borrow::Cow;
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 483816b98d6..4b3c25b02c2 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -13,6 +13,7 @@ use std::path::{Path, PathBuf};
 use std::str::FromStr;
 
 use crate::cache::{Interned, INTERNER};
+use crate::channel::GitInfo;
 pub use crate::flags::Subcommand;
 use crate::flags::{Color, Flags};
 use crate::util::exe;
@@ -48,7 +49,7 @@ pub struct Config {
     /// Call Build::ninja() instead of this.
     pub ninja_in_file: bool,
     pub verbose: usize,
-    pub submodules: bool,
+    pub submodules: Option<bool>,
     pub fast_submodules: bool,
     pub compiler_docs: bool,
     pub docs_minification: bool,
@@ -552,7 +553,7 @@ impl Config {
         config.backtrace = true;
         config.rust_optimize = true;
         config.rust_optimize_tests = true;
-        config.submodules = true;
+        config.submodules = None;
         config.fast_submodules = true;
         config.docs = true;
         config.docs_minification = true;
@@ -658,11 +659,11 @@ impl Config {
         config.npm = build.npm.map(PathBuf::from);
         config.gdb = build.gdb.map(PathBuf::from);
         config.python = build.python.map(PathBuf::from);
+        config.submodules = build.submodules;
         set(&mut config.low_priority, build.low_priority);
         set(&mut config.compiler_docs, build.compiler_docs);
         set(&mut config.docs_minification, build.docs_minification);
         set(&mut config.docs, build.docs);
-        set(&mut config.submodules, build.submodules);
         set(&mut config.fast_submodules, build.fast_submodules);
         set(&mut config.locked_deps, build.locked_deps);
         set(&mut config.vendor, build.vendor);
@@ -792,8 +793,16 @@ impl Config {
 
                 // CI-built LLVM can be either dynamic or static.
                 let ci_llvm = config.out.join(&*config.build.triple).join("ci-llvm");
-                let link_type = t!(std::fs::read_to_string(ci_llvm.join("link-type.txt")));
-                config.llvm_link_shared = link_type == "dynamic";
+                config.llvm_link_shared = if config.dry_run {
+                    // just assume dynamic for now
+                    true
+                } else {
+                    let link_type = t!(
+                        std::fs::read_to_string(ci_llvm.join("link-type.txt")),
+                        format!("CI llvm missing: {}", ci_llvm.display())
+                    );
+                    link_type == "dynamic"
+                };
             }
 
             if config.llvm_thin_lto {
@@ -1075,6 +1084,10 @@ impl Config {
     pub fn llvm_enabled(&self) -> bool {
         self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
     }
+
+    pub fn submodules(&self, rust_info: &GitInfo) -> bool {
+        self.submodules.unwrap_or(rust_info.is_git())
+    }
 }
 
 fn set<T>(field: &mut T, val: Option<T>) {
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 999882a1c04..8d9f169e6c5 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -160,6 +160,7 @@ o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of tw
 o("extended", "build.extended", "build an extended rust tool set")
 
 v("tools", None, "List of extended tools will be installed")
+v("codegen-backends", None, "List of codegen backends to build")
 v("build", "build.build", "GNUs ./configure syntax LLVM build triple")
 v("host", None, "GNUs ./configure syntax LLVM host triples")
 v("target", None, "GNUs ./configure syntax LLVM target triples")
@@ -339,6 +340,8 @@ for key in known_args:
         set('target.{}.llvm-filecheck'.format(build()), value)
     elif option.name == 'tools':
         set('build.tools', value.split(','))
+    elif option.name == 'codegen-backends':
+        set('rust.codegen-backends', value.split(','))
     elif option.name == 'host':
         set('build.host', value.split(','))
     elif option.name == 'target':
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 92853378e58..c37763243c0 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1955,8 +1955,16 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
         cmd.arg("--libfiles");
         builder.verbose(&format!("running {:?}", cmd));
         let files = output(&mut cmd);
+        let build_llvm_out = &builder.llvm_out(builder.config.build);
+        let target_llvm_out = &builder.llvm_out(target);
         for file in files.trim_end().split(' ') {
-            builder.install(Path::new(file), dst_libdir, 0o644);
+            // If we're not using a custom LLVM, make sure we package for the target.
+            let file = if let Ok(relative_path) = Path::new(file).strip_prefix(build_llvm_out) {
+                target_llvm_out.join(relative_path)
+            } else {
+                PathBuf::from(file)
+            };
+            builder.install(&file, dst_libdir, 0o644);
         }
         !builder.config.dry_run
     } else {
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 80a60c79edf..1b7614b2989 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -152,7 +152,7 @@ Subcommands:
     fmt         Run rustfmt
     test, t     Build and run some test suites
     bench       Build and run some benchmarks
-    doc         Build documentation
+    doc, d      Build documentation
     clean       Clean out build directories
     dist        Build distribution artifacts
     install     Install distribution artifacts
@@ -244,6 +244,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
                 || (s == "t")
                 || (s == "bench")
                 || (s == "doc")
+                || (s == "d")
                 || (s == "clean")
                 || (s == "dist")
                 || (s == "install")
@@ -312,7 +313,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
             "clippy" => {
                 opts.optflag("", "fix", "automatically apply lint suggestions");
             }
-            "doc" => {
+            "doc" | "d" => {
                 opts.optflag("", "open", "open the docs in a browser");
             }
             "clean" => {
@@ -487,7 +488,7 @@ Arguments:
         ./x.py test --stage 1",
                 );
             }
-            "doc" => {
+            "doc" | "d" => {
                 subcommand_help.push_str(
                     "\n
 Arguments:
@@ -573,7 +574,7 @@ Arguments:
                 },
             },
             "bench" => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") },
-            "doc" => Subcommand::Doc { paths, open: matches.opt_present("open") },
+            "doc" | "d" => Subcommand::Doc { paths, open: matches.opt_present("open") },
             "clean" => {
                 if !paths.is_empty() {
                     println!("\nclean does not take a path argument\n");
diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs
index 2fe9b06e426..5c0322e18a4 100644
--- a/src/bootstrap/job.rs
+++ b/src/bootstrap/job.rs
@@ -103,12 +103,20 @@ pub unsafe fn setup(build: &mut Build) {
     };
 
     let parent = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid.parse().unwrap());
-    assert!(
-        !parent.is_null(),
-        "PID `{}` doesn't seem to exist: {}",
-        pid,
-        io::Error::last_os_error()
-    );
+
+    // If we get a null parent pointer here, it is possible that either
+    // we have got an invalid pid or the parent process has been closed.
+    // Since the first case rarely happens
+    // (only when wrongly setting the environmental variable),
+    // so it might be better to improve the experience of the second case
+    // when users have interrupted the parent process and we don't finish
+    // duplicating the handle yet.
+    // We just need close the job object if that occurs.
+    if parent.is_null() {
+        CloseHandle(job);
+        return;
+    }
+
     let mut parent_handle = ptr::null_mut();
     let r = DuplicateHandle(
         GetCurrentProcess(),
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 6bcdbe3e4bb..245f3eada2a 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -486,7 +486,7 @@ impl Build {
             t!(std::fs::read_dir(dir)).next().is_none()
         }
 
-        if !self.config.submodules {
+        if !self.config.submodules(&self.rust_info) {
             return;
         }
 
@@ -562,7 +562,7 @@ impl Build {
             "library/stdarch",
         ];
         // Avoid running git when there isn't a git checkout.
-        if !self.config.submodules {
+        if !self.config.submodules(&self.rust_info) {
             return;
         }
         let output = output(
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 1be414b29a1..b8a1513f2a6 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -118,6 +118,10 @@ impl Step for Llvm {
             let idx = target.triple.find('-').unwrap();
 
             format!("riscv{}{}", &target.triple[5..7], &target.triple[idx..])
+        } else if self.target.starts_with("powerpc") && self.target.ends_with("freebsd") {
+            // FreeBSD 13 had incompatible ABI changes on all PowerPC platforms.
+            // Set the version suffix to 13.0 so the correct target details are used.
+            format!("{}{}", self.target, "13.0")
         } else {
             target.to_string()
         };
@@ -277,6 +281,11 @@ impl Step for Llvm {
             }
         }
 
+        // Workaround for ppc32 lld limitation
+        if target == "powerpc-unknown-freebsd" {
+            cfg.define("CMAKE_EXE_LINKER_FLAGS", "-fuse-ld=bfd");
+        }
+
         // https://llvm.org/docs/HowToCrossCompileLLVM.html
         if target != builder.config.build {
             builder.ensure(Llvm { target: builder.config.build });
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 885010b039e..90ef48798dd 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -249,6 +249,7 @@ target | std | host | notes
 `powerpc-wrs-vxworks` | ? |  |
 `powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
 `powerpc64le-unknown-freebsd` |   |   | PPC64LE FreeBSD
+`powerpc-unknown-freebsd` |   |   | PowerPC FreeBSD
 `powerpc64-unknown-linux-musl` | ? |  |
 `powerpc64-wrs-vxworks` | ? |  |
 `powerpc64le-unknown-linux-musl` | ? |  |
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 5ce7c49278d..b45e84aff8c 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -105,7 +105,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
         registry: rustc_driver::diagnostics_registry(),
     };
 
-    let mut test_args = options.test_args.clone();
+    let test_args = options.test_args.clone();
     let display_warnings = options.display_warnings;
     let nocapture = options.nocapture;
     let externs = options.externs.clone();
@@ -166,12 +166,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
         Err(ErrorReported) => return Err(ErrorReported),
     };
 
-    test_args.insert(0, "rustdoctest".to_string());
-    if nocapture {
-        test_args.push("--nocapture".to_string());
-    }
-
-    test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
+    run_tests(test_args, nocapture, display_warnings, tests);
 
     // Collect and warn about unused externs, but only if we've gotten
     // reports for each doctest
@@ -214,6 +209,19 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
     Ok(())
 }
 
+crate fn run_tests(
+    mut test_args: Vec<String>,
+    nocapture: bool,
+    display_warnings: bool,
+    tests: Vec<test::TestDescAndFn>,
+) {
+    test_args.insert(0, "rustdoctest".to_string());
+    if nocapture {
+        test_args.push("--nocapture".to_string());
+    }
+    test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
+}
+
 // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
 fn scrape_test_config(attrs: &[ast::Attribute]) -> TestOptions {
     use rustc_ast_pretty::pprust;
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 552958d5e40..2dfbaff1cc9 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1029,14 +1029,12 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
 
             use crate::clean::Variant;
             if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
-                let count_fields = s.fields.len();
-                toggle_open(w, format_args!("{} field{}", count_fields, pluralize(count_fields)));
                 let variant_id = cx.derive_id(format!(
                     "{}.{}.fields",
                     ItemType::Variant,
                     variant.name.as_ref().unwrap()
                 ));
-                write!(w, "<div class=\"autohide sub-variant\" id=\"{id}\">", id = variant_id);
+                write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
                 write!(
                     w,
                     "<h3>Fields of <b>{name}</b></h3><div>",
@@ -1064,7 +1062,6 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
                     }
                 }
                 w.write_str("</div></div>");
-                toggle_close(w);
             }
         }
     }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 6672093eb7b..c2184e04b76 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -329,6 +329,7 @@ nav.sub {
 .logo-container > img {
 	max-width: 100px;
 	max-height: 100px;
+	height: 100%;
 	position: absolute;
 	left: 50%;
 	top: 50%;
@@ -1072,7 +1073,7 @@ a.test-arrow:hover{
 	padding-top: 1px;
 }
 
-#main > details > .sub-variant > h3 {
+#main .sub-variant > h3 {
 	font-size: 15px;
 	margin-left: 25px;
 	margin-bottom: 5px;
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 6c8b95c04c9..80af2a7aaf5 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -115,7 +115,7 @@ crate fn render<P: AsRef<Path>>(
 }
 
 /// Runs any tests/code examples in the markdown file `input`.
-crate fn test(mut options: Options) -> Result<(), String> {
+crate fn test(options: Options) -> Result<(), String> {
     let input_str = read_to_string(&options.input)
         .map_err(|err| format!("{}: {}", options.input.display(), err))?;
     let mut opts = TestOptions::default();
@@ -135,14 +135,11 @@ crate fn test(mut options: Options) -> Result<(), String> {
 
     find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);
 
-    options.test_args.insert(0, "rustdoctest".to_string());
-    if options.nocapture {
-        options.test_args.push("--nocapture".to_string());
-    }
-    test::test_main(
-        &options.test_args,
+    crate::doctest::run_tests(
+        options.test_args,
+        options.nocapture,
+        options.display_warnings,
         collector.tests,
-        Some(test::Options::new().display_output(options.display_warnings)),
     );
     Ok(())
 }
diff --git a/src/test/rustdoc-gui/module-items-font.goml b/src/test/rustdoc-gui/module-items-font.goml
new file mode 100644
index 00000000000..817b148bee1
--- /dev/null
+++ b/src/test/rustdoc-gui/module-items-font.goml
@@ -0,0 +1,4 @@
+// This test checks that the correct font is used on module items (in index.html pages).
+goto: file://|DOC_PATH|/test_docs/index.html
+assert-css: (".item-table .module-item a", {"font-family": '"Fira Sans", Arial, sans-serif'}, ALL)
+assert-css: (".item-table .docblock-short", {"font-family": '"Source Serif 4", "Noto Sans KR", serif'}, ALL)
diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs
index 167858b6065..8d2046591d0 100644
--- a/src/test/rustdoc/toggle-item-contents.rs
+++ b/src/test/rustdoc/toggle-item-contents.rs
@@ -62,8 +62,7 @@ pub struct PrivStruct {
 }
 
 // @has 'toggle_item_contents/enum.Enum.html'
-// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 2 fields'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
 pub enum Enum {
     A, B, C,
     D {
@@ -73,8 +72,7 @@ pub enum Enum {
 }
 
 // @has 'toggle_item_contents/enum.EnumStructVariant.html'
-// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 field'
+// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
 pub enum EnumStructVariant {
     A, B, C,
     D {
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
index 73b23da5bcb..7950dd3e99e 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
@@ -29,7 +29,6 @@ impl Bar for AssocNoCopy {
 impl Thing for AssocNoCopy {
     type Out = Box<dyn Bar<Assoc: Copy>>;
     //~^ ERROR the trait bound `String: Copy` is not satisfied
-    //~| ERROR the trait bound `String: Copy` is not satisfied
 
     fn func() -> Self::Out {
         Box::new(AssocNoCopy)
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
index 414d74d4786..0f1d35be0eb 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
@@ -4,12 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
 LL |     type Out = Box<dyn Bar<Assoc: Copy>>;
    |                            ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
 
-error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28
-   |
-LL |     type Out = Box<dyn Bar<Assoc: Copy>>;
-   |                            ^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-87261.rs b/src/test/ui/associated-types/issue-87261.rs
new file mode 100644
index 00000000000..a70f771e482
--- /dev/null
+++ b/src/test/ui/associated-types/issue-87261.rs
@@ -0,0 +1,99 @@
+trait Foo {}
+
+trait Trait {
+    type Associated;
+}
+trait DerivedTrait: Trait {}
+trait GenericTrait<A> {
+    type Associated;
+}
+
+struct Impl;
+impl Foo for Impl {}
+impl Trait for Impl {
+    type Associated = ();
+}
+impl DerivedTrait for Impl {}
+impl<A> GenericTrait<A> for Impl {
+    type Associated = ();
+}
+
+fn returns_opaque() -> impl Trait + 'static {
+    Impl
+}
+fn returns_opaque_derived() -> impl DerivedTrait + 'static {
+    Impl
+}
+fn returns_opaque_foo() -> impl Trait + Foo {
+    Impl
+}
+fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
+    Impl
+}
+fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
+    Impl
+}
+fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
+    Impl
+}
+fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
+    Impl
+}
+
+fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+
+fn check_generics<A, B, C, D, E, F, G>(a: A, b: B, c: C, d: D, e: E, f: F, g: G)
+where
+    A: Trait + 'static,
+    B: DerivedTrait + 'static,
+    C: Trait + Foo,
+    D: DerivedTrait + Foo,
+    E: GenericTrait<()> + 'static,
+    F: GenericTrait<()> + Foo,
+    G: GenericTrait<()> + GenericTrait<u8>,
+{
+    accepts_trait(a);
+    //~^ ERROR type mismatch resolving `<A as Trait>::Associated == ()`
+
+    accepts_trait(b);
+    //~^ ERROR type mismatch resolving `<B as Trait>::Associated == ()`
+
+    accepts_trait(c);
+    //~^ ERROR type mismatch resolving `<C as Trait>::Associated == ()`
+
+    accepts_trait(d);
+    //~^ ERROR type mismatch resolving `<D as Trait>::Associated == ()`
+
+    accepts_generic_trait(e);
+    //~^ ERROR type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
+
+    accepts_generic_trait(f);
+    //~^ ERROR type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
+
+    accepts_generic_trait(g);
+    //~^ ERROR type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
+}
+
+fn main() {
+    accepts_trait(returns_opaque());
+    //~^ ERROR type mismatch resolving `<impl Trait as Trait>::Associated == ()`
+
+    accepts_trait(returns_opaque_derived());
+    //~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
+
+    accepts_trait(returns_opaque_foo());
+    //~^ ERROR type mismatch resolving `<impl Trait+Foo as Trait>::Associated == ()`
+
+    accepts_trait(returns_opaque_derived_foo());
+    //~^ ERROR type mismatch resolving `<impl DerivedTrait+Foo as Trait>::Associated == ()`
+
+    accepts_generic_trait(returns_opaque_generic());
+    //~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
+
+    accepts_generic_trait(returns_opaque_generic_foo());
+    //~^ ERROR type mismatch resolving `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated == ()`
+
+    accepts_generic_trait(returns_opaque_generic_duplicate());
+    //~^ ERROR type mismatch resolving `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
+}
diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr
new file mode 100644
index 00000000000..0725acfe537
--- /dev/null
+++ b/src/test/ui/associated-types/issue-87261.stderr
@@ -0,0 +1,238 @@
+error[E0271]: type mismatch resolving `<A as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:56:5
+   |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(a);
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<A as Trait>::Associated`
+help: consider constraining the associated type `<A as Trait>::Associated` to `()`
+   |
+LL |     A: Trait<Associated = ()> + 'static,
+   |             ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<B as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:59:5
+   |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(b);
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<B as Trait>::Associated`
+   = help: consider constraining the associated type `<B as Trait>::Associated` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error[E0271]: type mismatch resolving `<C as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:62:5
+   |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(c);
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<C as Trait>::Associated`
+help: consider constraining the associated type `<C as Trait>::Associated` to `()`
+   |
+LL |     C: Trait<Associated = ()> + Foo,
+   |             ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<D as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:65:5
+   |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(d);
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<D as Trait>::Associated`
+   = help: consider constraining the associated type `<D as Trait>::Associated` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error[E0271]: type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
+  --> $DIR/issue-87261.rs:68:5
+   |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+   |                                              --------------- required by this bound in `accepts_generic_trait`
+...
+LL |     accepts_generic_trait(e);
+   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<E as GenericTrait<()>>::Associated`
+help: consider constraining the associated type `<E as GenericTrait<()>>::Associated` to `()`
+   |
+LL |     E: GenericTrait<(), Associated = ()> + 'static,
+   |                       ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
+  --> $DIR/issue-87261.rs:71:5
+   |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+   |                                              --------------- required by this bound in `accepts_generic_trait`
+...
+LL |     accepts_generic_trait(f);
+   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<F as GenericTrait<()>>::Associated`
+help: consider constraining the associated type `<F as GenericTrait<()>>::Associated` to `()`
+   |
+LL |     F: GenericTrait<(), Associated = ()> + Foo,
+   |                       ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
+  --> $DIR/issue-87261.rs:74:5
+   |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+   |                                              --------------- required by this bound in `accepts_generic_trait`
+...
+LL |     accepts_generic_trait(g);
+   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<G as GenericTrait<()>>::Associated`
+   = help: consider constraining the associated type `<G as GenericTrait<()>>::Associated` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:79:5
+   |
+LL | fn returns_opaque() -> impl Trait + 'static {
+   |                        -------------------- the found opaque type
+...
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(returns_opaque());
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl Trait as Trait>::Associated`
+help: consider constraining the associated type `<impl Trait as Trait>::Associated` to `()`
+   |
+LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
+   |                                  ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:82:5
+   |
+LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
+   |                                --------------------------- the found opaque type
+...
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(returns_opaque_derived());
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl DerivedTrait as Trait>::Associated`
+help: consider constraining the associated type `<impl DerivedTrait as Trait>::Associated` to `()`
+   |
+LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static {
+   |                                                 ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<impl Trait+Foo as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:85:5
+   |
+LL | fn returns_opaque_foo() -> impl Trait + Foo {
+   |                            ---------------- the found opaque type
+...
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(returns_opaque_foo());
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl Trait+Foo as Trait>::Associated`
+help: consider constraining the associated type `<impl Trait+Foo as Trait>::Associated` to `()`
+   |
+LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
+   |                                      ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<impl DerivedTrait+Foo as Trait>::Associated == ()`
+  --> $DIR/issue-87261.rs:88:5
+   |
+LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
+   |                                    ----------------------- the found opaque type
+...
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+   |                           --------------- required by this bound in `accepts_trait`
+...
+LL |     accepts_trait(returns_opaque_derived_foo());
+   |     ^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl DerivedTrait+Foo as Trait>::Associated`
+   = help: consider constraining the associated type `<impl DerivedTrait+Foo as Trait>::Associated` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
+  --> $DIR/issue-87261.rs:91:5
+   |
+LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
+   |                                ------------------------------- the found opaque type
+...
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+   |                                              --------------- required by this bound in `accepts_generic_trait`
+...
+LL |     accepts_generic_trait(returns_opaque_generic());
+   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated`
+help: consider constraining the associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated` to `()`
+   |
+LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static {
+   |                                                    ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated == ()`
+  --> $DIR/issue-87261.rs:94:5
+   |
+LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
+   |                                    --------------------------- the found opaque type
+...
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+   |                                              --------------- required by this bound in `accepts_generic_trait`
+...
+LL |     accepts_generic_trait(returns_opaque_generic_foo());
+   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated`
+help: consider constraining the associated type `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated` to `()`
+   |
+LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo {
+   |                                                        ^^^^^^^^^^^^^^^^^
+
+error[E0271]: type mismatch resolving `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
+  --> $DIR/issue-87261.rs:97:5
+   |
+LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
+   |                                          ---------------------------------------- the found opaque type
+...
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+   |                                              --------------- required by this bound in `accepts_generic_trait`
+...
+LL |     accepts_generic_trait(returns_opaque_generic_duplicate());
+   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+   |
+   = note:    expected unit type `()`
+           found associated type `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated`
+   = help: consider constraining the associated type `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/async-await/issue-86507.rs b/src/test/ui/async-await/issue-86507.rs
new file mode 100644
index 00000000000..317f0317664
--- /dev/null
+++ b/src/test/ui/async-await/issue-86507.rs
@@ -0,0 +1,25 @@
+// edition:2018
+
+use ::core::pin::Pin;
+use ::core::future::Future;
+use ::core::marker::Send;
+
+trait Foo {
+    fn bar<'me, 'async_trait, T: Send>(x: &'me T)
+        -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
+        where 'me: 'async_trait;
+}
+
+impl Foo for () {
+    fn bar<'me, 'async_trait, T: Send>(x: &'me T)
+        -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
+        where 'me:'async_trait {
+            Box::pin( //~ ERROR future cannot be sent between threads safely
+                async move {
+                    let x = x;
+                }
+            )
+         }
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/issue-86507.stderr b/src/test/ui/async-await/issue-86507.stderr
new file mode 100644
index 00000000000..51e8f61085b
--- /dev/null
+++ b/src/test/ui/async-await/issue-86507.stderr
@@ -0,0 +1,23 @@
+error: future cannot be sent between threads safely
+  --> $DIR/issue-86507.rs:17:13
+   |
+LL | /             Box::pin(
+LL | |                 async move {
+LL | |                     let x = x;
+LL | |                 }
+LL | |             )
+   | |_____________^ future created by async block is not `Send`
+   |
+note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
+  --> $DIR/issue-86507.rs:19:29
+   |
+LL |                     let x = x;
+   |                             ^ has type `&T` which is not `Send`, because `T` is not `Sync`
+   = note: required for the cast to the object type `dyn Future<Output = ()> + Send`
+help: consider further restricting type parameter `T`
+   |
+LL |         where 'me:'async_trait, T: std::marker::Sync {
+   |                               ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
index eed90772d29..b6841da1f0b 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
@@ -1,15 +1,11 @@
 error: lifetime may not live long enough
-  --> $DIR/ret-impl-trait-one.rs:10:80
+  --> $DIR/ret-impl-trait-one.rs:10:65
    |
-LL |   async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
-   |  ________________________________--__--__________________________________________^
-   | |                                |   |
-   | |                                |   lifetime `'b` defined here
-   | |                                lifetime `'a` defined here
-LL | |
-LL | |     (a, b)
-LL | | }
-   | |_^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+   |                                --  --                           ^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
+   |                                |   |
+   |                                |   lifetime `'b` defined here
+   |                                lifetime `'a` defined here
    |
    = help: consider adding the following bound: `'b: 'a`
 
diff --git a/src/test/ui/bastion-of-the-turbofish.rs b/src/test/ui/bastion-of-the-turbofish.rs
index d9ca7ddc7ca..233ddbbe117 100644
--- a/src/test/ui/bastion-of-the-turbofish.rs
+++ b/src/test/ui/bastion-of-the-turbofish.rs
@@ -25,9 +25,12 @@
 //
 // My heart aches in sorrow, for I know I am defeated. Let this be a warning
 // to all those who come after. Here stands the bastion of the Turbofish.
+//
+// RIP Anna Harren, Guardian Angel of the Hallowed Turbofish. <3
 
 // See https://github.com/rust-lang/rust/pull/53562
 // and https://github.com/rust-lang/rfcs/pull/2527
+// and https://twitter.com/garblefart/status/1393236602856611843
 // for context.
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-assign-to-subfield.rs b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs
index dfa3a561ec7..050d702b625 100644
--- a/src/test/ui/borrowck/borrowck-assign-to-subfield.rs
+++ b/src/test/ui/borrowck/borrowck-assign-to-subfield.rs
@@ -1,6 +1,5 @@
 // run-pass
 // pretty-expanded FIXME #23616
-#![allow(dead_code)]
 
 pub fn main() {
     struct A {
diff --git a/src/test/ui/const-generics/auxiliary/impl-const.rs b/src/test/ui/const-generics/issues/auxiliary/impl-const.rs
index 4a6b5784221..4a6b5784221 100644
--- a/src/test/ui/const-generics/auxiliary/impl-const.rs
+++ b/src/test/ui/const-generics/issues/auxiliary/impl-const.rs
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr b/src/test/ui/const-generics/issues/issue-61522-array-len-succ.full.stderr
index 56deec16548..56deec16548 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61522-array-len-succ.full.stderr
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr b/src/test/ui/const-generics/issues/issue-61522-array-len-succ.min.stderr
index 36a0a37ae9c..36a0a37ae9c 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61522-array-len-succ.min.stderr
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.rs b/src/test/ui/const-generics/issues/issue-61522-array-len-succ.rs
index d4a948b9259..d4a948b9259 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.rs
+++ b/src/test/ui/const-generics/issues/issue-61522-array-len-succ.rs
diff --git a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr b/src/test/ui/const-generics/issues/issue-66596-impl-trait-for-str-const-arg.min.stderr
index e96b9e70352..e96b9e70352 100644
--- a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-66596-impl-trait-for-str-const-arg.min.stderr
diff --git a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs b/src/test/ui/const-generics/issues/issue-66596-impl-trait-for-str-const-arg.rs
index 2a741ba87a9..2a741ba87a9 100644
--- a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs
+++ b/src/test/ui/const-generics/issues/issue-66596-impl-trait-for-str-const-arg.rs
diff --git a/src/test/ui/const-generics/issue-67375.full.stderr b/src/test/ui/const-generics/issues/issue-67375.full.stderr
index 0fe65272f1b..0fe65272f1b 100644
--- a/src/test/ui/const-generics/issue-67375.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-67375.full.stderr
diff --git a/src/test/ui/const-generics/issue-67375.min.stderr b/src/test/ui/const-generics/issues/issue-67375.min.stderr
index be81fa92129..be81fa92129 100644
--- a/src/test/ui/const-generics/issue-67375.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67375.min.stderr
diff --git a/src/test/ui/const-generics/issue-67375.rs b/src/test/ui/const-generics/issues/issue-67375.rs
index a8875b8b6bf..a8875b8b6bf 100644
--- a/src/test/ui/const-generics/issue-67375.rs
+++ b/src/test/ui/const-generics/issues/issue-67375.rs
diff --git a/src/test/ui/const-generics/issue-67945-1.full.stderr b/src/test/ui/const-generics/issues/issue-67945-1.full.stderr
index 63c50b5ca54..63c50b5ca54 100644
--- a/src/test/ui/const-generics/issue-67945-1.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-67945-1.full.stderr
diff --git a/src/test/ui/const-generics/issue-67945-1.min.stderr b/src/test/ui/const-generics/issues/issue-67945-1.min.stderr
index 074d36c8ef3..074d36c8ef3 100644
--- a/src/test/ui/const-generics/issue-67945-1.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67945-1.min.stderr
diff --git a/src/test/ui/const-generics/issue-67945-1.rs b/src/test/ui/const-generics/issues/issue-67945-1.rs
index 84737e4e985..84737e4e985 100644
--- a/src/test/ui/const-generics/issue-67945-1.rs
+++ b/src/test/ui/const-generics/issues/issue-67945-1.rs
diff --git a/src/test/ui/const-generics/issue-67945-2.full.stderr b/src/test/ui/const-generics/issues/issue-67945-2.full.stderr
index b9004060231..b9004060231 100644
--- a/src/test/ui/const-generics/issue-67945-2.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-67945-2.full.stderr
diff --git a/src/test/ui/const-generics/issue-67945-2.min.stderr b/src/test/ui/const-generics/issues/issue-67945-2.min.stderr
index c06df79f842..c06df79f842 100644
--- a/src/test/ui/const-generics/issue-67945-2.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67945-2.min.stderr
diff --git a/src/test/ui/const-generics/issue-67945-2.rs b/src/test/ui/const-generics/issues/issue-67945-2.rs
index 4a46786e9a9..4a46786e9a9 100644
--- a/src/test/ui/const-generics/issue-67945-2.rs
+++ b/src/test/ui/const-generics/issues/issue-67945-2.rs
diff --git a/src/test/ui/const-generics/issue-67945-3.full.stderr b/src/test/ui/const-generics/issues/issue-67945-3.full.stderr
index fa66252bd69..fa66252bd69 100644
--- a/src/test/ui/const-generics/issue-67945-3.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-67945-3.full.stderr
diff --git a/src/test/ui/const-generics/issue-67945-3.min.stderr b/src/test/ui/const-generics/issues/issue-67945-3.min.stderr
index 5c30429c895..5c30429c895 100644
--- a/src/test/ui/const-generics/issue-67945-3.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67945-3.min.stderr
diff --git a/src/test/ui/const-generics/issue-67945-3.rs b/src/test/ui/const-generics/issues/issue-67945-3.rs
index 5bad61cfc76..5bad61cfc76 100644
--- a/src/test/ui/const-generics/issue-67945-3.rs
+++ b/src/test/ui/const-generics/issues/issue-67945-3.rs
diff --git a/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs b/src/test/ui/const-generics/issues/issue-68104-print-stack-overflow.rs
index 43c3999133c..43c3999133c 100644
--- a/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs
+++ b/src/test/ui/const-generics/issues/issue-68104-print-stack-overflow.rs
diff --git a/src/test/ui/const-generics/issue-70180-1-stalled_on.rs b/src/test/ui/const-generics/issues/issue-70180-1-stalled_on.rs
index f0554823273..f0554823273 100644
--- a/src/test/ui/const-generics/issue-70180-1-stalled_on.rs
+++ b/src/test/ui/const-generics/issues/issue-70180-1-stalled_on.rs
diff --git a/src/test/ui/const-generics/issue-70180-2-stalled_on.rs b/src/test/ui/const-generics/issues/issue-70180-2-stalled_on.rs
index 21cefc09c25..21cefc09c25 100644
--- a/src/test/ui/const-generics/issue-70180-2-stalled_on.rs
+++ b/src/test/ui/const-generics/issues/issue-70180-2-stalled_on.rs
diff --git a/src/test/ui/const-generics/issue-71202.rs b/src/test/ui/const-generics/issues/issue-71202.rs
index 78dee1717f1..78dee1717f1 100644
--- a/src/test/ui/const-generics/issue-71202.rs
+++ b/src/test/ui/const-generics/issues/issue-71202.rs
diff --git a/src/test/ui/const-generics/issue-71986.rs b/src/test/ui/const-generics/issues/issue-71986.rs
index 6bfdba5711e..6bfdba5711e 100644
--- a/src/test/ui/const-generics/issue-71986.rs
+++ b/src/test/ui/const-generics/issues/issue-71986.rs
diff --git a/src/test/ui/const-generics/issue-73899.rs b/src/test/ui/const-generics/issues/issue-73899.rs
index 2a3a5ab2a3b..2a3a5ab2a3b 100644
--- a/src/test/ui/const-generics/issue-73899.rs
+++ b/src/test/ui/const-generics/issues/issue-73899.rs
diff --git a/src/test/ui/const-generics/issue-74906.rs b/src/test/ui/const-generics/issues/issue-74906.rs
index dc3c33736da..dc3c33736da 100644
--- a/src/test/ui/const-generics/issue-74906.rs
+++ b/src/test/ui/const-generics/issues/issue-74906.rs
diff --git a/src/test/ui/const-generics/issue-75763.rs b/src/test/ui/const-generics/issues/issue-75763.rs
index c311de05a1c..c311de05a1c 100644
--- a/src/test/ui/const-generics/issue-75763.rs
+++ b/src/test/ui/const-generics/issues/issue-75763.rs
diff --git a/src/test/ui/const-generics/issue-79518-default_trait_method_normalization.rs b/src/test/ui/const-generics/issues/issue-79518-default_trait_method_normalization.rs
index 8f02bfb937a..8f02bfb937a 100644
--- a/src/test/ui/const-generics/issue-79518-default_trait_method_normalization.rs
+++ b/src/test/ui/const-generics/issues/issue-79518-default_trait_method_normalization.rs
diff --git a/src/test/ui/const-generics/issue-79518-default_trait_method_normalization.stderr b/src/test/ui/const-generics/issues/issue-79518-default_trait_method_normalization.stderr
index c90774e944f..c90774e944f 100644
--- a/src/test/ui/const-generics/issue-79518-default_trait_method_normalization.stderr
+++ b/src/test/ui/const-generics/issues/issue-79518-default_trait_method_normalization.stderr
diff --git a/src/test/ui/const-generics/issue-80561-incorrect-param-env.rs b/src/test/ui/const-generics/issues/issue-80561-incorrect-param-env.rs
index a34d74b29e9..a34d74b29e9 100644
--- a/src/test/ui/const-generics/issue-80561-incorrect-param-env.rs
+++ b/src/test/ui/const-generics/issues/issue-80561-incorrect-param-env.rs
diff --git a/src/test/ui/const-generics/issue-86820.rs b/src/test/ui/const-generics/issues/issue-86820.rs
index 04650403c6b..04650403c6b 100644
--- a/src/test/ui/const-generics/issue-86820.rs
+++ b/src/test/ui/const-generics/issues/issue-86820.rs
diff --git a/src/test/ui/const-generics/issue-86820.stderr b/src/test/ui/const-generics/issues/issue-86820.stderr
index f4396f2f2b0..f4396f2f2b0 100644
--- a/src/test/ui/const-generics/issue-86820.stderr
+++ b/src/test/ui/const-generics/issues/issue-86820.stderr
diff --git a/src/test/ui/const-generics/issues/issue-87076.rs b/src/test/ui/const-generics/issues/issue-87076.rs
new file mode 100644
index 00000000000..5dfda943bf6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-87076.rs
@@ -0,0 +1,20 @@
+// build-pass
+
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+#[derive(PartialEq, Eq)]
+pub struct UnitDims {
+    pub time: u8,
+    pub length: u8,
+}
+
+pub struct UnitValue<const DIMS: UnitDims>;
+
+impl<const DIMS: UnitDims> UnitValue<DIMS> {
+    fn crash() {}
+}
+
+fn main() {
+    UnitValue::<{ UnitDims { time: 1, length: 2 } }>::crash();
+}
diff --git a/src/test/ui/crate-loading/missing-std.rs b/src/test/ui/crate-loading/missing-std.rs
index de4ccc18560..1a34c21ba54 100644
--- a/src/test/ui/crate-loading/missing-std.rs
+++ b/src/test/ui/crate-loading/missing-std.rs
@@ -1,7 +1,6 @@
 // compile-flags: --target x86_64-unknown-uefi
 // needs-llvm-components: x86
 // rustc-env:CARGO=/usr/bin/cargo
-// rustc-env:RUSTUP_HOME=/home/bors/.rustup
 #![no_core]
 extern crate core;
 //~^ ERROR can't find crate for `core`
diff --git a/src/test/ui/crate-loading/missing-std.stderr b/src/test/ui/crate-loading/missing-std.stderr
index e61486fdc6f..25808efdfa6 100644
--- a/src/test/ui/crate-loading/missing-std.stderr
+++ b/src/test/ui/crate-loading/missing-std.stderr
@@ -1,5 +1,5 @@
 error[E0463]: can't find crate for `core`
-  --> $DIR/missing-std.rs:6:1
+  --> $DIR/missing-std.rs:5:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ can't find crate
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
index 087f4582b21..c2fbbf94fd6 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.rs
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -12,7 +12,6 @@ fn main() {
 fn cycle1() -> impl Clone {
     //~^ ERROR cycle detected
     send(cycle2().clone());
-    //~^ ERROR cannot be sent between threads safely
 
     Rc::new(Cell::new(5))
 }
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index e578c4b4f81..3eb141cc2bb 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
 note: ...which requires computing type of `cycle2::{opaque#0}`...
-  --> $DIR/auto-trait-leak.rs:20:16
+  --> $DIR/auto-trait-leak.rs:19:16
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
 note: ...which requires borrow-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires processing `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires processing MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires unsafety-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires building MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:20:1
+  --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,22 +84,6 @@ LL | |     Rc::new(String::from("foo"))
 LL | | }
    | |_^
 
-error[E0277]: `Rc<String>` cannot be sent between threads safely
-  --> $DIR/auto-trait-leak.rs:14:5
-   |
-LL | fn send<T: Send>(_: T) {}
-   |            ---- required by this bound in `send`
-...
-LL |     send(cycle2().clone());
-   |     ^^^^ `Rc<String>` cannot be sent between threads safely
-...
-LL | fn cycle2() -> impl Clone {
-   |                ---------- within this `impl Clone`
-   |
-   = help: within `impl Clone`, the trait `Send` is not implemented for `Rc<String>`
-   = note: required because it appears within the type `impl Clone`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0277, E0391.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/impl-trait/issue-86465.rs b/src/test/ui/impl-trait/issue-86465.rs
new file mode 100644
index 00000000000..23a3748c12c
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-86465.rs
@@ -0,0 +1,10 @@
+#![feature(min_type_alias_impl_trait)]
+
+type X<'a, 'b> = impl std::fmt::Debug;
+
+fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+    //~^ ERROR concrete type differs from previous defining opaque type use
+    (a, a)
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issue-86465.stderr b/src/test/ui/impl-trait/issue-86465.stderr
new file mode 100644
index 00000000000..595b16aa685
--- /dev/null
+++ b/src/test/ui/impl-trait/issue-86465.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/issue-86465.rs:5:1
+   |
+LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a u32`, got `&'b u32`
+   |
+note: previous use here
+  --> $DIR/issue-86465.rs:5:1
+   |
+LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/impl-trait/issues/issue-54600.rs b/src/test/ui/impl-trait/issues/issue-54600.rs
new file mode 100644
index 00000000000..7a647993023
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-54600.rs
@@ -0,0 +1,7 @@
+use std::fmt::Debug;
+
+fn main() {
+    let x: Option<impl Debug> = Some(44_u32);
+    //~^ `impl Trait` not allowed outside of function and method return types
+    println!("{:?}", x);
+}
diff --git a/src/test/ui/impl-trait/issues/issue-54600.stderr b/src/test/ui/impl-trait/issues/issue-54600.stderr
new file mode 100644
index 00000000000..4d0c32c6bb7
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-54600.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-54600.rs:4:19
+   |
+LL |     let x: Option<impl Debug> = Some(44_u32);
+   |                   ^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-54840.rs b/src/test/ui/impl-trait/issues/issue-54840.rs
new file mode 100644
index 00000000000..030d5715d57
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-54840.rs
@@ -0,0 +1,7 @@
+use std::ops::Add;
+
+fn main() {
+    let i: i32 = 0;
+    let j: &impl Add = &i;
+    //~^ `impl Trait` not allowed outside of function and method return types
+}
diff --git a/src/test/ui/impl-trait/issues/issue-54840.stderr b/src/test/ui/impl-trait/issues/issue-54840.stderr
new file mode 100644
index 00000000000..b8046b7482f
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-54840.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-54840.rs:5:13
+   |
+LL |     let j: &impl Add = &i;
+   |             ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-58504.rs b/src/test/ui/impl-trait/issues/issue-58504.rs
new file mode 100644
index 00000000000..aac33b3b3e5
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-58504.rs
@@ -0,0 +1,12 @@
+#![feature(generators, generator_trait, never_type)]
+
+use std::ops::Generator;
+
+fn mk_gen() -> impl Generator<Return=!, Yield=()> {
+    || { loop { yield; } }
+}
+
+fn main() {
+    let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
+    //~^ `impl Trait` not allowed outside of function and method return types
+}
diff --git a/src/test/ui/impl-trait/issues/issue-58504.stderr b/src/test/ui/impl-trait/issues/issue-58504.stderr
new file mode 100644
index 00000000000..ff1010f0661
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-58504.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-58504.rs:10:16
+   |
+LL |     let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-58956.rs b/src/test/ui/impl-trait/issues/issue-58956.rs
new file mode 100644
index 00000000000..5fe18b6e9b5
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-58956.rs
@@ -0,0 +1,14 @@
+trait Lam {}
+
+pub struct B;
+impl Lam for B {}
+pub struct Wrap<T>(T);
+
+const _A: impl Lam = {
+    //~^ `impl Trait` not allowed outside of function and method return types
+    let x: Wrap<impl Lam> = Wrap(B);
+    //~^ `impl Trait` not allowed outside of function and method return types
+    x.0
+};
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-58956.stderr b/src/test/ui/impl-trait/issues/issue-58956.stderr
new file mode 100644
index 00000000000..00ebf170ab2
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-58956.stderr
@@ -0,0 +1,15 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-58956.rs:7:11
+   |
+LL | const _A: impl Lam = {
+   |           ^^^^^^^^
+
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-58956.rs:9:17
+   |
+LL |     let x: Wrap<impl Lam> = Wrap(B);
+   |                 ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-70971.rs b/src/test/ui/impl-trait/issues/issue-70971.rs
new file mode 100644
index 00000000000..d4dc2fd877b
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-70971.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let x : (impl Copy,) = (true,);
+    //~^ `impl Trait` not allowed outside of function and method return types
+}
diff --git a/src/test/ui/impl-trait/issues/issue-70971.stderr b/src/test/ui/impl-trait/issues/issue-70971.stderr
new file mode 100644
index 00000000000..31993da3e32
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-70971.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-70971.rs:2:14
+   |
+LL |     let x : (impl Copy,) = (true,);
+   |              ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-79099.rs b/src/test/ui/impl-trait/issues/issue-79099.rs
new file mode 100644
index 00000000000..f72533d42e1
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-79099.rs
@@ -0,0 +1,10 @@
+struct Bug {
+    V1: [(); {
+        let f: impl core::future::Future<Output = u8> = async { 1 };
+        //~^ `impl Trait` not allowed outside of function and method return types
+        //~| expected identifier
+        1
+    }],
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-79099.stderr b/src/test/ui/impl-trait/issues/issue-79099.stderr
new file mode 100644
index 00000000000..121536d3f68
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-79099.stderr
@@ -0,0 +1,20 @@
+error: expected identifier, found `1`
+  --> $DIR/issue-79099.rs:3:65
+   |
+LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
+   |                                                         -----   ^ expected identifier
+   |                                                         |
+   |                                                         `async` blocks are only allowed in Rust 2018 or later
+   |
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-79099.rs:3:16
+   |
+LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-84919.rs b/src/test/ui/impl-trait/issues/issue-84919.rs
new file mode 100644
index 00000000000..479bad97cdf
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-84919.rs
@@ -0,0 +1,9 @@
+trait Trait {}
+impl Trait for () {}
+
+fn foo<'a: 'a>() {
+    let _x: impl Trait = ();
+    //~^ `impl Trait` not allowed outside of function and method return types
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-84919.stderr b/src/test/ui/impl-trait/issues/issue-84919.stderr
new file mode 100644
index 00000000000..bb1bcfefe64
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-84919.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-84919.rs:5:13
+   |
+LL |     let _x: impl Trait = ();
+   |             ^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-86201.rs b/src/test/ui/impl-trait/issues/issue-86201.rs
new file mode 100644
index 00000000000..8dc76f4f752
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-86201.rs
@@ -0,0 +1,13 @@
+#![feature(unboxed_closures)]
+#![feature(min_type_alias_impl_trait)]
+
+type FunType = impl Fn<()>;
+//~^ could not find defining uses
+static STATIC_FN: FunType = some_fn;
+//~^ mismatched types
+
+fn some_fn() {}
+
+fn main() {
+    let _: <FunType as FnOnce<()>>::Output = STATIC_FN();
+}
diff --git a/src/test/ui/impl-trait/issues/issue-86201.stderr b/src/test/ui/impl-trait/issues/issue-86201.stderr
new file mode 100644
index 00000000000..b1460096ded
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-86201.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-86201.rs:6:29
+   |
+LL | type FunType = impl Fn<()>;
+   |                ----------- the expected opaque type
+LL |
+LL | static STATIC_FN: FunType = some_fn;
+   |                             ^^^^^^^ expected opaque type, found fn item
+   |
+   = note: expected opaque type `impl Fn<()>`
+                  found fn item `fn() {some_fn}`
+
+error: could not find defining uses
+  --> $DIR/issue-86201.rs:4:16
+   |
+LL | type FunType = impl Fn<()>;
+   |                ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/issues/issue-86642.rs b/src/test/ui/impl-trait/issues/issue-86642.rs
new file mode 100644
index 00000000000..8953ff81581
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-86642.rs
@@ -0,0 +1,8 @@
+static x: impl Fn(&str) -> Result<&str, ()> = move |source| {
+    //~^ `impl Trait` not allowed outside of function and method return types
+    let res = (move |source| Ok(source))(source);
+    let res = res.or((move |source| Ok(source))(source));
+    res
+};
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-86642.stderr b/src/test/ui/impl-trait/issues/issue-86642.stderr
new file mode 100644
index 00000000000..2fc0a6fe1f5
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-86642.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-86642.rs:1:11
+   |
+LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/impl-trait/issues/issue-87295.rs b/src/test/ui/impl-trait/issues/issue-87295.rs
new file mode 100644
index 00000000000..2f2bfe147bd
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-87295.rs
@@ -0,0 +1,18 @@
+trait Trait {
+    type Output;
+}
+impl Trait for () {
+    type Output = i32;
+}
+
+struct Struct<F>(F);
+impl<F> Struct<F> {
+    pub fn new(_: F) -> Self {
+        todo!()
+    }
+}
+
+fn main() {
+    let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
+    //~^ `impl Trait` not allowed outside of function and method return types
+}
diff --git a/src/test/ui/impl-trait/issues/issue-87295.stderr b/src/test/ui/impl-trait/issues/issue-87295.stderr
new file mode 100644
index 00000000000..f5c7603ce49
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-87295.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` not allowed outside of function and method return types
+  --> $DIR/issue-87295.rs:16:31
+   |
+LL |     let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr
index c3a5d3dfeee..4400b6179c6 100644
--- a/src/test/ui/issues/issue-19380.stderr
+++ b/src/test/ui/issues/issue-19380.stderr
@@ -1,8 +1,8 @@
 error[E0038]: the trait `Qiz` cannot be made into an object
-  --> $DIR/issue-19380.rs:11:9
+  --> $DIR/issue-19380.rs:11:29
    |
 LL |   foos: &'static [&'static (dyn Qiz + 'static)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Qiz` cannot be made into an object
+   |                             ^^^^^^^^^^^^^^^^^ `Qiz` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
   --> $DIR/issue-19380.rs:2:6
diff --git a/src/test/ui/issues/issue-37131.stderr b/src/test/ui/issues/issue-37131.stderr
index 660a6935f36..b45574f0c49 100644
--- a/src/test/ui/issues/issue-37131.stderr
+++ b/src/test/ui/issues/issue-37131.stderr
@@ -1,6 +1,8 @@
 error[E0463]: can't find crate for `std`
    |
    = note: the `thumbv6m-none-eabi` target may not be installed
+   = help: consider downloading the target with `rustup target add thumbv6m-none-eabi`
+   = help: consider building the standard library from source with `cargo build -Zbuild-std`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr b/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr
index 7e23e0fd747..d963c07ea91 100644
--- a/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr
+++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr
@@ -1,6 +1,8 @@
 error[E0463]: can't find crate for `core`
    |
    = note: the `thumbv7em-none-eabihf` target may not be installed
+   = help: consider downloading the target with `rustup target add thumbv7em-none-eabihf`
+   = help: consider building the standard library from source with `cargo build -Zbuild-std`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/dead-code/self-assign.rs b/src/test/ui/lint/dead-code/self-assign.rs
index b8bf7d860c4..ea7ce98d884 100644
--- a/src/test/ui/lint/dead-code/self-assign.rs
+++ b/src/test/ui/lint/dead-code/self-assign.rs
@@ -1,6 +1,8 @@
 // Test that dead code warnings are issued for superfluous assignments of
 // fields or variables to themselves (issue #75356).
 
+// ignore-test FIXME(81658, 83171)
+
 // check-pass
 #![allow(unused_assignments)]
 #![warn(dead_code)]
diff --git a/src/test/ui/lint/dead-code/write-only-field.rs b/src/test/ui/lint/dead-code/write-only-field.rs
deleted file mode 100644
index 7b3f1e9f5b6..00000000000
--- a/src/test/ui/lint/dead-code/write-only-field.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-#![deny(dead_code)]
-
-struct S {
-    f: i32, //~ ERROR: field is never read
-    sub: Sub, //~ ERROR: field is never read
-}
-
-struct Sub {
-    f: i32, //~ ERROR: field is never read
-}
-
-fn field_write(s: &mut S) {
-    s.f = 1;
-    s.sub.f = 2;
-}
-
-fn main() {
-    let mut s = S { f: 0, sub: Sub { f: 0 } };
-    field_write(&mut s);
-
-    auto_deref();
-    nested_boxes();
-}
-
-fn auto_deref() {
-    struct E {
-        x: bool,
-        y: bool, //~ ERROR: field is never read
-    }
-
-    struct P<'a> {
-        e: &'a mut E
-    }
-
-    impl P<'_> {
-        fn f(&mut self) {
-            self.e.x = true;
-            self.e.y = true;
-        }
-    }
-
-    let mut e = E { x: false, y: false };
-    let mut p = P { e: &mut e };
-    p.f();
-    assert!(e.x);
-}
-
-fn nested_boxes() {
-    struct A {
-        b: Box<B>,
-    }
-
-    struct B {
-        c: Box<C>,
-    }
-
-    struct C {
-        u: u32, //~ ERROR: field is never read
-        v: u32, //~ ERROR: field is never read
-    }
-
-    let mut a = A {
-        b: Box::new(B {
-            c: Box::new(C { u: 0, v: 0 }),
-        }),
-    };
-    a.b.c.v = 10;
-    a.b.c = Box::new(C { u: 1, v: 2 });
-}
diff --git a/src/test/ui/lint/dead-code/write-only-field.stderr b/src/test/ui/lint/dead-code/write-only-field.stderr
deleted file mode 100644
index a191d22c8b9..00000000000
--- a/src/test/ui/lint/dead-code/write-only-field.stderr
+++ /dev/null
@@ -1,44 +0,0 @@
-error: field is never read: `f`
-  --> $DIR/write-only-field.rs:4:5
-   |
-LL |     f: i32,
-   |     ^^^^^^
-   |
-note: the lint level is defined here
-  --> $DIR/write-only-field.rs:1:9
-   |
-LL | #![deny(dead_code)]
-   |         ^^^^^^^^^
-
-error: field is never read: `sub`
-  --> $DIR/write-only-field.rs:5:5
-   |
-LL |     sub: Sub,
-   |     ^^^^^^^^
-
-error: field is never read: `f`
-  --> $DIR/write-only-field.rs:9:5
-   |
-LL |     f: i32,
-   |     ^^^^^^
-
-error: field is never read: `y`
-  --> $DIR/write-only-field.rs:28:9
-   |
-LL |         y: bool,
-   |         ^^^^^^^
-
-error: field is never read: `u`
-  --> $DIR/write-only-field.rs:58:9
-   |
-LL |         u: u32,
-   |         ^^^^^^
-
-error: field is never read: `v`
-  --> $DIR/write-only-field.rs:59:9
-   |
-LL |         v: u32,
-   |         ^^^^^^
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/lint/inert-attr-macro.rs b/src/test/ui/lint/inert-attr-macro.rs
new file mode 100644
index 00000000000..dc0bb8ac265
--- /dev/null
+++ b/src/test/ui/lint/inert-attr-macro.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+#![warn(unused)]
+
+macro_rules! foo {
+    () => {}
+}
+
+fn main() {
+    #[inline] foo!(); //~ WARN unused attribute `inline`
+
+    // This does nothing, since `#[allow(warnings)]` is itself
+    // an inert attribute on a macro call
+    #[allow(warnings)] #[inline] foo!(); //~ WARN unused attribute `allow`
+    //~^ WARN unused attribute `inline`
+
+    // This does work, since the attribute is on a parent
+    // of the macro invocation.
+    #[allow(warnings)] { #[inline] foo!(); }
+}
diff --git a/src/test/ui/lint/inert-attr-macro.stderr b/src/test/ui/lint/inert-attr-macro.stderr
new file mode 100644
index 00000000000..3b3aa5d0bc0
--- /dev/null
+++ b/src/test/ui/lint/inert-attr-macro.stderr
@@ -0,0 +1,44 @@
+warning: unused attribute `inline`
+  --> $DIR/inert-attr-macro.rs:10:5
+   |
+LL |     #[inline] foo!();
+   |     ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/inert-attr-macro.rs:3:9
+   |
+LL | #![warn(unused)]
+   |         ^^^^^^
+   = note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]`
+note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
+  --> $DIR/inert-attr-macro.rs:10:15
+   |
+LL |     #[inline] foo!();
+   |               ^^^
+
+warning: unused attribute `allow`
+  --> $DIR/inert-attr-macro.rs:14:5
+   |
+LL |     #[allow(warnings)] #[inline] foo!();
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `foo`
+  --> $DIR/inert-attr-macro.rs:14:34
+   |
+LL |     #[allow(warnings)] #[inline] foo!();
+   |                                  ^^^
+
+warning: unused attribute `inline`
+  --> $DIR/inert-attr-macro.rs:14:24
+   |
+LL |     #[allow(warnings)] #[inline] foo!();
+   |                        ^^^^^^^^^
+   |
+note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo`
+  --> $DIR/inert-attr-macro.rs:14:34
+   |
+LL |     #[allow(warnings)] #[inline] foo!();
+   |                                  ^^^
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/repr/repr-no-niche.rs b/src/test/ui/repr/repr-no-niche.rs
index a7f0d509af5..2e6064aeb00 100644
--- a/src/test/ui/repr/repr-no-niche.rs
+++ b/src/test/ui/repr/repr-no-niche.rs
@@ -73,8 +73,7 @@ mod enum_inline {
     // general; this test is relying on that.)
     two_fifty_six_variant_enum!(Visible2, N8);
 
-    #[repr(no_niche)]
-    two_fifty_six_variant_enum!(Cloaked2, N8);
+    two_fifty_six_variant_enum!(#[repr(no_niche)] Cloaked2, N8);
 }
 
 mod enum_param {
@@ -96,8 +95,7 @@ mod enum_param {
     // here as above (assuming `T` is instantiated with `NonZeroU8`).
     two_fifty_six_variant_enum!(Visible2<T>);
 
-    #[repr(no_niche)]
-    two_fifty_six_variant_enum!(Cloaked2<T>);
+    two_fifty_six_variant_enum!(#[repr(no_niche)] Cloaked2<T>);
 }
 
 fn main() {
@@ -157,8 +155,8 @@ fn main() {
 }
 
 macro two_fifty_six_variant_enum {
-    ($name:ident<$param:ident>) => {
-        #[derive(Debug)]
+    ($(#[$attr:meta])* $name:ident<$param:ident>) => {
+        #[derive(Debug)] $(#[$attr])*
         pub enum $name<$param> {
             _V00($param, u16), _V01(u16, $param), _V02($param, u16), _V03(u16, $param),
             _V04($param, u16), _V05(u16, $param), _V06($param, u16), _V07(u16, $param),
@@ -242,8 +240,8 @@ macro two_fifty_six_variant_enum {
         }
     },
 
-    ($name:ident, $param:ty) => {
-        #[derive(Debug)]
+    ($(#[$attr:meta])* $name:ident, $param:ty) => {
+        #[derive(Debug)] $(#[$attr])*
         pub enum $name {
             _V00($param, u16), _V01(u16, $param), _V02($param, u16), _V03(u16, $param),
             _V04($param, u16), _V05(u16, $param), _V06($param, u16), _V07(u16, $param),
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
index a678731934f..e25c6363515 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
@@ -1,8 +1,8 @@
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                          -                     ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |                          -          ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
    |                          |
    |                          let's call the lifetime of this reference `'1`
    |
diff --git a/src/test/ui/traits/vtable/vtable-diamond.rs b/src/test/ui/traits/vtable/vtable-diamond.rs
new file mode 100644
index 00000000000..f64ae95f1d4
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-diamond.rs
@@ -0,0 +1,39 @@
+// build-fail
+#![feature(rustc_attrs)]
+
+#[rustc_dump_vtable]
+trait A {
+    fn foo_a(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait B: A {
+    fn foo_b(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait C: A {
+    //~^ error Vtable
+    fn foo_c(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait D: B + C {
+    //~^ error Vtable
+    fn foo_d(&self) {}
+}
+
+struct S;
+
+impl A for S {}
+impl B for S {}
+impl C for S {}
+impl D for S {}
+
+fn foo(d: &dyn D) {
+    d.foo_d();
+}
+
+fn main() {
+    foo(&S);
+}
diff --git a/src/test/ui/traits/vtable/vtable-diamond.stderr b/src/test/ui/traits/vtable/vtable-diamond.stderr
new file mode 100644
index 00000000000..92a7f29536e
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-diamond.stderr
@@ -0,0 +1,35 @@
+error: Vtable entries for `<S as D>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as A>::foo_a),
+    Method(<S as B>::foo_b),
+    Method(<S as C>::foo_c),
+    TraitVPtr(<S as C>),
+    Method(<S as D>::foo_d),
+]
+  --> $DIR/vtable-diamond.rs:21:1
+   |
+LL | / trait D: B + C {
+LL | |
+LL | |     fn foo_d(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as C>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as A>::foo_a),
+    Method(<S as C>::foo_c),
+]
+  --> $DIR/vtable-diamond.rs:15:1
+   |
+LL | / trait C: A {
+LL | |
+LL | |     fn foo_c(&self) {}
+LL | | }
+   | |_^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/traits/vtable/vtable-multi-level.rs b/src/test/ui/traits/vtable/vtable-multi-level.rs
new file mode 100644
index 00000000000..33112b4eaaa
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-multi-level.rs
@@ -0,0 +1,122 @@
+// build-fail
+#![feature(rustc_attrs)]
+
+//   O --> G --> C --> A
+//     \     \     \-> B
+//     |     |-> F --> D
+//     |           \-> E
+//     |-> N --> J --> H
+//           \     \-> I
+//           |-> M --> K
+//                 \-> L
+
+#[rustc_dump_vtable]
+trait A {
+    fn foo_a(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait B {
+    //~^ error Vtable
+    fn foo_b(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait C: A + B {
+    fn foo_c(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait D {
+    //~^ error Vtable
+    fn foo_d(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait E {
+    //~^ error Vtable
+    fn foo_e(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait F: D + E {
+    //~^ error Vtable
+    fn foo_f(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait G: C + F {
+    fn foo_g(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait H {
+    //~^ error Vtable
+    fn foo_h(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait I {
+    //~^ error Vtable
+    fn foo_i(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait J: H + I {
+    //~^ error Vtable
+    fn foo_j(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait K {
+    //~^ error Vtable
+    fn foo_k(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait L {
+    //~^ error Vtable
+    fn foo_l(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait M: K + L {
+    //~^ error Vtable
+    fn foo_m(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait N: J + M {
+    //~^ error Vtable
+    fn foo_n(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait O: G + N {
+    //~^ error Vtable
+    fn foo_o(&self) {}
+}
+
+struct S;
+
+impl A for S {}
+impl B for S {}
+impl C for S {}
+impl D for S {}
+impl E for S {}
+impl F for S {}
+impl G for S {}
+impl H for S {}
+impl I for S {}
+impl J for S {}
+impl K for S {}
+impl L for S {}
+impl M for S {}
+impl N for S {}
+impl O for S {}
+
+fn foo(_: &dyn O) {}
+
+fn main() {
+    foo(&S);
+}
diff --git a/src/test/ui/traits/vtable/vtable-multi-level.stderr b/src/test/ui/traits/vtable/vtable-multi-level.stderr
new file mode 100644
index 00000000000..7700db98e0b
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-multi-level.stderr
@@ -0,0 +1,214 @@
+error: Vtable entries for `<S as O>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as A>::foo_a),
+    Method(<S as B>::foo_b),
+    TraitVPtr(<S as B>),
+    Method(<S as C>::foo_c),
+    Method(<S as D>::foo_d),
+    TraitVPtr(<S as D>),
+    Method(<S as E>::foo_e),
+    TraitVPtr(<S as E>),
+    Method(<S as F>::foo_f),
+    TraitVPtr(<S as F>),
+    Method(<S as G>::foo_g),
+    Method(<S as H>::foo_h),
+    TraitVPtr(<S as H>),
+    Method(<S as I>::foo_i),
+    TraitVPtr(<S as I>),
+    Method(<S as J>::foo_j),
+    TraitVPtr(<S as J>),
+    Method(<S as K>::foo_k),
+    TraitVPtr(<S as K>),
+    Method(<S as L>::foo_l),
+    TraitVPtr(<S as L>),
+    Method(<S as M>::foo_m),
+    TraitVPtr(<S as M>),
+    Method(<S as N>::foo_n),
+    TraitVPtr(<S as N>),
+    Method(<S as O>::foo_o),
+]
+  --> $DIR/vtable-multi-level.rs:95:1
+   |
+LL | / trait O: G + N {
+LL | |
+LL | |     fn foo_o(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as B>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as B>::foo_b),
+]
+  --> $DIR/vtable-multi-level.rs:19:1
+   |
+LL | / trait B {
+LL | |
+LL | |     fn foo_b(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as D>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as D>::foo_d),
+]
+  --> $DIR/vtable-multi-level.rs:30:1
+   |
+LL | / trait D {
+LL | |
+LL | |     fn foo_d(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as E>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as E>::foo_e),
+]
+  --> $DIR/vtable-multi-level.rs:36:1
+   |
+LL | / trait E {
+LL | |
+LL | |     fn foo_e(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as F>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as D>::foo_d),
+    Method(<S as E>::foo_e),
+    TraitVPtr(<S as E>),
+    Method(<S as F>::foo_f),
+]
+  --> $DIR/vtable-multi-level.rs:42:1
+   |
+LL | / trait F: D + E {
+LL | |
+LL | |     fn foo_f(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as H>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as H>::foo_h),
+]
+  --> $DIR/vtable-multi-level.rs:53:1
+   |
+LL | / trait H {
+LL | |
+LL | |     fn foo_h(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as I>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as I>::foo_i),
+]
+  --> $DIR/vtable-multi-level.rs:59:1
+   |
+LL | / trait I {
+LL | |
+LL | |     fn foo_i(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as J>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as H>::foo_h),
+    Method(<S as I>::foo_i),
+    TraitVPtr(<S as I>),
+    Method(<S as J>::foo_j),
+]
+  --> $DIR/vtable-multi-level.rs:65:1
+   |
+LL | / trait J: H + I {
+LL | |
+LL | |     fn foo_j(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as K>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as K>::foo_k),
+]
+  --> $DIR/vtable-multi-level.rs:71:1
+   |
+LL | / trait K {
+LL | |
+LL | |     fn foo_k(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as L>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as L>::foo_l),
+]
+  --> $DIR/vtable-multi-level.rs:77:1
+   |
+LL | / trait L {
+LL | |
+LL | |     fn foo_l(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as M>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as K>::foo_k),
+    Method(<S as L>::foo_l),
+    TraitVPtr(<S as L>),
+    Method(<S as M>::foo_m),
+]
+  --> $DIR/vtable-multi-level.rs:83:1
+   |
+LL | / trait M: K + L {
+LL | |
+LL | |     fn foo_m(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as N>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as H>::foo_h),
+    Method(<S as I>::foo_i),
+    TraitVPtr(<S as I>),
+    Method(<S as J>::foo_j),
+    Method(<S as K>::foo_k),
+    TraitVPtr(<S as K>),
+    Method(<S as L>::foo_l),
+    TraitVPtr(<S as L>),
+    Method(<S as M>::foo_m),
+    TraitVPtr(<S as M>),
+    Method(<S as N>::foo_n),
+]
+  --> $DIR/vtable-multi-level.rs:89:1
+   |
+LL | / trait N: J + M {
+LL | |
+LL | |     fn foo_n(&self) {}
+LL | | }
+   | |_^
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/traits/vtable/vtable-multiple.rs b/src/test/ui/traits/vtable/vtable-multiple.rs
new file mode 100644
index 00000000000..cb0d0b72481
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-multiple.rs
@@ -0,0 +1,31 @@
+// build-fail
+#![feature(rustc_attrs)]
+
+#[rustc_dump_vtable]
+trait A {
+    fn foo_a(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait B {
+    //~^ error Vtable
+    fn foo_b(&self) {}
+}
+
+#[rustc_dump_vtable]
+trait C: A + B {
+    //~^ error Vtable
+    fn foo_c(&self) {}
+}
+
+struct S;
+
+impl A for S {}
+impl B for S {}
+impl C for S {}
+
+fn foo(c: &dyn C) {}
+
+fn main() {
+    foo(&S);
+}
diff --git a/src/test/ui/traits/vtable/vtable-multiple.stderr b/src/test/ui/traits/vtable/vtable-multiple.stderr
new file mode 100644
index 00000000000..f51b083de25
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-multiple.stderr
@@ -0,0 +1,33 @@
+error: Vtable entries for `<S as C>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as A>::foo_a),
+    Method(<S as B>::foo_b),
+    TraitVPtr(<S as B>),
+    Method(<S as C>::foo_c),
+]
+  --> $DIR/vtable-multiple.rs:16:1
+   |
+LL | / trait C: A + B {
+LL | |
+LL | |     fn foo_c(&self) {}
+LL | | }
+   | |_^
+
+error: Vtable entries for `<S as B>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as B>::foo_b),
+]
+  --> $DIR/vtable-multiple.rs:10:1
+   |
+LL | / trait B {
+LL | |
+LL | |     fn foo_b(&self) {}
+LL | | }
+   | |_^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/traits/vtable/vtable-vacant.rs b/src/test/ui/traits/vtable/vtable-vacant.rs
new file mode 100644
index 00000000000..ebea94171f2
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-vacant.rs
@@ -0,0 +1,28 @@
+// build-fail
+#![feature(rustc_attrs)]
+
+// B --> A
+
+#[rustc_dump_vtable]
+trait A {
+    fn foo_a1(&self) {}
+    fn foo_a2(&self) where Self: Sized {}
+}
+
+#[rustc_dump_vtable]
+trait B: A {
+    //~^ error Vtable
+    fn foo_b1(&self) {}
+    fn foo_b2() where Self: Sized {}
+}
+
+struct S;
+
+impl A for S {}
+impl B for S {}
+
+fn foo(_: &dyn B) {}
+
+fn main() {
+    foo(&S);
+}
diff --git a/src/test/ui/traits/vtable/vtable-vacant.stderr b/src/test/ui/traits/vtable/vtable-vacant.stderr
new file mode 100644
index 00000000000..768cca52689
--- /dev/null
+++ b/src/test/ui/traits/vtable/vtable-vacant.stderr
@@ -0,0 +1,20 @@
+error: Vtable entries for `<S as B>`: [
+    MetadataDropInPlace,
+    MetadataSize,
+    MetadataAlign,
+    Method(<S as A>::foo_a1),
+    Vacant,
+    Method(<S as B>::foo_b1),
+    Vacant,
+]
+  --> $DIR/vtable-vacant.rs:13:1
+   |
+LL | / trait B: A {
+LL | |
+LL | |     fn foo_b1(&self) {}
+LL | |     fn foo_b2() where Self: Sized {}
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr
index d0f3be336dc..28ac61a6b98 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.nll.stderr
@@ -28,7 +28,7 @@ LL | type WrongGeneric<T> = impl 'static;
            found opaque type `impl Sized`
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:17:30
+  --> $DIR/generic_type_does_not_live_long_enough.rs:16:30
    |
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                              ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
index 6394a1f8e85..90a753b5a6d 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr
@@ -36,16 +36,7 @@ LL | type WrongGeneric<T> = impl 'static;
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                  - help: consider adding an explicit lifetime bound...: `T: 'static`
 
-error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:12:24
-   |
-LL | type WrongGeneric<T> = impl 'static;
-   |                        ^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: 'static`...
-   = note: ...so that the type `T` will meet its required lifetime bounds
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0308, E0310.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr
index 7496d96fa21..b8ca8e46079 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.nll.stderr
@@ -19,7 +19,7 @@ LL | type WrongGeneric<T> = impl 'static;
            found opaque type `impl Sized`
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:17:30
+  --> $DIR/generic_type_does_not_live_long_enough.rs:16:30
    |
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                              ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
index 49ead8b094c..e5028220107 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr
@@ -27,16 +27,7 @@ LL | type WrongGeneric<T> = impl 'static;
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                  - help: consider adding an explicit lifetime bound...: `T: 'static`
 
-error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:12:24
-   |
-LL | type WrongGeneric<T> = impl 'static;
-   |                        ^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: 'static`...
-   = note: ...so that the type `T` will meet its required lifetime bounds
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0308, E0310.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
index 3dda34ff668..9f647d9e737 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
@@ -11,7 +11,6 @@ fn main() {
 
 type WrongGeneric<T> = impl 'static;
 //~^ ERROR the parameter type `T` may not live long enough
-//~| ERROR the parameter type `T` may not live long enough
 //~| ERROR: at least one trait must be specified
 
 fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr
index 481d66dd811..e2b8b19aeba 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.nll.stderr
@@ -8,13 +8,13 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
 
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
@@ -28,7 +28,7 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: expected type `for<'r> Fn<(&'r X,)>`
               found type `Fn<(&'static X,)>`
 note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
index d90f328708a..61e8da91bba 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr
@@ -16,52 +16,5 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 5 previous errors; 1 warning emitted
+error: aborting due to previous error; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr
index 0343a769564..3a4d1d90c03 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.nll.stderr
@@ -1,11 +1,11 @@
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
@@ -19,7 +19,7 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: expected type `for<'r> Fn<(&'r X,)>`
               found type `Fn<(&'static X,)>`
 note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
+  --> $DIR/issue-57611-trait-alias.rs:24:9
    |
 LL |         |x| x
    |         ^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
index d019f40757e..f65e91e52c7 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr
@@ -7,52 +7,5 @@ LL |     type Bar = impl Baz<Self, Self>;
    = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
-   |
-   = note: expected type `for<'r> Fn<(&'r X,)>`
-              found type `Fn<(&'<empty> X,)>`
-note: this closure does not fulfill the lifetime requirements
-  --> $DIR/issue-57611-trait-alias.rs:28:9
-   |
-LL |         |x| x
-   |         ^^^^^
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/issue-57611-trait-alias.rs:20:16
-   |
-LL |     type Bar = impl Baz<Self, Self>;
-   |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
-   |
-   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
-   = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 5 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
index ccc727e0bf0..508ecdd88a4 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -19,10 +19,6 @@ struct X;
 impl Foo for X {
     type Bar = impl Baz<Self, Self>;
     //~^ ERROR implementation of `FnOnce` is not general enough
-    //~| ERROR implementation of `FnOnce` is not general enough
-    //~| ERROR implementation of `FnOnce` is not general enough
-    //~| ERROR mismatched types
-    //~| ERROR mismatched types
 
     fn bar(&self) -> Self::Bar {
         |x| x
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs
index b7c8a58a656..cee5e5a01cc 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs
@@ -9,7 +9,6 @@ trait Bug {
 impl Bug for &() {
     type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable
     //~^ ERROR the trait bound `(): Bug` is not satisfied
-    //~^^ ERROR the trait bound `(): Bug` is not satisfied
 
     const FUN: fn() -> Self::Item = || ();
     //~^ ERROR type alias impl trait is not permitted here
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
index 4906ea9c2e2..a9df74689df 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
@@ -8,7 +8,7 @@ LL |     type Item = impl Bug;
    = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: type alias impl trait is not permitted here
-  --> $DIR/issue-60371.rs:14:40
+  --> $DIR/issue-60371.rs:13:40
    |
 LL |     const FUN: fn() -> Self::Item = || ();
    |                                        ^
@@ -25,16 +25,7 @@ LL |     type Item = impl Bug;
    = help: the following implementations were found:
              <&() as Bug>
 
-error[E0277]: the trait bound `(): Bug` is not satisfied
-  --> $DIR/issue-60371.rs:10:17
-   |
-LL |     type Item = impl Bug;
-   |                 ^^^^^^^^ the trait `Bug` is not implemented for `()`
-   |
-   = help: the following implementations were found:
-             <&() as Bug>
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0658.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
new file mode 100644
index 00000000000..4b0f2afee54
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
@@ -0,0 +1,19 @@
+#![feature(member_constraints)]
+#![feature(type_alias_impl_trait)]
+//~^ WARN incomplete
+
+pub trait A {
+    type B;
+    fn f(&self) -> Self::B;
+}
+impl<'a, 'b> A for () {
+    //~^ ERROR the lifetime parameter `'a` is not constrained
+    //~| ERROR the lifetime parameter `'b` is not constrained
+    type B = impl core::fmt::Debug;
+    //~^ ERROR is unstable
+
+
+    fn f(&self) -> Self::B {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
new file mode 100644
index 00000000000..4506a6e23d5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
@@ -0,0 +1,34 @@
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/issue-74761-2.rs:12:14
+   |
+LL |     type B = impl core::fmt::Debug;
+   |              ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
+
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-74761-2.rs:2:12
+   |
+LL | #![feature(type_alias_impl_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-74761-2.rs:9:6
+   |
+LL | impl<'a, 'b> A for () {
+   |      ^^ unconstrained lifetime parameter
+
+error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/issue-74761-2.rs:9:10
+   |
+LL | impl<'a, 'b> A for () {
+   |          ^^ unconstrained lifetime parameter
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0207, E0658.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
index 38aa18fe40e..11756017ad8 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
@@ -5,9 +5,9 @@
 #![feature(min_type_alias_impl_trait)]
 
 type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
-//~^ ERROR could not find defining uses
 
 fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+    //~^ ERROR concrete type differs from previous defining opaque type
     (a.clone(), a)
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
index c00973c0761..52b0462de98 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
@@ -1,8 +1,14 @@
-error: could not find defining uses
-  --> $DIR/multiple-def-uses-in-one-fn2.rs:7:52
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
    |
-LL | type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
-   |                                                    ^^^^^^^^^^^^^
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B`
+   |
+note: previous use here
+  --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
+   |
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
index 17e90005811..5f25365666c 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
@@ -11,6 +11,7 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>)
 }
 
 fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+    //~^ ERROR concrete type differs from previous defining opaque type
     (a, b)
     //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
index bbe709dccab..3d943b77af5 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
@@ -1,10 +1,11 @@
 error[E0308]: mismatched types
-  --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9
    |
 LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
    |      -                    - found type parameter
    |      |
    |      expected type parameter
+LL |
 LL |     (a, b)
    |         ^ expected type parameter `A`, found type parameter `B`
    |
@@ -13,6 +14,18 @@ LL |     (a, b)
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
-error: aborting due to previous error
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1
+   |
+LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]`
+   |
+note: previous use here
+  --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1
+   |
+LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/wf/wf-in-fn-type-arg.stderr b/src/test/ui/wf/wf-in-fn-type-arg.stderr
index 33300b39642..20aa9770710 100644
--- a/src/test/ui/wf/wf-in-fn-type-arg.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-arg.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/wf-in-fn-type-arg.rs:9:8
+  --> $DIR/wf-in-fn-type-arg.rs:9:11
    |
 LL | struct MustBeCopy<T:Copy> {
    |                     ---- required by this bound in `MustBeCopy`
 ...
 LL |     x: fn(MustBeCopy<T>)
-   |        ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+   |           ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
diff --git a/src/test/ui/wf/wf-in-fn-type-ret.stderr b/src/test/ui/wf/wf-in-fn-type-ret.stderr
index 1ffc47e6d82..48af696c3a7 100644
--- a/src/test/ui/wf/wf-in-fn-type-ret.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-ret.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/wf-in-fn-type-ret.rs:9:8
+  --> $DIR/wf-in-fn-type-ret.rs:9:16
    |
 LL | struct MustBeCopy<T:Copy> {
    |                     ---- required by this bound in `MustBeCopy`
 ...
 LL |     x: fn() -> MustBeCopy<T>
-   |        ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+   |                ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
diff --git a/src/test/ui/wf/wf-in-obj-type-trait.stderr b/src/test/ui/wf/wf-in-obj-type-trait.stderr
index 8606eabf59c..b3b919a569e 100644
--- a/src/test/ui/wf/wf-in-obj-type-trait.stderr
+++ b/src/test/ui/wf/wf-in-obj-type-trait.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/wf-in-obj-type-trait.rs:11:8
+  --> $DIR/wf-in-obj-type-trait.rs:11:19
    |
 LL | struct MustBeCopy<T:Copy> {
    |                     ---- required by this bound in `MustBeCopy`
 ...
 LL |     x: dyn Object<MustBeCopy<T>>
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+   |                   ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr
index b59dbb3e76c..c734051ccf3 100644
--- a/src/tools/clippy/tests/ui/future_not_send.stderr
+++ b/src/tools/clippy/tests/ui/future_not_send.stderr
@@ -55,11 +55,11 @@ note: captured value is not `Send`
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                          ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
-note: captured value is not `Send`
+note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
   --> $DIR/future_not_send.rs:20:40
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
-   |                                        ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`
+   |                                        ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
    = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
diff --git a/src/tools/rls b/src/tools/rls
-Subproject 517e9d62c095a04fa497d6b6d3c63b31696a88b
+Subproject a82a0527057eab59c24a0452add35ccb39584e8
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 26d6081c881..869245d5b95 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -17,12 +17,16 @@ path = "lib.rs"
 [target.'cfg(windows)'.dependencies.winapi]
 version = "0.3"
 features = [
-  "aclapi",
   "accctrl",
+  "aclapi",
   "basetsd",
+  "cfg",
   "consoleapi",
   "errhandlingapi",
+  "evntrace",
   "fibersapi",
+  "in6addr",
+  "inaddr",
   "ioapiset",
   "jobapi",
   "jobapi2",
@@ -32,6 +36,8 @@ features = [
   "memoryapi",
   "minschannel",
   "minwinbase",
+  "mstcpip",
+  "mswsock",
   "namedpipeapi",
   "ntdef",
   "ntsecapi",
@@ -54,6 +60,8 @@ features = [
   "winbase",
   "wincon",
   "wincrypt",
+  "windef",
+  "winioctl",
   "winsock2",
   "ws2def",
   "ws2ipdef",
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 799d685ce5c..32660ae2aee 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -28,18 +28,16 @@ const LICENSES: &[&str] = &[
 const EXCEPTIONS: &[(&str, &str)] = &[
     ("mdbook", "MPL-2.0"),                                  // mdbook
     ("openssl", "Apache-2.0"),                              // cargo, mdbook
-    ("fuchsia-zircon-sys", "BSD-3-Clause"),                 // rustdoc, rustc, cargo
-    ("fuchsia-zircon", "BSD-3-Clause"), // rustdoc, rustc, cargo (jobserver & tempdir)
-    ("colored", "MPL-2.0"),             // rustfmt
-    ("ordslice", "Apache-2.0"),         // rls
-    ("ryu", "Apache-2.0 OR BSL-1.0"),   // rls/cargo/... (because of serde)
-    ("bytesize", "Apache-2.0"),         // cargo
-    ("im-rc", "MPL-2.0+"),              // cargo
-    ("sized-chunks", "MPL-2.0+"),       // cargo via im-rc
-    ("bitmaps", "MPL-2.0+"),            // cargo via im-rc
+    ("colored", "MPL-2.0"),                                 // rustfmt
+    ("ordslice", "Apache-2.0"),                             // rls
+    ("ryu", "Apache-2.0 OR BSL-1.0"),                       // rls/cargo/... (because of serde)
+    ("bytesize", "Apache-2.0"),                             // cargo
+    ("im-rc", "MPL-2.0+"),                                  // cargo
+    ("sized-chunks", "MPL-2.0+"),                           // cargo via im-rc
+    ("bitmaps", "MPL-2.0+"),                                // cargo via im-rc
     ("crossbeam-queue", "MIT/Apache-2.0 AND BSD-2-Clause"), // rls via rayon
-    ("instant", "BSD-3-Clause"),        // rustc_driver/tracing-subscriber/parking_lot
-    ("snap", "BSD-3-Clause"),           // rustc
+    ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
+    ("snap", "BSD-3-Clause"),    // rustc
     // FIXME: this dependency violates the documentation comment above:
     ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target
 ];
@@ -115,8 +113,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
     "fixedbitset",
     "flate2",
     "fortanix-sgx-abi",
-    "fuchsia-zircon",
-    "fuchsia-zircon-sys",
     "generic-array",
     "getopts",
     "getrandom",
@@ -130,7 +126,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
     "itertools",
     "itoa",
     "jobserver",
-    "kernel32-sys",
     "lazy_static",
     "libc",
     "libz-sys",
@@ -222,7 +217,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
     "version_check",
     "wasi",
     "winapi",
-    "winapi-build",
     "winapi-i686-pc-windows-gnu",
     "winapi-util",
     "winapi-x86_64-pc-windows-gnu",
diff --git a/src/version b/src/version
index 094d6ad00ce..3ebf789f5a8 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.55.0
+1.56.0