From 4512f211ae77306b0cd0686a7871d56edbf36d30 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Tue, 31 Oct 2023 13:58:03 +0000
Subject: [PATCH] Accept less invalid Rust in rustdoc

---
 library/core/src/primitive_docs.rs            |  20 --
 src/librustdoc/core.rs                        |   6 +-
 tests/rustdoc-gui/src/lib2/lib.rs             |   9 +-
 tests/rustdoc-json/enums/field_hidden.rs      |   5 +-
 tests/rustdoc-json/enums/kind.rs              |   5 +-
 .../rustdoc-json/enums/tuple_fields_hidden.rs |   5 +-
 .../generic-associated-types/gats.rs          |   5 +-
 tests/rustdoc-json/impls/auto.rs              |   9 +-
 .../type/inherent_associated_type_bound.rs    |   2 +-
 .../infinite-recursive-type-2.rs              |   3 +-
 .../infinite-recursive-type-2.stderr          |  17 ++
 .../infinite-recursive-type.rs                |   3 +-
 .../infinite-recursive-type.stderr            |  17 ++
 .../invalid_const_in_lifetime_position.rs     |   5 +
 .../invalid_const_in_lifetime_position.stderr |  84 ++++++-
 tests/rustdoc-ui/issues/issue-105742.rs       |   8 +
 tests/rustdoc-ui/issues/issue-105742.stderr   | 234 ++++++++++++++----
 .../not-wf-ambiguous-normalization.rs         |   1 +
 .../not-wf-ambiguous-normalization.stderr     |   9 +
 tests/rustdoc-ui/recursive-deref-ice.rs       |   5 +-
 tests/rustdoc-ui/unable-fulfill-trait.rs      |   3 +-
 tests/rustdoc-ui/unable-fulfill-trait.stderr  |  23 +-
 tests/rustdoc/const-generics/const-impl.rs    |   4 +-
 .../decl-trailing-whitespace.declaration.html |  14 +-
 tests/rustdoc/decl-trailing-whitespace.rs     |   8 +-
 ...ide-complex-unevaluated-const-arguments.rs |  11 +-
 .../intra-doc/prim-associated-traits.rs       |   2 +-
 ...oc-notable_trait_box_is_not_an_iterator.rs |  11 +-
 .../whitespace-after-where-clause.enum.html   |   2 +-
 .../whitespace-after-where-clause.enum2.html  |   2 +-
 .../rustdoc/whitespace-after-where-clause.rs  |  15 +-
 .../whitespace-after-where-clause.struct.html |   2 +-
 ...whitespace-after-where-clause.struct2.html |   2 +-
 .../whitespace-after-where-clause.union.html  |   2 +-
 .../whitespace-after-where-clause.union2.html |   2 +-
 35 files changed, 428 insertions(+), 127 deletions(-)
 create mode 100644 tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr
 create mode 100644 tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr
 rename tests/{rustdoc => rustdoc-ui}/not-wf-ambiguous-normalization.rs (92%)
 create mode 100644 tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr

diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 380a21b376bde..f3695d16d7a6b 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1077,26 +1077,6 @@ mod prim_tuple {}
 #[doc(hidden)]
 impl<T> (T,) {}
 
-// Fake impl that's only really used for docs.
-#[cfg(doc)]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(fake_variadic)]
-/// This trait is implemented on arbitrary-length tuples.
-impl<T: Clone> Clone for (T,) {
-    fn clone(&self) -> Self {
-        loop {}
-    }
-}
-
-// Fake impl that's only really used for docs.
-#[cfg(doc)]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(fake_variadic)]
-/// This trait is implemented on arbitrary-length tuples.
-impl<T: Copy> Copy for (T,) {
-    // empty
-}
-
 #[rustc_doc_primitive = "f32"]
 /// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
 ///
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 17b117de5d471..6d9f8b820c485 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -319,10 +319,14 @@ pub(crate) fn run_global_ctxt(
         tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
     });
 
-    // NOTE: This is copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
+    // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
+    let _ = tcx.sess.time("wf_checking", || {
+        tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
+    });
     tcx.sess.time("item_types_checking", || {
         tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
     });
