about summary refs log tree commit diff
path: root/tests/rustdoc/impl
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-05-05 17:01:08 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2025-05-05 17:47:18 +0200
commitb84f4cc39e99f801dcd37125dffa67eb796c85b8 (patch)
tree071def2349dabae166fd66b06ee9346aa825abb9 /tests/rustdoc/impl
parentbe71d8b24f1aebe9c45279d95a76db8fa6a62574 (diff)
downloadrust-b84f4cc39e99f801dcd37125dffa67eb796c85b8.tar.gz
rust-b84f4cc39e99f801dcd37125dffa67eb796c85b8.zip
Created `tests/rustdoc/impl` subfolder to limit number of files at the top level
Diffstat (limited to 'tests/rustdoc/impl')
-rw-r--r--tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs5
-rw-r--r--tests/rustdoc/impl/auxiliary/extern-impl-trait.rs27
-rw-r--r--tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs7
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-100204-aux.rs13
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-17476.rs7
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-21092.rs12
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-22025.rs10
-rw-r--r--tests/rustdoc/impl/auxiliary/issue-53689.rs1
-rw-r--r--tests/rustdoc/impl/auxiliary/precise-capturing.rs7
-rw-r--r--tests/rustdoc/impl/auxiliary/real_gimli.rs13
-rw-r--r--tests/rustdoc/impl/auxiliary/realcore.rs15
-rw-r--r--tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs23
-rw-r--r--tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs3
-rw-r--r--tests/rustdoc/impl/blanket-impl-29503.rs21
-rw-r--r--tests/rustdoc/impl/blanket-impl-78673.rs25
-rw-r--r--tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs35
-rw-r--r--tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs14
-rw-r--r--tests/rustdoc/impl/deduplicate-trait-impl-22025.rs9
-rw-r--r--tests/rustdoc/impl/default-impl.rs9
-rw-r--r--tests/rustdoc/impl/deprecated-impls.rs118
-rw-r--r--tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs13
-rw-r--r--tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs24
-rw-r--r--tests/rustdoc/impl/duplicated_impl.rs14
-rw-r--r--tests/rustdoc/impl/empty-impl-block.rs20
-rw-r--r--tests/rustdoc/impl/empty-impls.rs19
-rw-r--r--tests/rustdoc/impl/extern-impl-trait.rs11
-rw-r--r--tests/rustdoc/impl/extern-impl.rs27
-rw-r--r--tests/rustdoc/impl/foreign-implementors-js-43701.rs6
-rw-r--r--tests/rustdoc/impl/generic-impl.rs16
-rw-r--r--tests/rustdoc/impl/hidden-implementors-90781.rs78
-rw-r--r--tests/rustdoc/impl/hidden-impls.rs17
-rw-r--r--tests/rustdoc/impl/hidden-trait-struct-impls.rs22
-rw-r--r--tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs24
-rw-r--r--tests/rustdoc/impl/impl-alias-substituted.rs9
-rw-r--r--tests/rustdoc/impl/impl-assoc-type-21092.rs11
-rw-r--r--tests/rustdoc/impl/impl-associated-items-order.rs42
-rw-r--r--tests/rustdoc/impl/impl-associated-items-sidebar.rs42
-rw-r--r--tests/rustdoc/impl/impl-blanket-53689.rs17
-rw-r--r--tests/rustdoc/impl/impl-box.rs16
-rw-r--r--tests/rustdoc/impl/impl-disambiguation.rs30
-rw-r--r--tests/rustdoc/impl/impl-everywhere.rs30
-rw-r--r--tests/rustdoc/impl/impl-in-const-block.rs43
-rw-r--r--tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs27
-rw-r--r--tests/rustdoc/impl/impl-parts-crosscrate.rs20
-rw-r--r--tests/rustdoc/impl/impl-parts.rs12
-rw-r--r--tests/rustdoc/impl/impl-ref-20175.rs14
-rw-r--r--tests/rustdoc/impl/impl-trait-43869.rs75
-rw-r--r--tests/rustdoc/impl/impl-trait-alias.rs14
-rw-r--r--tests/rustdoc/impl/impl-trait-precise-capturing.rs26
-rw-r--r--tests/rustdoc/impl/impl-type-parameter-33592.rs14
-rw-r--r--tests/rustdoc/impl/implementor-stable-version.rs21
-rw-r--r--tests/rustdoc/impl/implementors-unstable-75588.rs18
-rw-r--r--tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs15
-rw-r--r--tests/rustdoc/impl/manual_impl.rs77
-rw-r--r--tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs14
-rw-r--r--tests/rustdoc/impl/module-impls.rs5
-rw-r--r--tests/rustdoc/impl/must_implement_one_of.rs10
-rw-r--r--tests/rustdoc/impl/negative-impl-no-items.rs26
-rw-r--r--tests/rustdoc/impl/negative-impl-sidebar.rs9
-rw-r--r--tests/rustdoc/impl/negative-impl.rs14
-rw-r--r--tests/rustdoc/impl/return-impl-trait.rs15
-rw-r--r--tests/rustdoc/impl/rustc-incoherent-impls.rs28
-rw-r--r--tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs36
-rw-r--r--tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs21
-rw-r--r--tests/rustdoc/impl/struct-implementations-title.rs9
-rw-r--r--tests/rustdoc/impl/trait-impl.rs45
-rw-r--r--tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs17
-rw-r--r--tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs17
-rw-r--r--tests/rustdoc/impl/universal-impl-trait.rs55
-rw-r--r--tests/rustdoc/impl/unneeded-trait-implementations-title.rs5
70 files changed, 1564 insertions, 0 deletions
diff --git a/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs
new file mode 100644
index 00000000000..15953122280
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs
@@ -0,0 +1,5 @@
+#[doc(hidden)]
+pub enum HiddenType {}
+
+#[doc(hidden)]
+pub trait HiddenTrait {}
diff --git a/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs b/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs
new file mode 100644
index 00000000000..dbd54393098
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs
@@ -0,0 +1,27 @@
+pub trait Foo {
+    type Associated;
+}
+
+pub struct X;
+pub struct Y;
+
+
+impl Foo for X {
+    type Associated = ();
+}
+
+impl Foo for Y {
+    type Associated = ();
+}
+
+impl X {
+    pub fn returns_sized<'a>(&'a self) -> impl Foo<Associated=()> + 'a {
+        X
+    }
+}
+
+impl Y {
+    pub fn returns_unsized<'a>(&'a self) -> Box<impl ?Sized + Foo<Associated=()> + 'a> {
+        Box::new(X)
+    }
+}
diff --git a/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs b/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs
new file mode 100644
index 00000000000..fc51e42e500
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_has_incoherent_inherent_impls]
+pub trait FooTrait {}
+
+#[rustc_has_incoherent_inherent_impls]
+pub struct FooStruct;
diff --git a/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs b/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs
new file mode 100644
index 00000000000..df1b59069be
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs
@@ -0,0 +1,13 @@
+#![crate_name="first"]
+
+pub mod prelude {
+    pub use crate::Bot;
+}
+
+pub struct Bot;
+
+impl Bot {
+    pub fn new() -> Bot {
+        Bot
+    }
+}
diff --git a/tests/rustdoc/impl/auxiliary/issue-17476.rs b/tests/rustdoc/impl/auxiliary/issue-17476.rs
new file mode 100644
index 00000000000..0a63b893fff
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/issue-17476.rs
@@ -0,0 +1,7 @@
+//@ compile-flags: -Cmetadata=aux
+
+#![doc(html_root_url = "http://example.com")]
+
+pub trait Foo {
+    fn foo(&self) {}
+}
diff --git a/tests/rustdoc/impl/auxiliary/issue-21092.rs b/tests/rustdoc/impl/auxiliary/issue-21092.rs
new file mode 100644
index 00000000000..49522e0d4b5
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/issue-21092.rs
@@ -0,0 +1,12 @@
+//@ compile-flags: -Cmetadata=aux
+
+pub trait Foo {
+    type Bar;
+    fn foo(&self) {}
+}
+
+pub struct Bar;
+
+impl Foo for Bar {
+    type Bar = i32;
+}
diff --git a/tests/rustdoc/impl/auxiliary/issue-22025.rs b/tests/rustdoc/impl/auxiliary/issue-22025.rs
new file mode 100644
index 00000000000..6bc55073283
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/issue-22025.rs
@@ -0,0 +1,10 @@
+//@ compile-flags: -Cmetadata=aux
+
+pub mod foo {
+
+    pub trait Foo {}
+    pub struct Bar;
+
+    impl Foo for Bar {}
+
+}
diff --git a/tests/rustdoc/impl/auxiliary/issue-53689.rs b/tests/rustdoc/impl/auxiliary/issue-53689.rs
new file mode 100644
index 00000000000..5003c2c00f4
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/issue-53689.rs
@@ -0,0 +1 @@
+pub struct MyStruct;
diff --git a/tests/rustdoc/impl/auxiliary/precise-capturing.rs b/tests/rustdoc/impl/auxiliary/precise-capturing.rs
new file mode 100644
index 00000000000..531d4dfdccc
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/precise-capturing.rs
@@ -0,0 +1,7 @@
+#![feature(precise_capturing)]
+
+pub fn cross_crate_empty() -> impl Sized + use<> {}
+
+pub fn cross_crate_missing() -> impl Sized {}
+
+pub fn cross_crate_args<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
diff --git a/tests/rustdoc/impl/auxiliary/real_gimli.rs b/tests/rustdoc/impl/auxiliary/real_gimli.rs
new file mode 100644
index 00000000000..871d9b31be9
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/real_gimli.rs
@@ -0,0 +1,13 @@
+//@ aux-build:realcore.rs
+
+#![crate_name = "real_gimli"]
+#![feature(staged_api, extremely_unstable)]
+#![unstable(feature = "rustc_private", issue = "none")]
+
+extern crate realcore;
+
+#[unstable(feature = "rustc_private", issue = "none")]
+pub struct EndianSlice;
+
+#[unstable(feature = "rustc_private", issue = "none")]
+impl realcore::Deref for EndianSlice {}
diff --git a/tests/rustdoc/impl/auxiliary/realcore.rs b/tests/rustdoc/impl/auxiliary/realcore.rs
new file mode 100644
index 00000000000..e0a906df002
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/realcore.rs
@@ -0,0 +1,15 @@
+#![crate_name = "realcore"]
+#![feature(staged_api)]
+#![unstable(feature = "extremely_unstable", issue = "none")]
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+pub struct Foo {}
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+pub trait Join {}
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+impl Join for Foo {}
+
+#[stable(feature = "faked_deref", since = "1.47.0")]
+pub trait Deref {}
diff --git a/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs b/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs
new file mode 100644
index 00000000000..032db3b25e6
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs
@@ -0,0 +1,23 @@
+#![feature(auto_traits)]
+
+pub mod bar {
+    use std::marker;
+
+    pub auto trait Bar {}
+
+    pub trait Foo {
+        fn foo(&self) {}
+    }
+
+    impl Foo {
+        pub fn test<T: Bar>(&self) {}
+    }
+
+    pub struct TypeId;
+
+    impl TypeId {
+        pub fn of<T: Bar + ?Sized>() -> TypeId {
+            panic!()
+        }
+    }
+}
diff --git a/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs b/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs
new file mode 100644
index 00000000000..135987fc00d
--- /dev/null
+++ b/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs
@@ -0,0 +1,3 @@
+#![feature(auto_traits)]
+
+pub auto trait AnAutoTrait {}
diff --git a/tests/rustdoc/impl/blanket-impl-29503.rs b/tests/rustdoc/impl/blanket-impl-29503.rs
new file mode 100644
index 00000000000..f43fe79ca58
--- /dev/null
+++ b/tests/rustdoc/impl/blanket-impl-29503.rs
@@ -0,0 +1,21 @@
+// https://github.com/rust-lang/rust/issues/29503
+#![crate_name="issue_29503"]
+
+use std::fmt;
+
+//@ has issue_29503/trait.MyTrait.html
+pub trait MyTrait {
+    fn my_string(&self) -> String;
+}
+
+//@ has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header']" "impl<T> MyTrait for Twhere T: Debug"
+impl<T> MyTrait for T
+where
+    T: fmt::Debug,
+{
+    fn my_string(&self) -> String {
+        format!("{:?}", self)
+    }
+}
+
+pub fn main() {}
diff --git a/tests/rustdoc/impl/blanket-impl-78673.rs b/tests/rustdoc/impl/blanket-impl-78673.rs
new file mode 100644
index 00000000000..412d4057406
--- /dev/null
+++ b/tests/rustdoc/impl/blanket-impl-78673.rs
@@ -0,0 +1,25 @@
+// https://github.com/rust-lang/rust/issues/78673
+#![crate_name = "issue_78673"]
+
+pub trait Something {}
+
+pub trait AnAmazingTrait {}
+
+impl<T: Something> AnAmazingTrait for T {}
+
+//@ has 'issue_78673/struct.MyStruct.html'
+//@ has  - '//*[@class="impl"]' 'AnAmazingTrait for MyStruct'
+//@ !has - '//*[@class="impl"]' 'AnAmazingTrait for T'
+pub struct MyStruct;
+
+impl AnAmazingTrait for MyStruct {}
+
+// generic structs may have _both_ specific and blanket impls that apply
+
+//@ has 'issue_78673/struct.AnotherStruct.html'
+//@ has - '//*[@class="impl"]' 'AnAmazingTrait for AnotherStruct<()>'
+//@ has - '//*[@class="impl"]' 'AnAmazingTrait for T'
+pub struct AnotherStruct<T>(T);
+
+impl<T: Something> Something for AnotherStruct<T> {}
+impl AnAmazingTrait for AnotherStruct<()> {}
diff --git a/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs
new file mode 100644
index 00000000000..ebfe251134a
--- /dev/null
+++ b/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs
@@ -0,0 +1,35 @@
+// Issue #86448: test for cross-crate `doc(hidden)`
+#![crate_name = "foo"]
+
+//@ aux-build:cross-crate-hidden-impl-parameter.rs
+extern crate cross_crate_hidden_impl_parameter;
+
+pub use ::cross_crate_hidden_impl_parameter::{HiddenType, HiddenTrait}; // OK, not re-exported
+
+pub enum MyLibType {}
+
+//@ !has foo/enum.MyLibType.html '//*[@id="impl-From%3CHiddenType%3E"]' 'impl From<HiddenType> for MyLibType'
+impl From<HiddenType> for MyLibType {
+    fn from(it: HiddenType) -> MyLibType {
+        match it {}
+    }
+}
+
+pub struct T<T>(T);
+
+//@ !has foo/enum.MyLibType.html '//*[@id="impl-From%3CT%3CT%3CT%3CT%3CHiddenType%3E%3E%3E%3E%3E"]' 'impl From<T<T<T<T<HiddenType>>>>> for MyLibType'
+impl From<T<T<T<T<HiddenType>>>>> for MyLibType {
+    fn from(it: T<T<T<T<HiddenType>>>>) -> MyLibType {
+        todo!()
+    }
+}
+
+//@ !has foo/enum.MyLibType.html '//*[@id="impl-HiddenTrait"]' 'impl HiddenTrait for MyLibType'
+impl HiddenTrait for MyLibType {}
+
+//@ !has foo/struct.T.html '//*[@id="impl-From%3CMyLibType%3E"]' 'impl From<MyLibType> for T<T<T<T<HiddenType>>>>'
+impl From<MyLibType> for T<T<T<T<HiddenType>>>> {
+    fn from(it: MyLibType) -> T<T<T<T<HiddenType>>>> {
+        match it {}
+    }
+}
diff --git a/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs b/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs
new file mode 100644
index 00000000000..5812d414997
--- /dev/null
+++ b/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs
@@ -0,0 +1,14 @@
+// https://github.com/rust-lang/rust/issues/21474
+#![crate_name="issue_21474"]
+
+pub use inner::*;
+
+mod inner {
+    impl super::Blah for super::What { }
+}
+
+pub trait Blah { }
+
+//@ count issue_21474/struct.What.html \
+//        '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+pub struct What;
diff --git a/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs b/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs
new file mode 100644
index 00000000000..7b1648a56ac
--- /dev/null
+++ b/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs
@@ -0,0 +1,9 @@
+//@ aux-build:issue-22025.rs
+//@ ignore-cross-compile
+
+// https://github.com/rust-lang/rust/issues/22025
+#![crate_name="issue_22025"]
+
+extern crate issue_22025;
+
+pub use issue_22025::foo::{Foo, Bar};
diff --git a/tests/rustdoc/impl/default-impl.rs b/tests/rustdoc/impl/default-impl.rs
new file mode 100644
index 00000000000..2ba9c4ab5ad
--- /dev/null
+++ b/tests/rustdoc/impl/default-impl.rs
@@ -0,0 +1,9 @@
+//@ aux-build:rustdoc-default-impl.rs
+//@ ignore-cross-compile
+
+extern crate rustdoc_default_impl as foo;
+
+pub use foo::bar;
+
+pub fn wut<T: bar::Bar>() {
+}
diff --git a/tests/rustdoc/impl/deprecated-impls.rs b/tests/rustdoc/impl/deprecated-impls.rs
new file mode 100644
index 00000000000..a57f26ec7fd
--- /dev/null
+++ b/tests/rustdoc/impl/deprecated-impls.rs
@@ -0,0 +1,118 @@
+#![crate_name = "foo"]
+
+//@ has foo/struct.Foo0.html
+pub struct Foo0;
+
+impl Foo0 {
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.1: fn_with_doc'
+    //@ hasraw - 'fn_with_doc short'
+    //@ hasraw - 'fn_with_doc full'
+    /// fn_with_doc short
+    ///
+    /// fn_with_doc full
+    #[deprecated(since = "1.0.1", note = "fn_with_doc")]
+    pub fn fn_with_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.2: fn_without_doc'
+    #[deprecated(since = "1.0.2", note = "fn_without_doc")]
+    pub fn fn_without_doc() {}
+}
+
+pub trait Bar {
+    /// fn_empty_with_doc short
+    ///
+    /// fn_empty_with_doc full
+    #[deprecated(since = "1.0.3", note = "fn_empty_with_doc")]
+    fn fn_empty_with_doc();
+
+    #[deprecated(since = "1.0.4", note = "fn_empty_without_doc")]
+    fn fn_empty_without_doc();
+
+    /// fn_def_with_doc short
+    ///
+    /// fn_def_with_doc full
+    #[deprecated(since = "1.0.5", note = "fn_def_with_doc")]
+    fn fn_def_with_doc() {}
+
+    #[deprecated(since = "1.0.6", note = "fn_def_without_doc")]
+    fn fn_def_without_doc() {}
+
+    /// fn_def_def_with_doc short
+    ///
+    /// fn_def_def_with_doc full
+    #[deprecated(since = "1.0.7", note = "fn_def_def_with_doc")]
+    fn fn_def_def_with_doc() {}
+
+    #[deprecated(since = "1.0.8", note = "fn_def_def_without_doc")]
+    fn fn_def_def_without_doc() {}
+}
+
+//@ has foo/struct.Foo1.html
+pub struct Foo1;
+
+impl Bar for Foo1 {
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
+    //@ hasraw - 'fn_empty_with_doc_impl short'
+    //@ hasraw - 'fn_empty_with_doc_impl full'
+    /// fn_empty_with_doc_impl short
+    ///
+    /// fn_empty_with_doc_impl full
+    fn fn_empty_with_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.4: fn_empty_without_doc'
+    fn fn_empty_without_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
+    //@ hasraw - 'fn_def_with_doc_impl short'
+    //@ hasraw - 'fn_def_with_doc_impl full'
+    /// fn_def_with_doc_impl short
+    ///
+    /// fn_def_with_doc_impl full
+    fn fn_def_with_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.6: fn_def_without_doc'
+    fn fn_def_without_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
+    //@ hasraw - 'fn_def_def_with_doc short'
+    //@ !hasraw - 'fn_def_def_with_doc full'
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
+}
+
+//@ has foo/struct.Foo2.html
+pub struct Foo2;
+
+impl Bar for Foo2 {
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.3: fn_empty_with_doc'
+    //@ hasraw - 'fn_empty_with_doc short'
+    //@ !hasraw - 'fn_empty_with_doc full'
+    fn fn_empty_with_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.4: fn_empty_without_doc'
+    //@ hasraw - 'fn_empty_without_doc_impl short'
+    //@ hasraw - 'fn_empty_without_doc_impl full'
+    /// fn_empty_without_doc_impl short
+    ///
+    /// fn_empty_without_doc_impl full
+    fn fn_empty_without_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.5: fn_def_with_doc'
+    //@ hasraw - 'fn_def_with_doc short'
+    //@ !hasraw - 'fn_def_with_doc full'
+    fn fn_def_with_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.6: fn_def_without_doc'
+    //@ hasraw - 'fn_def_without_doc_impl short'
+    //@ hasraw - 'fn_def_without_doc_impl full'
+    /// fn_def_without_doc_impl short
+    ///
+    /// fn_def_without_doc_impl full
+    fn fn_def_without_doc() {}
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.7: fn_def_def_with_doc'
+    //@ hasraw - 'fn_def_def_with_doc short'
+    //@ !hasraw - 'fn_def_def_with_doc full'
+
+    //@ has - '//*[@class="stab deprecated"]' 'Deprecated since 1.0.8: fn_def_def_without_doc'
+}
diff --git a/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs b/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs
new file mode 100644
index 00000000000..d5ee3d09276
--- /dev/null
+++ b/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs
@@ -0,0 +1,13 @@
+// https://github.com/rust-lang/rust/issues/33069
+#![crate_name="issue_33069"]
+
+pub trait Bar {}
+
+#[doc(hidden)]
+pub mod hidden {
+    pub struct Foo;
+}
+
+//@ has issue_33069/trait.Bar.html
+//@ !has - '//code' 'impl Bar for Foo'
+impl Bar for hidden::Foo {}
diff --git a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
new file mode 100644
index 00000000000..f85d7b23637
--- /dev/null
+++ b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs
@@ -0,0 +1,24 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/101129>.
+
+#![feature(doc_auto_cfg)]
+#![crate_type = "lib"]
+#![crate_name = "foo"]
+
+pub struct S;
+pub trait MyTrait1 {}
+pub trait MyTrait2 {}
+
+//@ has foo/struct.S.html
+//@ has - '//*[@id="impl-MyTrait1-for-S"]//*[@class="stab portability"]' \
+//        'Available on non-crate feature coolstuff only.'
+#[cfg(not(feature = "coolstuff"))]
+impl MyTrait1 for S {}
+
+#[cfg(not(feature = "coolstuff"))]
+mod submod {
+    use crate::{S, MyTrait2};
+    // This impl should also have the `not(feature = "coolstuff")`.
+    //@ has - '//*[@id="impl-MyTrait2-for-S"]//*[@class="stab portability"]' \
+    //        'Available on non-crate feature coolstuff only.'
+    impl MyTrait2 for S {}
+}
diff --git a/tests/rustdoc/impl/duplicated_impl.rs b/tests/rustdoc/impl/duplicated_impl.rs
new file mode 100644
index 00000000000..e7828885cc1
--- /dev/null
+++ b/tests/rustdoc/impl/duplicated_impl.rs
@@ -0,0 +1,14 @@
+// This test ensures that the same implementation doesn't show more than once.
+// It's a regression test for https://github.com/rust-lang/rust/issues/96036.
+
+#![crate_name = "foo"]
+
+// We check that there is only one "impl<T> Something<Whatever> for T" listed in the
+// blanket implementations.
+
+//@ has 'foo/struct.Whatever.html'
+//@ count - '//*[@id="blanket-implementations-list"]/section[@class="impl"]' 1
+
+pub trait Something<T> { }
+pub struct Whatever;
+impl<T> Something<Whatever> for T {}
diff --git a/tests/rustdoc/impl/empty-impl-block.rs b/tests/rustdoc/impl/empty-impl-block.rs
new file mode 100644
index 00000000000..91fd4a64ef9
--- /dev/null
+++ b/tests/rustdoc/impl/empty-impl-block.rs
@@ -0,0 +1,20 @@
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.Foo.html'
+pub struct Foo;
+
+//@ has - '//*[@class="docblock"]' 'Hello empty impl block!'
+//@ has - '//*[@class="item-info"]' 'This impl block contains no items.'
+/// Hello empty impl block!
+impl Foo {}
+// We ensure that this empty impl block without doc isn't rendered.
+//@ count - '//*[@class="impl"]' 'impl Foo' 1
+impl Foo {}
+
+// Just to ensure that empty trait impl blocks are rendered.
+pub struct Another;
+pub trait Bar {}
+
+//@ has 'foo/struct.Another.html'
+//@ has - '//h3[@class="code-header"]' 'impl Bar for Another'
+impl Bar for Another {}
diff --git a/tests/rustdoc/impl/empty-impls.rs b/tests/rustdoc/impl/empty-impls.rs
new file mode 100644
index 00000000000..912a8d3d913
--- /dev/null
+++ b/tests/rustdoc/impl/empty-impls.rs
@@ -0,0 +1,19 @@
+#![crate_name = "foo"]
+
+//@ has foo/struct.Foo.html
+//@ has - '//div[@id="synthetic-implementations-list"]/*[@id="impl-Send-for-Foo"]' 'impl Send for Foo'
+pub struct Foo;
+
+pub trait EmptyTrait {}
+
+//@ has - '//div[@id="trait-implementations-list"]/*[@id="impl-EmptyTrait-for-Foo"]' 'impl EmptyTrait for Foo'
+impl EmptyTrait for Foo {}
+
+pub trait NotEmpty {
+    fn foo(&self);
+}
+
+//@ has - '//div[@id="trait-implementations-list"]/details/summary/*[@id="impl-NotEmpty-for-Foo"]' 'impl NotEmpty for Foo'
+impl NotEmpty for Foo {
+    fn foo(&self) {}
+}
diff --git a/tests/rustdoc/impl/extern-impl-trait.rs b/tests/rustdoc/impl/extern-impl-trait.rs
new file mode 100644
index 00000000000..65b7a8cef49
--- /dev/null
+++ b/tests/rustdoc/impl/extern-impl-trait.rs
@@ -0,0 +1,11 @@
+//@ aux-build:extern-impl-trait.rs
+
+#![crate_name = "foo"]
+
+extern crate extern_impl_trait;
+
+//@ has 'foo/struct.X.html' '//h4[@class="code-header"]' "impl Foo<Associated = ()> + 'a"
+pub use extern_impl_trait::X;
+
+//@ has 'foo/struct.Y.html' '//h4[@class="code-header"]' "impl Foo<Associated = ()> + ?Sized + 'a"
+pub use extern_impl_trait::Y;
diff --git a/tests/rustdoc/impl/extern-impl.rs b/tests/rustdoc/impl/extern-impl.rs
new file mode 100644
index 00000000000..4fc31393988
--- /dev/null
+++ b/tests/rustdoc/impl/extern-impl.rs
@@ -0,0 +1,27 @@
+#![crate_name = "foo"]
+
+//@ has foo/struct.Foo.html
+pub struct Foo;
+
+impl Foo {
+    //@ has - '//h4[@class="code-header"]' 'fn rust0()'
+    pub fn rust0() {}
+    //@ has - '//h4[@class="code-header"]' 'fn rust1()'
+    pub extern "Rust" fn rust1() {}
+    //@ has - '//h4[@class="code-header"]' 'extern "C" fn c0()'
+    pub extern fn c0() {}
+    //@ has - '//h4[@class="code-header"]' 'extern "C" fn c1()'
+    pub extern "C" fn c1() {}
+    //@ has - '//h4[@class="code-header"]' 'extern "system" fn system0()'
+    pub extern "system" fn system0() {}
+}
+
+//@ has foo/trait.Bar.html
+pub trait Bar {}
+
+//@ has - '//h3[@class="code-header"]' 'impl Bar for fn()'
+impl Bar for fn() {}
+//@ has - '//h3[@class="code-header"]' 'impl Bar for extern "C" fn()'
+impl Bar for extern fn() {}
+//@ has - '//h3[@class="code-header"]' 'impl Bar for extern "system" fn()'
+impl Bar for extern "system" fn() {}
diff --git a/tests/rustdoc/impl/foreign-implementors-js-43701.rs b/tests/rustdoc/impl/foreign-implementors-js-43701.rs
new file mode 100644
index 00000000000..03147da02c2
--- /dev/null
+++ b/tests/rustdoc/impl/foreign-implementors-js-43701.rs
@@ -0,0 +1,6 @@
+// https://github.com/rust-lang/rust/issues/43701
+#![crate_name = "foo"]
+
+pub use std::vec::Vec;
+
+//@ !has trait.impl/core/clone/trait.Clone.js
diff --git a/tests/rustdoc/impl/generic-impl.rs b/tests/rustdoc/impl/generic-impl.rs
new file mode 100644
index 00000000000..9d15d0fff77
--- /dev/null
+++ b/tests/rustdoc/impl/generic-impl.rs
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+use std::fmt;
+
+//@ !has foo/struct.Bar.html '//*[@id="impl-ToString-for-Bar"]' ''
+pub struct Bar;
+
+//@ has foo/struct.Foo.html '//*[@id="impl-ToString-for-T"]//h3[@class="code-header"]' 'impl<T> ToString for T'
+pub struct Foo;
+//@ has foo/struct.Foo.html '//*[@class="sidebar-elems"]//section//a[@href="#impl-ToString-for-T"]' 'ToString'
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Foo")
+    }
+}
diff --git a/tests/rustdoc/impl/hidden-implementors-90781.rs b/tests/rustdoc/impl/hidden-implementors-90781.rs
new file mode 100644
index 00000000000..960a85b91f0
--- /dev/null
+++ b/tests/rustdoc/impl/hidden-implementors-90781.rs
@@ -0,0 +1,78 @@
+//@ compile-flags: -Z unstable-options --document-hidden-items --document-private-items
+
+// regression test for https://github.com/rust-lang/rust/issues/90781
+#![crate_name = "foo"]
+
+//@ has foo/trait.TPubVis.html
+//@ has - '//*[@id="implementors-list"]' 'HidPriv'
+//@ has - '//*[@id="implementors-list"]' 'HidPub'
+//@ has - '//*[@id="implementors-list"]' 'VisPriv'
+//@ has - '//*[@id="implementors-list"]' 'VisPub'
+pub trait TPubVis {}
+
+//@ has foo/trait.TPubHidden.html
+//@ has - '//*[@id="implementors-list"]' 'HidPriv'
+//@ has - '//*[@id="implementors-list"]' 'HidPub'
+//@ has - '//*[@id="implementors-list"]' 'VisPriv'
+//@ has - '//*[@id="implementors-list"]' 'VisPub'
+#[doc(hidden)]
+pub trait TPubHidden {}
+
+//@ has foo/trait.TPrivVis.html
+//@ has - '//*[@id="implementors-list"]' 'HidPriv'
+//@ has - '//*[@id="implementors-list"]' 'HidPub'
+//@ has - '//*[@id="implementors-list"]' 'VisPriv'
+//@ has - '//*[@id="implementors-list"]' 'VisPub'
+trait TPrivVis {}
+
+#[doc(hidden)]
+//@ has foo/trait.TPrivHidden.html
+//@ has - '//*[@id="impl-TPrivHidden-for-HidPriv"]' 'HidPriv'
+//@ has - '//*[@id="impl-TPrivHidden-for-HidPub"]' 'HidPub'
+//@ has - '//*[@id="impl-TPrivHidden-for-VisPriv"]' 'VisPriv'
+//@ has - '//*[@id="impl-TPrivHidden-for-VisPub"]' 'VisPub'
+trait TPrivHidden {}
+
+//@ has foo/struct.VisPub.html
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
+pub struct VisPub;
+
+//@ has foo/struct.VisPriv.html
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
+struct VisPriv;
+
+//@ has foo/struct.HidPub.html
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
+#[doc(hidden)]
+pub struct HidPub;
+
+//@ has foo/struct.HidPriv.html
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPrivVis'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubHidden'
+//@ has - '//*[@id="trait-implementations-list"]' 'TPubVis'
+#[doc(hidden)]
+struct HidPriv;
+
+macro_rules! implement {
+    ($trait:ident - $($struct:ident)+) => {
+        $(
+            impl $trait for $struct {}
+        )+
+    }
+}
+
+
+implement!(TPubVis - VisPub VisPriv HidPub HidPriv);
+implement!(TPubHidden - VisPub VisPriv HidPub HidPriv);
+implement!(TPrivVis - VisPub VisPriv HidPub HidPriv);
+implement!(TPrivHidden - VisPub VisPriv HidPub HidPriv);
diff --git a/tests/rustdoc/impl/hidden-impls.rs b/tests/rustdoc/impl/hidden-impls.rs
new file mode 100644
index 00000000000..73deeed9e90
--- /dev/null
+++ b/tests/rustdoc/impl/hidden-impls.rs
@@ -0,0 +1,17 @@
+#![crate_name = "foo"]
+
+mod hidden {
+    #[derive(Clone)]
+    pub struct Foo;
+}
+
+#[doc(hidden)]
+pub mod __hidden {
+    pub use hidden::Foo;
+}
+
+//@ has foo/trait.Clone.html
+//@ !hasraw - 'Foo'
+//@ has trait.impl/core/clone/trait.Clone.js
+//@ !hasraw - 'Foo'
+pub use std::clone::Clone;
diff --git a/tests/rustdoc/impl/hidden-trait-struct-impls.rs b/tests/rustdoc/impl/hidden-trait-struct-impls.rs
new file mode 100644
index 00000000000..1010cb45960
--- /dev/null
+++ b/tests/rustdoc/impl/hidden-trait-struct-impls.rs
@@ -0,0 +1,22 @@
+#![crate_name = "foo"]
+
+#[doc(hidden)]
+pub trait Foo {}
+
+trait Dark {}
+
+pub trait Bam {}
+
+pub struct Bar;
+
+struct Hidden;
+
+//@ !has foo/struct.Bar.html '//*[@id="impl-Foo-for-Bar"]' 'impl Foo for Bar'
+impl Foo for Bar {}
+//@ !has foo/struct.Bar.html '//*[@id="impl-Dark-for-Bar"]' 'impl Dark for Bar'
+impl Dark for Bar {}
+//@ has foo/struct.Bar.html '//*[@id="impl-Bam-for-Bar"]' 'impl Bam for Bar'
+//@ has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Bar'
+impl Bam for Bar {}
+//@ !has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Hidden'
+impl Bam for Hidden {}
diff --git a/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs b/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs
new file mode 100644
index 00000000000..995121a8455
--- /dev/null
+++ b/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs
@@ -0,0 +1,24 @@
+// https://github.com/rust-lang/rust/issues/74083
+#![crate_name="foo"]
+
+use std::ops::Deref;
+
+pub struct Foo;
+
+impl Foo {
+    pub fn foo(&mut self) {}
+}
+
+//@ has foo/struct.Bar.html
+//@ !has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo'
+pub struct Bar {
+    foo: Foo,
+}
+
+impl Deref for Bar {
+    type Target = Foo;
+
+    fn deref(&self) -> &Foo {
+        &self.foo
+    }
+}
diff --git a/tests/rustdoc/impl/impl-alias-substituted.rs b/tests/rustdoc/impl/impl-alias-substituted.rs
new file mode 100644
index 00000000000..02efcd88df8
--- /dev/null
+++ b/tests/rustdoc/impl/impl-alias-substituted.rs
@@ -0,0 +1,9 @@
+pub struct Matrix<T, const N: usize, const M: usize>([[T; N]; M]);
+
+pub type Vector<T, const N: usize> = Matrix<T, N, 1>;
+
+//@ has "impl_alias_substituted/struct.Matrix.html" '//*[@class="impl"]//h3[@class="code-header"]' \
+//  "impl<T: Copy> Matrix<T, 3, 1>"
+impl<T: Copy> Vector<T, 3> {
+    pub fn test() {}
+}
diff --git a/tests/rustdoc/impl/impl-assoc-type-21092.rs b/tests/rustdoc/impl/impl-assoc-type-21092.rs
new file mode 100644
index 00000000000..c350456195d
--- /dev/null
+++ b/tests/rustdoc/impl/impl-assoc-type-21092.rs
@@ -0,0 +1,11 @@
+//@ aux-build:issue-21092.rs
+//@ ignore-cross-compile
+
+// https://github.com/rust-lang/rust/issues/21092
+#![crate_name="issue_21092"]
+
+extern crate issue_21092;
+
+//@ has issue_21092/struct.Bar.html
+//@ has - '//*[@id="associatedtype.Bar"]' 'type Bar = i32'
+pub use issue_21092::{Foo, Bar};
diff --git a/tests/rustdoc/impl/impl-associated-items-order.rs b/tests/rustdoc/impl/impl-associated-items-order.rs
new file mode 100644
index 00000000000..759e0f0b400
--- /dev/null
+++ b/tests/rustdoc/impl/impl-associated-items-order.rs
@@ -0,0 +1,42 @@
+// This test ensures that impl associated items always follow this order:
+//
+// 1. Consts
+// 2. Types
+// 3. Functions
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.Bar.html'
+pub struct Bar;
+
+impl Bar {
+    //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[3]/h4' \
+    // 'pub fn foo()'
+    pub fn foo() {}
+    //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[1]/h4' \
+    // 'pub const X: u8 = 12u8'
+    pub const X: u8 = 12;
+    //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[2]/h4' \
+    // 'pub type Y = u8'
+    pub type Y = u8;
+}
+
+pub trait Foo {
+    const W: u32;
+    fn yeay();
+    type Z;
+}
+
+impl Foo for Bar {
+    //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[2]/h4' \
+    // 'type Z = u8'
+    type Z = u8;
+    //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[1]/h4' \
+    // 'const W: u32 = 12u32'
+    const W: u32 = 12;
+    //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[3]/h4' \
+    // 'fn yeay()'
+    fn yeay() {}
+}
diff --git a/tests/rustdoc/impl/impl-associated-items-sidebar.rs b/tests/rustdoc/impl/impl-associated-items-sidebar.rs
new file mode 100644
index 00000000000..d393a577e50
--- /dev/null
+++ b/tests/rustdoc/impl/impl-associated-items-sidebar.rs
@@ -0,0 +1,42 @@
+// This test ensures that impl/trait associated items are listed in the sidebar.
+
+// ignore-tidy-linelength
+
+#![feature(inherent_associated_types)]
+#![feature(associated_type_defaults)]
+#![allow(incomplete_features)]
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.Bar.html'
+pub struct Bar;
+
+impl Bar {
+    //@ has - '//*[@class="sidebar-elems"]//h3[1]' 'Associated Constants'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block associatedconstant"]/li/a[@href="#associatedconstant.X"]' 'X'
+    pub const X: u8 = 12;
+    //@ has - '//*[@class="sidebar-elems"]//h3[2]' 'Associated Types'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block associatedtype"]/li/a[@href="#associatedtype.Y"]' 'Y'
+    pub type Y = u8;
+}
+
+//@ has 'foo/trait.Foo.html'
+pub trait Foo {
+    //@ has - '//*[@class="sidebar-elems"]//h3[5]' 'Required Methods'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][5]/li/a[@href="#tymethod.yeay"]' 'yeay'
+    fn yeay();
+    //@ has - '//*[@class="sidebar-elems"]//h3[6]' 'Provided Methods'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][6]/li/a[@href="#method.boo"]' 'boo'
+    fn boo() {}
+    //@ has - '//*[@class="sidebar-elems"]//h3[1]' 'Required Associated Constants'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][1]/li/a[@href="#associatedconstant.W"]' 'W'
+    const W: u32;
+    //@ has - '//*[@class="sidebar-elems"]//h3[2]' 'Provided Associated Constants'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][2]/li/a[@href="#associatedconstant.U"]' 'U'
+    const U: u32 = 0;
+    //@ has - '//*[@class="sidebar-elems"]//h3[3]' 'Required Associated Types'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][3]/li/a[@href="#associatedtype.Z"]' 'Z'
+    type Z;
+    //@ has - '//*[@class="sidebar-elems"]//h3[4]' 'Provided Associated Types'
+    //@ has - '//*[@class="sidebar-elems"]//ul[@class="block"][4]/li/a[@href="#associatedtype.T"]' 'T'
+    type T = u32;
+}
diff --git a/tests/rustdoc/impl/impl-blanket-53689.rs b/tests/rustdoc/impl/impl-blanket-53689.rs
new file mode 100644
index 00000000000..4b1697349f2
--- /dev/null
+++ b/tests/rustdoc/impl/impl-blanket-53689.rs
@@ -0,0 +1,17 @@
+// https://github.com/rust-lang/rust/issues/53689
+//@ aux-build:issue-53689.rs
+
+#![crate_name = "foo"]
+
+extern crate issue_53689;
+
+//@ has foo/trait.MyTrait.html
+//@ !hasraw - 'MyStruct'
+//@ count - '//*[h3="impl<T> MyTrait for T"]' 1
+pub trait MyTrait {}
+
+impl<T> MyTrait for T {}
+
+mod a {
+    pub use issue_53689::MyStruct;
+}
diff --git a/tests/rustdoc/impl/impl-box.rs b/tests/rustdoc/impl/impl-box.rs
new file mode 100644
index 00000000000..1fb63e21685
--- /dev/null
+++ b/tests/rustdoc/impl/impl-box.rs
@@ -0,0 +1,16 @@
+// https://github.com/rust-lang/rust/issues/92940
+//
+// Show traits implemented on fundamental types that wrap local ones.
+
+pub struct MyType;
+
+//@ has 'impl_box/struct.MyType.html'
+//@ has '-' '//*[@id="impl-Iterator-for-Box%3CMyType%3E"]' 'impl Iterator for Box<MyType>'
+
+impl Iterator for Box<MyType> {
+    type Item = ();
+
+    fn next(&mut self) -> Option<Self::Item> {
+        todo!()
+    }
+}
diff --git a/tests/rustdoc/impl/impl-disambiguation.rs b/tests/rustdoc/impl/impl-disambiguation.rs
new file mode 100644
index 00000000000..cfd5013964b
--- /dev/null
+++ b/tests/rustdoc/impl/impl-disambiguation.rs
@@ -0,0 +1,30 @@
+#![crate_name = "foo"]
+
+pub trait Foo {}
+
+pub struct Bar<T> { field: T }
+
+//@ has foo/trait.Foo.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
+//     "impl Foo for Bar<u8>"
+impl Foo for Bar<u8> {}
+//@ has foo/trait.Foo.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
+//     "impl Foo for Bar<u16>"
+impl Foo for Bar<u16> {}
+//@ has foo/trait.Foo.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
+//     "impl<'a> Foo for &'a Bar<u8>"
+impl<'a> Foo for &'a Bar<u8> {}
+
+pub mod mod1 {
+    pub struct Baz {}
+}
+
+pub mod mod2 {
+    pub enum Baz {}
+}
+
+//@ has foo/trait.Foo.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
+//     "impl Foo for foo::mod1::Baz"
+impl Foo for mod1::Baz {}
+//@ has foo/trait.Foo.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
+//     "impl<'a> Foo for &'a foo::mod2::Baz"
+impl<'a> Foo for &'a mod2::Baz {}
diff --git a/tests/rustdoc/impl/impl-everywhere.rs b/tests/rustdoc/impl/impl-everywhere.rs
new file mode 100644
index 00000000000..d1a4e901bad
--- /dev/null
+++ b/tests/rustdoc/impl/impl-everywhere.rs
@@ -0,0 +1,30 @@
+#![crate_name = "foo"]
+
+pub trait Foo {}
+pub trait Foo2 {}
+
+pub struct Bar;
+
+impl Foo for Bar {}
+impl Foo2 for Bar {}
+
+//@ has foo/fn.foo.html '//section[@id="main-content"]//pre' "x: &'x impl Foo"
+//@ has foo/fn.foo.html '//section[@id="main-content"]//pre' "-> &'x impl Foo"
+pub fn foo<'x>(x: &'x impl Foo) -> &'x impl Foo {
+    x
+}
+
+//@ has foo/fn.foo2.html '//section[@id="main-content"]//pre' "x: &'x impl Foo"
+//@ has foo/fn.foo2.html '//section[@id="main-content"]//pre' '-> impl Foo2'
+pub fn foo2<'x>(_x: &'x impl Foo) -> impl Foo2 {
+    Bar
+}
+
+//@ has foo/fn.foo_foo.html '//section[@id="main-content"]//pre' '-> impl Foo + Foo2'
+pub fn foo_foo() -> impl Foo + Foo2 {
+    Bar
+}
+
+//@ has foo/fn.foo_foo_foo.html '//section[@id="main-content"]//pre' "x: &'x (impl Foo + Foo2)"
+pub fn foo_foo_foo<'x>(_x: &'x (impl Foo + Foo2)) {
+}
diff --git a/tests/rustdoc/impl/impl-in-const-block.rs b/tests/rustdoc/impl/impl-in-const-block.rs
new file mode 100644
index 00000000000..3f757fa9566
--- /dev/null
+++ b/tests/rustdoc/impl/impl-in-const-block.rs
@@ -0,0 +1,43 @@
+// Regression test for #83026.
+// The goal of this test is to ensure that impl blocks inside
+// const expressions are documented as well.
+
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.A.html'
+//@ has - '//*[@id="method.new"]/*[@class="code-header"]' 'pub fn new() -> A'
+//@ has - '//*[@id="method.bar"]/*[@class="code-header"]' 'pub fn bar(&self)'
+//@ has - '//*[@id="method.woo"]/*[@class="code-header"]' 'pub fn woo(&self)'
+//@ has - '//*[@id="method.yoo"]/*[@class="code-header"]' 'pub fn yoo()'
+//@ has - '//*[@id="method.yuu"]/*[@class="code-header"]' 'pub fn yuu()'
+pub struct A;
+
+const _: () = {
+    impl A {
+        const FOO: () = {
+            impl A {
+                pub fn woo(&self) {}
+            }
+        };
+
+        pub fn new() -> A {
+            A
+        }
+    }
+};
+pub const X: () = {
+    impl A {
+        pub fn bar(&self) {}
+    }
+};
+
+fn foo() {
+    impl A {
+        pub fn yoo() {}
+    }
+    const _: () = {
+        impl A {
+            pub fn yuu() {}
+        }
+    };
+}
diff --git a/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs b/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs
new file mode 100644
index 00000000000..a514bc35bfc
--- /dev/null
+++ b/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs
@@ -0,0 +1,27 @@
+#![crate_name = "foo"]
+
+//@ has 'foo/index.html'
+// There should be only `type A`.
+//@ count - '//*[@class="item-table"]//dt' 1
+//@ has - '//dt/a[@href="type.A.html"]' 'A'
+
+mod foo {
+    pub struct S;
+}
+
+use foo::S;
+
+pub type A = S;
+
+//@ has 'foo/type.A.html'
+//@ has - '//*[@id="method.default"]/h4' 'fn default() -> Self'
+impl Default for A {
+    fn default() -> Self {
+        S
+    }
+}
+
+//@ has - '//*[@id="method.a"]/h4' 'pub fn a(&self)'
+impl A {
+    pub fn a(&self) {}
+}
diff --git a/tests/rustdoc/impl/impl-parts-crosscrate.rs b/tests/rustdoc/impl/impl-parts-crosscrate.rs
new file mode 100644
index 00000000000..631c8bb3eb3
--- /dev/null
+++ b/tests/rustdoc/impl/impl-parts-crosscrate.rs
@@ -0,0 +1,20 @@
+//@ aux-build:rustdoc-impl-parts-crosscrate.rs
+//@ ignore-cross-compile
+
+#![feature(negative_impls)]
+
+extern crate rustdoc_impl_parts_crosscrate;
+
+pub struct Bar<T: Copy + Send> { t: T }
+
+// The output file is html embedded in javascript, so the html tags
+// aren't stripped by the processing script and we can't check for the
+// full impl string.  Instead, just make sure something from each part
+// is mentioned.
+
+//@ hasraw trait.impl/rustdoc_impl_parts_crosscrate/trait.AnAutoTrait.js Bar
+//@ hasraw - Send
+//@ hasraw - !AnAutoTrait
+//@ hasraw - Copy
+impl<T: Send> !rustdoc_impl_parts_crosscrate::AnAutoTrait for Bar<T>
+    where T: Copy {}
diff --git a/tests/rustdoc/impl/impl-parts.rs b/tests/rustdoc/impl/impl-parts.rs
new file mode 100644
index 00000000000..4f281bfd63c
--- /dev/null
+++ b/tests/rustdoc/impl/impl-parts.rs
@@ -0,0 +1,12 @@
+#![feature(negative_impls)]
+#![feature(auto_traits)]
+
+pub auto trait AnAutoTrait {}
+
+pub struct Foo<T: Clone + Sync> { field: T }
+
+//@ has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \
+//     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
+//@ has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
+//     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
+impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {}
diff --git a/tests/rustdoc/impl/impl-ref-20175.rs b/tests/rustdoc/impl/impl-ref-20175.rs
new file mode 100644
index 00000000000..b1a9286fd41
--- /dev/null
+++ b/tests/rustdoc/impl/impl-ref-20175.rs
@@ -0,0 +1,14 @@
+// https://github.com/rust-lang/rust/issues/20175
+
+#![crate_name="issue_20175"]
+
+pub trait Foo {
+    fn foo(&self) {}
+}
+
+pub struct Bar;
+
+//@ has issue_20175/struct.Bar.html \
+//      '//*[@id="method.foo"]' \
+//      'fn foo'
+impl<'a> Foo for &'a Bar {}
diff --git a/tests/rustdoc/impl/impl-trait-43869.rs b/tests/rustdoc/impl/impl-trait-43869.rs
new file mode 100644
index 00000000000..89176f59ca1
--- /dev/null
+++ b/tests/rustdoc/impl/impl-trait-43869.rs
@@ -0,0 +1,75 @@
+// https://github.com/rust-lang/rust/issues/43869
+#![crate_name="foo"]
+
+pub fn g() -> impl Iterator<Item=u8> {
+    Some(1u8).into_iter()
+}
+
+#[allow(unused_parens)]
+pub fn h() -> (impl Iterator<Item=u8>) {
+    Some(1u8).into_iter()
+}
+
+pub fn i() -> impl Iterator<Item=u8> + 'static {
+    Some(1u8).into_iter()
+}
+
+pub fn j() -> impl Iterator<Item=u8> + Clone {
+    Some(1u8).into_iter()
+}
+
+pub fn k() -> [impl Clone; 2] {
+    [123u32, 456u32]
+}
+
+pub fn l() -> (impl Clone, impl Default) {
+    (789u32, -123i32)
+}
+
+pub fn m() -> &'static impl Clone {
+    &1u8
+}
+
+pub fn n() -> *const impl Clone {
+    &1u8
+}
+
+pub fn o() -> &'static [impl Clone] {
+    b":)"
+}
+
+// issue #44731
+pub fn test_44731_0() -> Box<impl Iterator<Item=u8>> {
+    Box::new(g())
+}
+
+pub fn test_44731_1() -> Result<Box<impl Clone>, ()> {
+    Ok(Box::new(j()))
+}
+
+// NOTE these involve Fn sugar, where impl Trait is disallowed for now, see issue #45994
+//
+//pub fn test_44731_2() -> Box<Fn(impl Clone)> {
+//    Box::new(|_: u32| {})
+//}
+//
+//pub fn test_44731_3() -> Box<Fn() -> impl Clone> {
+//    Box::new(|| 0u32)
+//}
+
+pub fn test_44731_4() -> Box<Iterator<Item=impl Clone>> {
+    Box::new(g())
+}
+
+//@ has foo/fn.g.html
+//@ has foo/fn.h.html
+//@ has foo/fn.i.html
+//@ has foo/fn.j.html
+//@ has foo/fn.k.html
+//@ has foo/fn.l.html
+//@ has foo/fn.m.html
+//@ has foo/fn.n.html
+//@ has foo/fn.o.html
+//@ has foo/fn.test_44731_0.html
+//@ has foo/fn.test_44731_1.html
+//@ has foo/fn.test_44731_4.html
diff --git a/tests/rustdoc/impl/impl-trait-alias.rs b/tests/rustdoc/impl/impl-trait-alias.rs
new file mode 100644
index 00000000000..f7ecfffbf46
--- /dev/null
+++ b/tests/rustdoc/impl/impl-trait-alias.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+
+trait MyTrait {}
+impl MyTrait for i32 {}
+
+//@ hasraw impl_trait_alias/type.Foo.html 'Foo'
+/// debug type
+pub type Foo = impl MyTrait;
+
+//@ hasraw impl_trait_alias/fn.foo.html 'foo'
+/// debug function
+pub fn foo() -> Foo {
+    1
+}
diff --git a/tests/rustdoc/impl/impl-trait-precise-capturing.rs b/tests/rustdoc/impl/impl-trait-precise-capturing.rs
new file mode 100644
index 00000000000..3ec8c578013
--- /dev/null
+++ b/tests/rustdoc/impl/impl-trait-precise-capturing.rs
@@ -0,0 +1,26 @@
+//@ aux-build:precise-capturing.rs
+
+#![crate_name = "foo"]
+
+extern crate precise_capturing;
+
+//@ has foo/fn.two.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'b, 'a>"
+pub fn two<'a, 'b, 'c>() -> impl Sized + use<'b, 'a /* no 'c */> {}
+
+//@ has foo/fn.params.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'a, T, N>"
+pub fn params<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {}
+
+//@ has foo/fn.none.html '//section[@id="main-content"]//pre' "-> impl Sized + use<>"
+pub fn none() -> impl Sized + use<> {}
+
+//@ has foo/fn.first.html '//section[@id="main-content"]//pre' "-> impl use<> + Sized"
+pub fn first() -> impl use<> + Sized {}
+
+//@ has foo/fn.cross_crate_empty.html '//section[@id="main-content"]//pre' "-> impl Sized + use<>"
+pub use precise_capturing::cross_crate_empty;
+
+//@ matches foo/fn.cross_crate_missing.html '//section[@id="main-content"]//pre' "-> impl Sized$"
+pub use precise_capturing::cross_crate_missing;
+
+//@ has foo/fn.cross_crate_args.html '//section[@id="main-content"]//pre' "-> impl Sized + use<'a, T, N>"
+pub use precise_capturing::cross_crate_args;
diff --git a/tests/rustdoc/impl/impl-type-parameter-33592.rs b/tests/rustdoc/impl/impl-type-parameter-33592.rs
new file mode 100644
index 00000000000..ac5df460925
--- /dev/null
+++ b/tests/rustdoc/impl/impl-type-parameter-33592.rs
@@ -0,0 +1,14 @@
+// https://github.com/rust-lang/rust/issues/33592
+#![crate_name = "foo"]
+
+pub trait Foo<T> {}
+
+pub struct Bar;
+
+pub struct Baz;
+
+//@ has foo/trait.Foo.html '//h3[@class="code-header"]' 'impl Foo<i32> for Bar'
+impl Foo<i32> for Bar {}
+
+//@ has foo/trait.Foo.html '//h3[@class="code-header"]' 'impl<T> Foo<T> for Baz'
+impl<T> Foo<T> for Baz {}
diff --git a/tests/rustdoc/impl/implementor-stable-version.rs b/tests/rustdoc/impl/implementor-stable-version.rs
new file mode 100644
index 00000000000..cd4fa93f803
--- /dev/null
+++ b/tests/rustdoc/impl/implementor-stable-version.rs
@@ -0,0 +1,21 @@
+#![stable(feature = "bar", since = "3.3.3")]
+#![crate_name = "foo"]
+
+#![feature(staged_api)]
+
+#[stable(feature = "bar", since = "3.3.3")]
+pub trait Bar {}
+
+#[stable(feature = "baz", since = "3.3.3")]
+pub trait Baz {}
+
+#[stable(feature = "baz", since = "3.3.3")]
+pub struct Foo;
+
+//@ has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' '4.4.4'
+#[stable(feature = "foobar", since = "4.4.4")]
+impl Bar for Foo {}
+
+//@ has foo/trait.Baz.html '//div[@id="implementors-list"]//span[@class="since"]' '3.3.3'
+#[stable(feature = "foobaz", since = "3.3.3")]
+impl Baz for Foo {}
diff --git a/tests/rustdoc/impl/implementors-unstable-75588.rs b/tests/rustdoc/impl/implementors-unstable-75588.rs
new file mode 100644
index 00000000000..44a785c4ad9
--- /dev/null
+++ b/tests/rustdoc/impl/implementors-unstable-75588.rs
@@ -0,0 +1,18 @@
+//@ aux-build:realcore.rs
+//@ aux-build:real_gimli.rs
+
+// Ensure unstably exported traits have their Implementors sections.
+// https://github.com/rust-lang/rust/issues/75588
+
+#![crate_name = "foo"]
+#![feature(extremely_unstable_foo)]
+
+extern crate realcore;
+extern crate real_gimli;
+
+// issue #74672
+//@ !has foo/trait.Deref.html '//*[@id="impl-Deref-for-EndianSlice"]//h3[@class="code-header"]' 'impl Deref for EndianSlice'
+pub use realcore::Deref;
+
+//@ has foo/trait.Join.html '//*[@id="impl-Join-for-Foo"]//h3[@class="code-header"]' 'impl Join for Foo'
+pub use realcore::Join;
diff --git a/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs b/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs
new file mode 100644
index 00000000000..ba6ed427871
--- /dev/null
+++ b/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs
@@ -0,0 +1,15 @@
+//@ aux-build:issue-100204-aux.rs
+//@ build-aux-docs
+//@ ignore-cross-compile
+
+// https://github.com/rust-lang/rust/issues/100204
+#![crate_name="second"]
+
+extern crate first;
+
+pub mod prelude {}
+
+//@ has first/struct.Bot.html '//h4[@class="code-header"]' 'pub fn new() -> Bot'
+//@ has second/struct.Bot.html '//h4[@class="code-header"]' 'pub fn new() -> Bot'
+#[doc(inline)]
+pub use first::*;
diff --git a/tests/rustdoc/impl/manual_impl.rs b/tests/rustdoc/impl/manual_impl.rs
new file mode 100644
index 00000000000..281262bb40a
--- /dev/null
+++ b/tests/rustdoc/impl/manual_impl.rs
@@ -0,0 +1,77 @@
+//@ has manual_impl/trait.T.html
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the trait definition.'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+/// Docs associated with the trait definition.
+pub trait T {
+    /// Docs associated with the trait a_method definition.
+    fn a_method(&self) -> usize;
+
+    /// Docs associated with the trait b_method definition.
+    fn b_method(&self) -> usize {
+        self.a_method()
+    }
+
+    /// Docs associated with the trait c_method definition.
+    ///
+    /// There is another line
+    fn c_method(&self) -> usize {
+        self.a_method()
+    }
+}
+
+//@ has manual_impl/struct.S1.html '//*[@class="trait"]' 'T'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the S1 trait implementation.'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the S1 trait a_method implementation.'
+//@ !has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
+//@ has - '//div[@class="impl-items"]//div[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+//@ has - '//div[@class="impl-items"]//div[@class="docblock"]' 'Docs associated with the trait c_method definition.'
+//@ !has - '//*[@class="docblock"]' 'There is another line'
+//@ has - '//div[@class="impl-items"]//div[@class="docblock"]' 'Read more'
+pub struct S1(usize);
+
+/// Docs associated with the S1 trait implementation.
+impl T for S1 {
+    /// Docs associated with the S1 trait a_method implementation.
+    fn a_method(&self) -> usize {
+        self.0
+    }
+}
+
+//@ has manual_impl/struct.S2.html '//*[@class="trait"]' 'T'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait implementation.'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait a_method implementation.'
+//@ has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait c_method implementation.'
+//@ has - '//div[@class="impl-items"]//div[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+pub struct S2(usize);
+
+/// Docs associated with the S2 trait implementation.
+impl T for S2 {
+    /// Docs associated with the S2 trait a_method implementation.
+    fn a_method(&self) -> usize {
+        self.0
+    }
+
+    /// Docs associated with the S2 trait c_method implementation.
+    fn c_method(&self) -> usize {
+        5
+    }
+}
+
+//@ has manual_impl/struct.S3.html '//*[@class="trait"]' 'T'
+//@ has  - '//div[@class="docblock"]' 'Docs associated with the S3 trait implementation.'
+//@ has  - '//div[@class="docblock"]' 'Docs associated with the S3 trait b_method implementation.'
+//@ has - '//div[@class="impl-items"]//div[@class="docblock"]' 'Docs associated with the trait a_method definition.'
+pub struct S3(usize);
+
+/// Docs associated with the S3 trait implementation.
+impl T for S3 {
+    fn a_method(&self) -> usize {
+        self.0
+    }
+
+    /// Docs associated with the S3 trait b_method implementation.
+    fn b_method(&self) -> usize {
+        5
+    }
+}
diff --git a/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs b/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs
new file mode 100644
index 00000000000..cda828d3967
--- /dev/null
+++ b/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs
@@ -0,0 +1,14 @@
+//@ aux-build:issue-17476.rs
+//@ ignore-cross-compile
+// https://github.com/rust-lang/rust/issues/17476
+
+#![crate_name="issue_17476"]
+
+extern crate issue_17476;
+
+pub struct Foo;
+
+//@ has issue_17476/struct.Foo.html \
+//      '//*[@href="http://example.com/issue_17476/trait.Foo.html#method.foo"]' \
+//      'foo'
+impl issue_17476::Foo for Foo {}
diff --git a/tests/rustdoc/impl/module-impls.rs b/tests/rustdoc/impl/module-impls.rs
new file mode 100644
index 00000000000..b66721ecb13
--- /dev/null
+++ b/tests/rustdoc/impl/module-impls.rs
@@ -0,0 +1,5 @@
+#![crate_name = "foo"]
+
+pub use std::marker::Send;
+
+//@ !hasraw foo/index.html 'Implementations'
diff --git a/tests/rustdoc/impl/must_implement_one_of.rs b/tests/rustdoc/impl/must_implement_one_of.rs
new file mode 100644
index 00000000000..ab965bab356
--- /dev/null
+++ b/tests/rustdoc/impl/must_implement_one_of.rs
@@ -0,0 +1,10 @@
+#![crate_name = "c"]
+#![feature(rustc_attrs)]
+
+#[rustc_must_implement_one_of(a, b)]
+//@ matches c/trait.Trait.html '//*[@class="stab must_implement"]' \
+//      'At least one of the `a`, `b` methods is required.$'
+pub trait Trait {
+    fn a() {}
+    fn b() {}
+}
diff --git a/tests/rustdoc/impl/negative-impl-no-items.rs b/tests/rustdoc/impl/negative-impl-no-items.rs
new file mode 100644
index 00000000000..c628e542033
--- /dev/null
+++ b/tests/rustdoc/impl/negative-impl-no-items.rs
@@ -0,0 +1,26 @@
+// This test ensures that negative impls don't have items listed inside them.
+
+#![feature(negative_impls)]
+#![crate_name = "foo"]
+
+pub struct Thing;
+
+//@ has 'foo/struct.Thing.html'
+// We check the full path to ensure there is no `<details>` element.
+//@ has - '//div[@id="trait-implementations-list"]/section[@id="impl-Iterator-for-Thing"]/h3' \
+// 'impl !Iterator for Thing'
+impl !Iterator for Thing {}
+
+// This struct will allow us to compare both paths.
+pub struct Witness;
+
+//@ has 'foo/struct.Witness.html'
+//@ has - '//div[@id="trait-implementations-list"]/details//section[@id="impl-Iterator-for-Witness"]/h3' \
+// 'impl Iterator for Witness'
+impl Iterator for Witness {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        None
+    }
+}
diff --git a/tests/rustdoc/impl/negative-impl-sidebar.rs b/tests/rustdoc/impl/negative-impl-sidebar.rs
new file mode 100644
index 00000000000..1742dce1945
--- /dev/null
+++ b/tests/rustdoc/impl/negative-impl-sidebar.rs
@@ -0,0 +1,9 @@
+#![feature(negative_impls)]
+#![crate_name = "foo"]
+
+pub struct Foo;
+
+//@ has foo/struct.Foo.html
+//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#trait-implementations"]' 'Trait Implementations'
+//@ has - '//*[@class="sidebar-elems"]//section//a' '!Sync'
+impl !Sync for Foo {}
diff --git a/tests/rustdoc/impl/negative-impl.rs b/tests/rustdoc/impl/negative-impl.rs
new file mode 100644
index 00000000000..f057a749b72
--- /dev/null
+++ b/tests/rustdoc/impl/negative-impl.rs
@@ -0,0 +1,14 @@
+#![feature(negative_impls)]
+
+//@ matches negative_impl/struct.Alpha.html '//pre' "pub struct Alpha"
+pub struct Alpha;
+//@ matches negative_impl/struct.Bravo.html '//pre' "pub struct Bravo<B>"
+pub struct Bravo<B>(B);
+
+//@ matches negative_impl/struct.Alpha.html '//*[@class="impl"]//h3[@class="code-header"]' \
+// "impl !Send for Alpha"
+impl !Send for Alpha {}
+
+//@ matches negative_impl/struct.Bravo.html '//*[@class="impl"]//h3[@class="code-header"]' "\
+// impl<B> !Send for Bravo<B>"
+impl<B> !Send for Bravo<B> {}
diff --git a/tests/rustdoc/impl/return-impl-trait.rs b/tests/rustdoc/impl/return-impl-trait.rs
new file mode 100644
index 00000000000..175867d2204
--- /dev/null
+++ b/tests/rustdoc/impl/return-impl-trait.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+pub trait Backend {}
+
+impl Backend for () {}
+
+pub struct Module<T>(T);
+
+pub type BackendImpl = impl Backend;
+
+//@ has return_impl_trait/fn.make_module.html
+/// Documentation
+pub fn make_module() -> Module<BackendImpl> {
+    Module(())
+}
diff --git a/tests/rustdoc/impl/rustc-incoherent-impls.rs b/tests/rustdoc/impl/rustc-incoherent-impls.rs
new file mode 100644
index 00000000000..81a7025906b
--- /dev/null
+++ b/tests/rustdoc/impl/rustc-incoherent-impls.rs
@@ -0,0 +1,28 @@
+//@ aux-build:incoherent-impl-types.rs
+//@ build-aux-docs
+
+#![crate_name = "foo"]
+#![feature(rustc_attrs)]
+
+extern crate incoherent_impl_types;
+
+// The only way this actually shows up is if the type gets inlined.
+#[doc(inline)]
+pub use incoherent_impl_types::FooTrait;
+
+//@ has foo/trait.FooTrait.html
+//@ count - '//section[@id="method.do_something"]' 1
+impl dyn FooTrait {
+    #[rustc_allow_incoherent_impl]
+    pub fn do_something() {}
+}
+
+#[doc(inline)]
+pub use incoherent_impl_types::FooStruct;
+
+//@ has foo/struct.FooStruct.html
+//@ count - '//section[@id="method.do_something"]' 1
+impl FooStruct {
+    #[rustc_allow_incoherent_impl]
+    pub fn do_something() {}
+}
diff --git a/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs b/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs
new file mode 100644
index 00000000000..b0beb1bdfa0
--- /dev/null
+++ b/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs
@@ -0,0 +1,36 @@
+// test for `doc(hidden)` with impl parameters in the same crate.
+#![crate_name = "foo"]
+
+#[doc(hidden)]
+pub enum HiddenType {}
+
+#[doc(hidden)]
+pub trait HiddenTrait {}
+
+pub enum MyLibType {}
+
+//@ !has foo/enum.MyLibType.html '//*[@id="impl-From%3CHiddenType%3E"]' 'impl From<HiddenType> for MyLibType'
+impl From<HiddenType> for MyLibType {
+    fn from(it: HiddenType) -> MyLibType {
+        match it {}
+    }
+}
+
+pub struct T<T>(T);
+
+//@ !has foo/enum.MyLibType.html '//*[@id="impl-From%3CT%3CT%3CT%3CT%3CHiddenType%3E%3E%3E%3E%3E"]' 'impl From<T<T<T<T<HiddenType>>>>> for MyLibType'
+impl From<T<T<T<T<HiddenType>>>>> for MyLibType {
+    fn from(it: T<T<T<T<HiddenType>>>>) -> MyLibType {
+        todo!()
+    }
+}
+
+//@ !has foo/enum.MyLibType.html '//*[@id="impl-HiddenTrait"]' 'impl HiddenTrait for MyLibType'
+impl HiddenTrait for MyLibType {}
+
+//@ !has foo/struct.T.html '//*[@id="impl-From%3CMyLibType%3E"]' 'impl From<MyLibType> for T<T<T<T<HiddenType>>>>'
+impl From<MyLibType> for T<T<T<T<HiddenType>>>> {
+    fn from(it: MyLibType) -> T<T<T<T<HiddenType>>>> {
+        match it {}
+    }
+}
diff --git a/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs b/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs
new file mode 100644
index 00000000000..b1bf029cf84
--- /dev/null
+++ b/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs
@@ -0,0 +1,21 @@
+// https://github.com/rust-lang/rust/issues/78701
+#![crate_name = "foo"]
+
+// This test ensures that if a blanket impl has the same ID as another impl, it'll
+// link to the blanket impl and not the other impl. Basically, we're checking if
+// the ID is correctly derived.
+
+//@ has 'foo/struct.AnotherStruct.html'
+//@ count - '//*[@class="sidebar"]//a[@href="#impl-AnAmazingTrait-for-AnotherStruct%3C()%3E"]' 1
+//@ count - '//*[@class="sidebar"]//a[@href="#impl-AnAmazingTrait-for-T"]' 1
+
+pub trait Something {}
+
+pub trait AnAmazingTrait {}
+
+impl<T: Something> AnAmazingTrait for T {}
+
+pub struct AnotherStruct<T>(T);
+
+impl<T: Something> Something for AnotherStruct<T> {}
+impl AnAmazingTrait for AnotherStruct<()> {}
diff --git a/tests/rustdoc/impl/struct-implementations-title.rs b/tests/rustdoc/impl/struct-implementations-title.rs
new file mode 100644
index 00000000000..ca5b5c0ee20
--- /dev/null
+++ b/tests/rustdoc/impl/struct-implementations-title.rs
@@ -0,0 +1,9 @@
+#![crate_name = "foo"]
+
+pub struct Struc;
+
+//@ has foo/struct.Struc.html
+//@ has - '//*[@id="main-content"]/h2[@id="implementations"]' "Implementations"
+impl Struc {
+    pub const S: u64 = 0;
+}
diff --git a/tests/rustdoc/impl/trait-impl.rs b/tests/rustdoc/impl/trait-impl.rs
new file mode 100644
index 00000000000..c65eecc4edf
--- /dev/null
+++ b/tests/rustdoc/impl/trait-impl.rs
@@ -0,0 +1,45 @@
+pub trait Trait {
+    /// Some long docs here.
+    ///
+    /// These docs are long enough that a link will be added to the end.
+    fn a();
+
+    /// These docs contain a [reference link].
+    ///
+    /// [reference link]: https://example.com
+    fn b();
+
+    /// ```
+    /// This code block should not be in the output, but a Read more link should be generated
+    /// ```
+    fn c();
+
+    /// Escaped formatting a\*b\*c\* works
+    fn d();
+}
+
+pub struct Struct;
+
+impl Trait for Struct {
+    //@ has trait_impl/struct.Struct.html '//*[@id="method.a"]/../../div[@class="docblock"]' 'Some long docs'
+    //@ !has - '//*[@id="method.a"]/../../div[@class="docblock"]' 'link will be added'
+    //@ has - '//*[@id="method.a"]/../../div[@class="docblock"]/a' 'Read more'
+    //@ has - '//*[@id="method.a"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.a'
+    fn a() {}
+
+    //@ has - '//*[@id="method.b"]/../../div[@class="docblock"]' 'These docs contain'
+    //@ has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'reference link'
+    //@ has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'https://example.com'
+    fn b() {}
+
+    //@ !has - '//*[@id="method.c"]/../../div[@class="docblock"]' 'code block'
+    //@ has - '//*[@id="method.c"]/../../div[@class="docblock"]/a' 'Read more'
+    //@ has - '//*[@id="method.c"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.c'
+    fn c() {}
+
+    //@ has - '//*[@id="method.d"]/../../div[@class="docblock"]' 'Escaped formatting a*b*c* works'
+    //@ !has - '//*[@id="method.d"]/../../div[@class="docblock"]/em' ''
+    fn d() {}
+
+    //@ has - '//*[@id="impl-Trait-for-Struct"]/h3//a/@href' 'trait.Trait.html'
+}
diff --git a/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs b/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs
new file mode 100644
index 00000000000..8eb6d007525
--- /dev/null
+++ b/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs
@@ -0,0 +1,17 @@
+#![crate_name = "foo"]
+
+// https://github.com/rust-lang/rust/issues/45584
+
+pub trait Bar<T, U> {}
+
+//@ has 'foo/struct.Foo1.html'
+pub struct Foo1;
+//@ count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+//@ has - '//*[@class="impl"]' "impl Bar<Foo1, &'static Foo1> for Foo1"
+impl Bar<Foo1, &'static Foo1> for Foo1 {}
+
+//@ has 'foo/struct.Foo2.html'
+pub struct Foo2;
+//@ count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+//@ has - '//*[@class="impl"]' "impl Bar<&'static Foo2, Foo2> for u8"
+impl Bar<&'static Foo2, Foo2> for u8 {}
diff --git a/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs b/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs
new file mode 100644
index 00000000000..6d6e5e0a839
--- /dev/null
+++ b/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs
@@ -0,0 +1,17 @@
+//@ should-fail
+// https://github.com/rust-lang/rust/issues/96381
+
+#![allow(unused)]
+
+trait Foo<T>: Sized {
+    fn bar(i: i32, t: T, s: &Self) -> (T, i32);
+}
+
+impl Foo<usize> for () {
+    fn bar(i: _, t: _, s: _) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
+        (1, 2)
+    }
+}
+
+fn main() {}
diff --git a/tests/rustdoc/impl/universal-impl-trait.rs b/tests/rustdoc/impl/universal-impl-trait.rs
new file mode 100644
index 00000000000..b78d69c0690
--- /dev/null
+++ b/tests/rustdoc/impl/universal-impl-trait.rs
@@ -0,0 +1,55 @@
+#![crate_name = "foo"]
+
+use std::io::Read;
+use std::borrow::Borrow;
+
+//@ has foo/fn.foo.html
+//@ has - //pre 'foo('
+//@ matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
+//@ matchesraw - '_z: .+impl.+trait\.Copy\.html.+, impl.+trait\.Clone\.html'
+pub fn foo(_x: impl Clone, _y: i32, _z: (impl Copy, impl Clone)) {
+}
+
+pub trait Trait {
+    //@ has foo/trait.Trait.html
+    //@ hasraw - 'method</a>('
+    //@ matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+    fn method(&self, _x: impl std::fmt::Debug) {
+    }
+}
+
+pub struct S<T>(T);
+
+impl<T> S<T> {
+    //@ has foo/struct.S.html
+    //@ hasraw - 'bar</a>('
+    //@ matchesraw - '_bar: impl <a class="trait" href="[^"]+/trait\.Copy\.html"'
+    pub fn bar(_bar: impl Copy) {
+    }
+
+    //@ hasraw - 'baz</a>('
+    //@ matchesraw - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
+    pub fn baz(_baz: S<impl Clone>) {
+    }
+
+    //@ hasraw - 'qux</a>('
+    //@ matchesraw - 'trait\.Read\.html'
+    pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) {
+    }
+}
+
+//@ hasraw - 'method</a>('
+//@ matchesraw - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
+impl<T> Trait for S<T> {}
+
+//@ has foo/fn.much_universe.html
+//@ matchesraw - 'T:.+Borrow.+impl .+trait\.Trait\.html'
+//@ matchesraw - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
+//@ matchesraw - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
+pub fn much_universe<
+    T: Borrow<impl Trait>,
+    U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
+>(
+    _: impl Read + Clone,
+) {
+}
diff --git a/tests/rustdoc/impl/unneeded-trait-implementations-title.rs b/tests/rustdoc/impl/unneeded-trait-implementations-title.rs
new file mode 100644
index 00000000000..f7a97dfaaef
--- /dev/null
+++ b/tests/rustdoc/impl/unneeded-trait-implementations-title.rs
@@ -0,0 +1,5 @@
+#![crate_name = "foo"]
+
+pub struct Bar;
+
+//@ count foo/struct.Bar.html '//*[@id="implementations"]' 0