+
     tcx.sess.abort_if_errors();
     tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx));
     tcx.sess.time("check_mod_attrs", || {
diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs
index 34e67d9d25438..a2a3c31878ba5 100644
--- a/tests/rustdoc-gui/src/lib2/lib.rs
+++ b/tests/rustdoc-gui/src/lib2/lib.rs
@@ -147,13 +147,13 @@ pub struct LongItemInfo2;
 #[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
 impl SimpleTrait for LongItemInfo2 {}
 
-pub struct WhereWhitespace<T>;
+pub struct WhereWhitespace<T>(T);
 
 impl<T> WhereWhitespace<T> {
     pub fn new<F>(f: F) -> Self
     where
         F: FnMut() -> i32,
-    {}
+    {todo!()}
 }
 
 impl<K, T> Whitespace<&K> for WhereWhitespace<T>
@@ -187,6 +187,11 @@ impl ItemInfoAlignmentTest {
 pub mod scroll_traits {
     use std::iter::*;
 
+    struct Intersperse<T>(T);
+    struct IntersperseWith<T, U>(T, U);
+    struct Flatten<T>(T);
+    struct Peekable<T>(T);
+
     /// Shamelessly (partially) copied from `std::iter::Iterator`.
     /// It allows us to check that the scroll is working as expected on "hidden" items.
     pub trait Iterator {
diff --git a/tests/rustdoc-json/enums/field_hidden.rs b/tests/rustdoc-json/enums/field_hidden.rs
index 5c0d0ffd3dfbe..f240985805790 100644
--- a/tests/rustdoc-json/enums/field_hidden.rs
+++ b/tests/rustdoc-json/enums/field_hidden.rs
@@ -1,7 +1,10 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/100529>.
 
 #![no_core]
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
 
 // @has "$.index[*][?(@.name=='ParseError')]"
 // @has "$.index[*][?(@.name=='UnexpectedEndTag')]"
diff --git a/tests/rustdoc-json/enums/kind.rs b/tests/rustdoc-json/enums/kind.rs
index e283c07400655..777161c4e4ba2 100644
--- a/tests/rustdoc-json/enums/kind.rs
+++ b/tests/rustdoc-json/enums/kind.rs
@@ -1,8 +1,11 @@
 // ignore-tidy-linelength
 
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![no_core]
 
+#[lang = "sized"]
+trait Sized {}
+
 pub enum Foo {
     // @set Unit = "$.index[*][?(@.name=='Unit')].id"
     // @is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"'
diff --git a/tests/rustdoc-json/enums/tuple_fields_hidden.rs b/tests/rustdoc-json/enums/tuple_fields_hidden.rs
index 3aeb0356420a4..34a4f4aec5384 100644
--- a/tests/rustdoc-json/enums/tuple_fields_hidden.rs
+++ b/tests/rustdoc-json/enums/tuple_fields_hidden.rs
@@ -1,6 +1,9 @@
-#![feature(no_core)]
+#![feature(no_core, lang_items)]
 #![no_core]
 
+#[lang = "sized"]
+trait Sized {}
+
 // @set 1.1.0 = "$.index[*][?(@.docs=='1.1.0')].id"
 // @set 2.1.0 = "$.index[*][?(@.docs=='2.1.0')].id"
 // @set 2.1.1 = "$.index[*][?(@.docs=='2.1.1')].id"
diff --git a/tests/rustdoc-json/generic-associated-types/gats.rs b/tests/rustdoc-json/generic-associated-types/gats.rs
index 99c57ff654093..9cfe649243f82 100644
--- a/tests/rustdoc-json/generic-associated-types/gats.rs
+++ b/tests/rustdoc-json/generic-associated-types/gats.rs
@@ -1,11 +1,14 @@
 // ignore-tidy-linelength
 
 #![no_core]
-#![feature(lang_items, no_core)]
+#![feature(lang_items, no_core, arbitrary_self_types)]
 
 #[lang = "sized"]
 pub trait Sized {}
 
+#[lang = "receiver"]
+pub trait Receiver {}
+
 pub trait Display {}
 
 pub trait LendingIterator {
diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs
index ace37e5b3dfe3..96c3ab08b9964 100644
--- a/tests/rustdoc-json/impls/auto.rs
+++ b/tests/rustdoc-json/impls/auto.rs
@@ -1,9 +1,12 @@
-#![feature(no_core, auto_traits, lang_items)]
+#![feature(no_core, auto_traits, lang_items, arbitrary_self_types)]
 #![no_core]
 
 #[lang = "sized"]
 trait Sized {}
 
+#[lang = "receiver"]
+pub trait Receiver {}
+
 pub auto trait Bar {}
 
 /// has span
@@ -12,8 +15,8 @@ impl Foo {
 }
 
 // Testing spans, so all tests below code
-// @is "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
-// @is "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
+// @is "$.index[*][?(@.docs=='has span')].span.begin" "[13, 0]"
+// @is "$.index[*][?(@.docs=='has span')].span.end" "[15, 1]"
 // FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91
 // is "$.index[*][?(@.inner.impl.synthetic==true)].span" null
 pub struct Foo;
diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
index 8e39f471824c7..6da23c8fb4e7d 100644
--- a/tests/rustdoc-json/type/inherent_associated_type_bound.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
@@ -16,5 +16,5 @@ pub struct Carrier<'a>(&'a ());
 pub fn user(_: for<'b> fn(Carrier<'b>::Focus<i32>)) {}
 
 impl<'a> Carrier<'a> {
-    pub type Focus<T> = &'a mut T;
+    pub type Focus<T> = &'a mut T where T: 'a;
 }
diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs
index e49fe07981379..7151ebd599f6d 100644
--- a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs
+++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs
@@ -1,7 +1,6 @@
-// check-pass
-
 pub fn f() -> impl Sized {
     pub enum E {
+        //~^ ERROR: recursive type
         V(E),
     }
 
diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr
new file mode 100644
index 0000000000000..edb5dfd4d55e2
--- /dev/null
+++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr
@@ -0,0 +1,17 @@
+error[E0072]: recursive type `f::E` has infinite size
+  --> $DIR/infinite-recursive-type-2.rs:2:5
+   |
+LL |     pub enum E {
+   |     ^^^^^^^^^^
+LL |
+LL |         V(E),
+   |           - recursive without indirection
+   |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+   |
+LL |         V(Box<E>),
+   |           ++++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0072`.
diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs
index 096130d776828..1f85505172938 100644
--- a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs
+++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs
@@ -1,7 +1,6 @@
-// check-pass
-
 fn f() -> impl Sized {
     enum E {
+        //~^ ERROR: recursive type
         V(E),
     }
 
diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr
new file mode 100644
index 0000000000000..349a569414cc1
--- /dev/null
+++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr
@@ -0,0 +1,17 @@
+error[E0072]: recursive type `f::E` has infinite size
+  --> $DIR/infinite-recursive-type.rs:2:5
+   |
+LL |     enum E {
+   |     ^^^^^^
+LL |
+LL |         V(E),
+   |           - recursive without indirection
+   |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+   |
+LL |         V(Box<E>),
+   |           ++++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0072`.
diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs
index c3f4fd63bac70..07fc239a8f86b 100644
--- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs
+++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs
@@ -4,3 +4,8 @@ trait X {
 fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
 //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
 //~| ERROR associated type takes 0 generic arguments but 1 generic argument
+//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
+//~| ERROR associated type takes 0 generic arguments but 1 generic argument
+//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
+//~| ERROR associated type takes 0 generic arguments but 1 generic argument
+//~| ERROR trait `X` cannot be made into an object
diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
index 527729a822862..50d55284754e5 100644
--- a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
+++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
@@ -28,6 +28,86 @@ note: associated type defined here, with 0 generic parameters
 LL |     type Y<'a>;
    |          ^
 
-error: aborting due to 2 previous errors
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+  --> $DIR/invalid_const_in_lifetime_position.rs:4:26
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+   |                          ^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/invalid_const_in_lifetime_position.rs:2:10
+   |
+LL |     type Y<'a>;
+   |          ^ --
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing lifetime argument
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
+   |                            +++
+
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/invalid_const_in_lifetime_position.rs:4:26
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+   |                          ^--- help: remove these generics
+   |                          |
+   |                          expected 0 generic arguments
+   |
+note: associated type defined here, with 0 generic parameters
+  --> $DIR/invalid_const_in_lifetime_position.rs:2:10
+   |
+LL |     type Y<'a>;
+   |          ^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+  --> $DIR/invalid_const_in_lifetime_position.rs:4:26
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+   |                          ^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/invalid_const_in_lifetime_position.rs:2:10
+   |
+LL |     type Y<'a>;
+   |          ^ --
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing lifetime argument
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
+   |                            +++
+
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/invalid_const_in_lifetime_position.rs:4:26
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+   |                          ^--- help: remove these generics
+   |                          |
+   |                          expected 0 generic arguments
+   |
+note: associated type defined here, with 0 generic parameters
+  --> $DIR/invalid_const_in_lifetime_position.rs:2:10
+   |
+LL |     type Y<'a>;
+   |          ^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0038]: the trait `X` cannot be made into an object
+  --> $DIR/invalid_const_in_lifetime_position.rs:4:20
+   |
+LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+   |                    ^^^^^^^^^^^^^^^^^^^^ `X` 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/invalid_const_in_lifetime_position.rs:2:10
+   |
+LL | trait X {
+   |       - this trait cannot be made into an object...
+LL |     type Y<'a>;
+   |          ^ ...because it contains the generic associated type `Y`
+   = help: consider moving `Y` to another trait
+
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0038, E0107.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/rustdoc-ui/issues/issue-105742.rs b/tests/rustdoc-ui/issues/issue-105742.rs
index 1fbb70c7808ee..5e493515cad5b 100644
--- a/tests/rustdoc-ui/issues/issue-105742.rs
+++ b/tests/rustdoc-ui/issues/issue-105742.rs
@@ -21,6 +21,8 @@ pub trait SVec: Index<
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
     Output = <Index<<Self as SVec>::Item,
     //~^ expected 1 lifetime argument
     //~| expected 1 generic argument
@@ -30,6 +32,8 @@ pub trait SVec: Index<
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
     Output = <Self as SVec>::Item> as SVec>::Item,
     //~^ expected 1 lifetime argument
     //~| expected 1 generic argument
@@ -47,6 +51,10 @@ pub trait SVec: Index<
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
     //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
+    //~| missing generics for associated type `SVec::Item`
 > {
     type Item<'a, T>;
 
diff --git a/tests/rustdoc-ui/issues/issue-105742.stderr b/tests/rustdoc-ui/issues/issue-105742.stderr
index 4d3f9f5bced77..ad1020a1f0817 100644
--- a/tests/rustdoc-ui/issues/issue-105742.stderr
+++ b/tests/rustdoc-ui/issues/issue-105742.stderr
@@ -5,7 +5,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -21,7 +21,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -31,13 +31,13 @@ LL |     <Self as SVec>::Item<T>,
    |                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:24:37
+  --> $DIR/issue-105742.rs:26:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -47,13 +47,13 @@ LL |     Output = <Index<<Self as SVec>::Item<'a>,
    |                                         ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:24:37
+  --> $DIR/issue-105742.rs:26:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -63,13 +63,13 @@ LL |     Output = <Index<<Self as SVec>::Item<T>,
    |                                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:30
+  --> $DIR/issue-105742.rs:37:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -79,13 +79,13 @@ LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
    |                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:30
+  --> $DIR/issue-105742.rs:37:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -95,13 +95,13 @@ LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
    |                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:46
+  --> $DIR/issue-105742.rs:37:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -111,13 +111,13 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
    |                                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:46
+  --> $DIR/issue-105742.rs:37:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -133,7 +133,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
    |                                        ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -149,7 +149,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
    |                                        ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -165,7 +165,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -182,7 +182,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -193,13 +193,13 @@ LL |     <Self as SVec>::Item<T>,
    |                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:24:37
+  --> $DIR/issue-105742.rs:26:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -210,13 +210,13 @@ LL |     Output = <Index<<Self as SVec>::Item<'a>,
    |                                         ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:24:37
+  --> $DIR/issue-105742.rs:26:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -227,13 +227,13 @@ LL |     Output = <Index<<Self as SVec>::Item<T>,
    |                                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:30
+  --> $DIR/issue-105742.rs:37:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -244,13 +244,13 @@ LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
    |                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:30
+  --> $DIR/issue-105742.rs:37:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -261,13 +261,13 @@ LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
    |                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:46
+  --> $DIR/issue-105742.rs:37:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -278,13 +278,13 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
    |                                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:46
+  --> $DIR/issue-105742.rs:37:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -331,7 +331,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -348,7 +348,7 @@ LL |     <Self as SVec>::Item,
    |                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -359,13 +359,13 @@ LL |     <Self as SVec>::Item<T>,
    |                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:24:37
+  --> $DIR/issue-105742.rs:26:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -376,13 +376,13 @@ LL |     Output = <Index<<Self as SVec>::Item<'a>,
    |                                         ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:24:37
+  --> $DIR/issue-105742.rs:26:37
    |
 LL |     Output = <Index<<Self as SVec>::Item,
    |                                     ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -393,13 +393,13 @@ LL |     Output = <Index<<Self as SVec>::Item<T>,
    |                                         +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:30
+  --> $DIR/issue-105742.rs:37:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -410,13 +410,13 @@ LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
    |                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:30
+  --> $DIR/issue-105742.rs:37:30
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -427,13 +427,13 @@ LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
    |                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:46
+  --> $DIR/issue-105742.rs:37:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -444,13 +444,13 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
    |                                                  ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:33:46
+  --> $DIR/issue-105742.rs:37:46
    |
 LL |     Output = <Self as SVec>::Item> as SVec>::Item,
    |                                              ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -461,13 +461,13 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<T>,
    |                                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:53:38
+  --> $DIR/issue-105742.rs:61:38
    |
 LL |     fn len(&self) -> <Self as SVec>::Item;
    |                                      ^^^^ expected 1 lifetime argument
    |
 note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^ --
@@ -477,13 +477,13 @@ LL |     fn len(&self) -> <Self as SVec>::Item<'_>;
    |                                          ++++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:53:38
+  --> $DIR/issue-105742.rs:61:38
    |
 LL |     fn len(&self) -> <Self as SVec>::Item;
    |                                      ^^^^ expected 1 generic argument
    |
 note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:51:10
+  --> $DIR/issue-105742.rs:59:10
    |
 LL |     type Item<'a, T>;
    |          ^^^^     -
@@ -492,7 +492,143 @@ help: add missing generic argument
 LL |     fn len(&self) -> <Self as SVec>::Item<T>;
    |                                          +++
 
-error: aborting due to 29 previous errors
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:15:21
+   |
+LL |     <Self as SVec>::Item,
+   |                     ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing lifetime argument
+   |
+LL |     <Self as SVec>::Item<'a>,
+   |                         ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:15:21
+   |
+LL |     <Self as SVec>::Item,
+   |                     ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing generic argument
+   |
+LL |     <Self as SVec>::Item<T>,
+   |                         +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:26:37
+   |
+LL |     Output = <Index<<Self as SVec>::Item,
+   |                                     ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing lifetime argument
+   |
+LL |     Output = <Index<<Self as SVec>::Item<'a>,
+   |                                         ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:26:37
+   |
+LL |     Output = <Index<<Self as SVec>::Item,
+   |                                     ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing generic argument
+   |
+LL |     Output = <Index<<Self as SVec>::Item<T>,
+   |                                         +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:37:30
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                              ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing lifetime argument
+   |
+LL |     Output = <Self as SVec>::Item<'a>> as SVec>::Item,
+   |                                  ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:37:30
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                              ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing generic argument
+   |
+LL |     Output = <Self as SVec>::Item<T>> as SVec>::Item,
+   |                                  +++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:37:46
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                                              ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing lifetime argument
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item<'a>,
+   |                                                  ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:37:46
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item,
+   |                                              ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add missing generic argument
+   |
+LL |     Output = <Self as SVec>::Item> as SVec>::Item<T>,
+   |                                                  +++
+
+error: aborting due to 37 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/rustdoc/not-wf-ambiguous-normalization.rs b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs
similarity index 92%
rename from tests/rustdoc/not-wf-ambiguous-normalization.rs
rename to tests/rustdoc-ui/not-wf-ambiguous-normalization.rs
index 1e9f925f8458d..3e4825d83b1fe 100644
--- a/tests/rustdoc/not-wf-ambiguous-normalization.rs
+++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs
@@ -12,6 +12,7 @@ struct DefaultAllocator;
 // `<DefaultAllocator as Allocator>::Buffer` to be ambiguous,
 // which caused an ICE with `-Znormalize-docs`.
 impl<T> Allocator for DefaultAllocator {
+    //~^ ERROR: type annotations needed
     type Buffer = ();
 }
 
diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr
new file mode 100644
index 0000000000000..34b20a0b32ce1
--- /dev/null
+++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/not-wf-ambiguous-normalization.rs:14:23
+   |
+LL | impl<T> Allocator for DefaultAllocator {
+   |                       ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/rustdoc-ui/recursive-deref-ice.rs b/tests/rustdoc-ui/recursive-deref-ice.rs
index c44fd27f40305..9e62841f99beb 100644
--- a/tests/rustdoc-ui/recursive-deref-ice.rs
+++ b/tests/rustdoc-ui/recursive-deref-ice.rs
@@ -4,7 +4,10 @@
 
 pub struct Attribute;
 
-pub struct Map<'hir> {}
+pub struct Map<'hir> {
+    lt: &'hir (),
+}
+
 impl<'hir> Map<'hir> {
     pub fn attrs(&self) -> &'hir [Attribute] { &[] }
 }
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs
index 7035708224808..10887ab190302 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.rs
+++ b/tests/rustdoc-ui/unable-fulfill-trait.rs
@@ -3,7 +3,8 @@
 pub struct Foo<'a, 'b, T> {
     field1: dyn Bar<'a, 'b,>,
     //~^ ERROR
-    //~^^ ERROR
+    //~| ERROR
+    //~| ERROR
 }
 
 pub trait Bar<'x, 's, U>
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr
index 72f35cb922445..d7735a4fd1127 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.stderr
+++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr
@@ -5,7 +5,7 @@ LL |     field1: dyn Bar<'a, 'b,>,
    |                 ^^^ expected 1 generic argument
    |
 note: trait defined here, with 1 generic parameter: `U`
-  --> $DIR/unable-fulfill-trait.rs:9:11
+  --> $DIR/unable-fulfill-trait.rs:10:11
    |
 LL | pub trait Bar<'x, 's, U>
    |           ^^^         -
@@ -20,7 +20,24 @@ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
 LL |     field1: dyn Bar<'a, 'b,>,
    |             ^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/unable-fulfill-trait.rs:4:13
+   |
+LL |     field1: dyn Bar<'a, 'b,>,
+   |             ^^^^^^^^^^^^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'b` as defined here
+  --> $DIR/unable-fulfill-trait.rs:3:20
+   |
+LL | pub struct Foo<'a, 'b, T> {
+   |                    ^^
+note: but lifetime parameter must outlive the lifetime `'a` as defined here
+  --> $DIR/unable-fulfill-trait.rs:3:16
+   |
+LL | pub struct Foo<'a, 'b, T> {
+   |                ^^
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0107, E0227.
+Some errors have detailed explanations: E0107, E0227, E0478.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/rustdoc/const-generics/const-impl.rs b/tests/rustdoc/const-generics/const-impl.rs
index b424ea4b33cec..f4eefcc1c33b5 100644
--- a/tests/rustdoc/const-generics/const-impl.rs
+++ b/tests/rustdoc/const-generics/const-impl.rs
@@ -2,7 +2,9 @@
 #![feature(adt_const_params)]
 #![crate_name = "foo"]
 
-#[derive(PartialEq, Eq)]
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
 pub enum Order {
     Sorted,
     Unsorted,
diff --git a/tests/rustdoc/decl-trailing-whitespace.declaration.html b/tests/rustdoc/decl-trailing-whitespace.declaration.html
index d73393633f3b8..59c318c16f3b0 100644
--- a/tests/rustdoc/decl-trailing-whitespace.declaration.html
+++ b/tests/rustdoc/decl-trailing-whitespace.declaration.html
@@ -1,22 +1,16 @@
 <code>pub trait Write {
     // Required methods
     fn <a href="#tymethod.poll_write" class="fn">poll_write</a>(
-        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
+        self,
         cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
         buf: &amp;mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]
     ) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
-<span class="item-spacer" />    fn <a href="#tymethod.poll_flush" class="fn">poll_flush</a>(
-        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
-        cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;
-    ) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
-<span class="item-spacer" />    fn <a href="#tymethod.poll_close" class="fn">poll_close</a>(
-        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
-        cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;
-    ) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+<span class="item-spacer" />    fn <a href="#tymethod.poll_flush" class="fn">poll_flush</a>(self, cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+<span class="item-spacer" />    fn <a href="#tymethod.poll_close" class="fn">poll_close</a>(self, cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
 
     // Provided method
     fn <a href="#method.poll_write_vectored" class="fn">poll_write_vectored</a>(
-        self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
+        self,
         cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
         bufs: &amp;[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]
     ) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt; { ... }
diff --git a/tests/rustdoc/decl-trailing-whitespace.rs b/tests/rustdoc/decl-trailing-whitespace.rs
index d2a12435d8f27..6678377430888 100644
--- a/tests/rustdoc/decl-trailing-whitespace.rs
+++ b/tests/rustdoc/decl-trailing-whitespace.rs
@@ -9,21 +9,21 @@ pub struct Error;
 pub trait Write {
     // @snapshot 'declaration' - '//*[@class="rust item-decl"]//code'
     fn poll_write(
-        self: Option<String>,
+        self,
         cx: &mut Option<String>,
         buf: &mut [usize]
     ) -> Option<Result<usize, Error>>;
     fn poll_flush(
-        self: Option<String>,
+        self,
         cx: &mut Option<String>
     ) -> Option<Result<(), Error>>;
     fn poll_close(
-        self: Option<String>,
+        self,
         cx: &mut Option<String>,
     ) -> Option<Result<(), Error>>;
 
     fn poll_write_vectored(
-        self: Option<String>,
+        self,
         cx: &mut Option<String>,
         bufs: &[usize]
     ) -> Option<Result<usize, Error>> {}
diff --git a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs
index 6006354eba4e5..d728f772a69c6 100644
--- a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs
+++ b/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs
@@ -4,9 +4,11 @@
 //
 // Read the documentation of `rustdoc::clean::utils::print_const_expr`
 // for further details.
-#![feature(const_trait_impl, generic_const_exprs)]
+#![feature(const_trait_impl, generic_const_exprs, adt_const_params, generic_const_items)]
 #![allow(incomplete_features)]
 
+use std::marker::ConstParamTy;
+
 // @has hide_complex_unevaluated_const_arguments/trait.Stage.html
 pub trait Stage {
     // A helper constant that prevents const expressions containing it
@@ -29,11 +31,13 @@ pub trait Stage {
     //
     // @has - '//*[@id="associatedconstant.ARRAY1"]' \
     //        'const ARRAY1: [u8; { _ }]'
-    const ARRAY1: [u8; Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)];
+    const ARRAY1: [u8; Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)]
+        where [(); Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)]:;
 
     // @has - '//*[@id="associatedconstant.VERBOSE"]' \
     //        'const VERBOSE: [u16; { _ }]'
-    const VERBOSE: [u16; compute("thing", 9 + 9) * Self::ABSTRACT];
+    const VERBOSE: [u16; compute("thing", 9 + 9) * Self::ABSTRACT]
+        where [(); compute("thing", 9 + 9) * Self::ABSTRACT]:;
 
     // Check that we do not leak the private struct field contained within
     // the path. The output could definitely be improved upon
@@ -69,6 +73,7 @@ pub trait Sub: Sup<{ 90 * 20 * 4 }, { Struct { private: () } }> {}
 
 pub trait Sup<const N: usize, const S: Struct> {}
 
+#[derive(ConstParamTy, PartialEq, Eq)]
 pub struct Struct { private: () }
 
 impl Struct {
diff --git a/tests/rustdoc/intra-doc/prim-associated-traits.rs b/tests/rustdoc/intra-doc/prim-associated-traits.rs
index 8639a24f7f386..71d7d2189e6f9 100644
--- a/tests/rustdoc/intra-doc/prim-associated-traits.rs
+++ b/tests/rustdoc/intra-doc/prim-associated-traits.rs
@@ -41,6 +41,6 @@ pub struct Number {
     pub u_128: u128,
     pub ch: char,
     pub boolean: bool,
-    pub string: str,
+    pub string: &'static str,
     pub n: !,
 }
diff --git a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs
index 3fb00c7db8411..6b94d79948395 100644
--- a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs
+++ b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs
@@ -3,25 +3,28 @@
 #![feature(no_core)]
 #![no_core]
 #[lang = "owned_box"]
-pub struct Box<T>;
+pub struct Box<T>(*const T);
 
 impl<T> Box<T> {
     pub fn new(x: T) -> Box<T> {
-        Box
+        Box(std::ptr::null())
     }
 }
 
+#[lang = "sized"]
+trait Sized {}
+
 #[doc(notable_trait)]
 pub trait FakeIterator {}
 
 impl<I: FakeIterator> FakeIterator for Box<I> {}
 
 #[lang = "pin"]
-pub struct Pin<T>;
+pub struct Pin<T>(T);
 
 impl<T> Pin<T> {
     pub fn new(x: T) -> Pin<T> {
-        Pin
+        Pin(x)
     }
 }
 
diff --git a/tests/rustdoc/whitespace-after-where-clause.enum.html b/tests/rustdoc/whitespace-after-where-clause.enum.html
index 20b60b68e88cf..ff4971f33cd68 100644
--- a/tests/rustdoc/whitespace-after-where-clause.enum.html
+++ b/tests/rustdoc/whitespace-after-where-clause.enum.html
@@ -1,5 +1,5 @@
 <pre class="rust item-decl"><code>pub enum Cow&lt;'a, B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
+    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
     Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>),
     Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.enum2.html b/tests/rustdoc/whitespace-after-where-clause.enum2.html
index 065ce757de1ab..bfc50f8adcdcb 100644
--- a/tests/rustdoc/whitespace-after-where-clause.enum2.html
+++ b/tests/rustdoc/whitespace-after-where-clause.enum2.html
@@ -1,4 +1,4 @@
-<pre class="rust item-decl"><code>pub enum Cow2&lt;'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + 'a&gt; {
+<pre class="rust item-decl"><code>pub enum Cow2&lt;'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + 'a&gt; {
     Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>),
     Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.rs b/tests/rustdoc/whitespace-after-where-clause.rs
index b540c7c97c1f4..832d3728e7593 100644
--- a/tests/rustdoc/whitespace-after-where-clause.rs
+++ b/tests/rustdoc/whitespace-after-where-clause.rs
@@ -6,7 +6,8 @@
 // @has 'foo/trait.ToOwned.html'
 // @snapshot trait - '//*[@class="rust item-decl"]'
 pub trait ToOwned<T>
-where T: Clone
+where
+    T: Clone,
 {
     type Owned;
     fn to_owned(&self) -> Self::Owned;
@@ -26,7 +27,7 @@ pub trait ToOwned2<T: Clone> {
 // @snapshot enum - '//*[@class="rust item-decl"]'
 pub enum Cow<'a, B: ?Sized + 'a>
 where
-    B: ToOwned<Clone>,
+    B: ToOwned<()>,
 {
     Borrowed(&'a B),
     Whatever(u32),
@@ -35,7 +36,7 @@ where
 // @has 'foo/enum.Cow2.html'
 // @snapshot enum2 - '//*[@class="rust item-decl"]'
 // There should be a whitespace before `{` in this case!
-pub enum Cow2<'a, B: ?Sized + ToOwned<Clone> + 'a> {
+pub enum Cow2<'a, B: ?Sized + ToOwned<()> + 'a> {
     Borrowed(&'a B),
     Whatever(u32),
 }
@@ -44,7 +45,7 @@ pub enum Cow2<'a, B: ?Sized + ToOwned<Clone> + 'a> {
 // @snapshot struct - '//*[@class="rust item-decl"]'
 pub struct Struct<'a, B: ?Sized + 'a>
 where
-    B: ToOwned<Clone>,
+    B: ToOwned<()>,
 {
     pub a: &'a B,
     pub b: u32,
@@ -53,7 +54,7 @@ where
 // @has 'foo/struct.Struct2.html'
 // @snapshot struct2 - '//*[@class="rust item-decl"]'
 // There should be a whitespace before `{` in this case!
-pub struct Struct2<'a, B: ?Sized + ToOwned<Clone> + 'a> {
+pub struct Struct2<'a, B: ?Sized + ToOwned<()> + 'a> {
     pub a: &'a B,
     pub b: u32,
 }
@@ -62,7 +63,7 @@ pub struct Struct2<'a, B: ?Sized + ToOwned<Clone> + 'a> {
 // @snapshot union - '//*[@class="rust item-decl"]'
 pub union Union<'a, B: ?Sized + 'a>
 where
-    B: ToOwned<Clone>,
+    B: ToOwned<()>,
 {
     a: &'a B,
     b: u32,
@@ -71,7 +72,7 @@ where
 // @has 'foo/union.Union2.html'
 // @snapshot union2 - '//*[@class="rust item-decl"]'
 // There should be a whitespace before `{` in this case!
-pub union Union2<'a, B: ?Sized + ToOwned<Clone> + 'a> {
+pub union Union2<'a, B: ?Sized + ToOwned<()> + 'a> {
     a: &'a B,
     b: u32,
 }
diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc/whitespace-after-where-clause.struct.html
index 948ddc499da8a..ca68535863398 100644
--- a/tests/rustdoc/whitespace-after-where-clause.struct.html
+++ b/tests/rustdoc/whitespace-after-where-clause.struct.html
@@ -1,5 +1,5 @@
 <pre class="rust item-decl"><code>pub struct Struct&lt;'a, B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
+    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
     pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>,
     pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.struct2.html b/tests/rustdoc/whitespace-after-where-clause.struct2.html
index c647e8d71218e..5aa8110c18f71 100644
--- a/tests/rustdoc/whitespace-after-where-clause.struct2.html
+++ b/tests/rustdoc/whitespace-after-where-clause.struct2.html
@@ -1,4 +1,4 @@
-<pre class="rust item-decl"><code>pub struct Struct2&lt;'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + 'a&gt; {
+<pre class="rust item-decl"><code>pub struct Struct2&lt;'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + 'a&gt; {
     pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>,
     pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.union.html b/tests/rustdoc/whitespace-after-where-clause.union.html
index 38b6cb8b5c613..40b0c6712842b 100644
--- a/tests/rustdoc/whitespace-after-where-clause.union.html
+++ b/tests/rustdoc/whitespace-after-where-clause.union.html
@@ -1,4 +1,4 @@
 <pre class="rust item-decl"><code>pub union Union&lt;'a, B&gt;<span class="where fmt-newline">where
-    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
+    B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
     /* private fields */
 }</code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.union2.html b/tests/rustdoc/whitespace-after-where-clause.union2.html
index 66ad30c92001f..177a161b83a62 100644
--- a/tests/rustdoc/whitespace-after-where-clause.union2.html
+++ b/tests/rustdoc/whitespace-after-where-clause.union2.html
@@ -1,3 +1,3 @@
-<pre class="rust item-decl"><code>pub union Union2&lt;'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + 'a&gt; {
+<pre class="rust item-decl"><code>pub union Union2&lt;'a, B: ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt; + 'a&gt; {
     /* private fields */
 }</code></pre>
\ No newline at end of file