summaryrefslogtreecommitdiffstats
path: root/tests/rustdoc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/rustdoc')
-rw-r--r--tests/rustdoc/alias-reexport.rs16
-rw-r--r--tests/rustdoc/alias-reexport2.rs16
-rw-r--r--tests/rustdoc/anchors.no_type_anchor2.html2
-rw-r--r--tests/rustdoc/assoc-consts.rs1
-rw-r--r--tests/rustdoc/auxiliary/alias-reexport.rs3
-rw-r--r--tests/rustdoc/auxiliary/alias-reexport2.rs12
-rw-r--r--tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html2
-rw-r--r--tests/rustdoc/decl-line-wrapping-empty-arg-list.rs12
-rw-r--r--tests/rustdoc/double-hyphen-to-dash.rs9
-rw-r--r--tests/rustdoc/files-creation-hidden.rs24
-rw-r--r--tests/rustdoc/files-creation-private.rs22
-rw-r--r--tests/rustdoc/generic-associated-types/gats.rs4
-rw-r--r--tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs23
-rw-r--r--tests/rustdoc/inline_cross/assoc-const-equality.rs8
-rw-r--r--tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs12
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs7
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs17
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs79
-rw-r--r--tests/rustdoc/inline_cross/dyn_trait.rs140
-rw-r--r--tests/rustdoc/intra-doc/issue-108459.rs37
-rw-r--r--tests/rustdoc/intra-doc/prim-precedence.rs2
-rw-r--r--tests/rustdoc/issue-109449-doc-hidden-reexports.rs143
-rw-r--r--tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs14
-rw-r--r--tests/rustdoc/issue-111249-file-creation.rs40
-rw-r--r--tests/rustdoc/issue-112515-impl-ty-alias.rs30
-rw-r--r--tests/rustdoc/redirect.rs2
-rw-r--r--tests/rustdoc/reexport-attr-merge.rs4
-rw-r--r--tests/rustdoc/reexport-doc-hidden-inside-private.rs16
-rw-r--r--tests/rustdoc/union-fields-html.rs11
-rw-r--r--tests/rustdoc/visibility.rs25
-rw-r--r--tests/rustdoc/where.SWhere_Echo_impl.html2
-rw-r--r--tests/rustdoc/where.SWhere_Simd_item-decl.html2
-rw-r--r--tests/rustdoc/where.alpha_trait_decl.html3
-rw-r--r--tests/rustdoc/where.bravo_trait_decl.html5
-rw-r--r--tests/rustdoc/where.charlie_fn_decl.html2
-rw-r--r--tests/rustdoc/where.golf_type_alias_decl.html2
-rw-r--r--tests/rustdoc/where.rs5
37 files changed, 724 insertions, 30 deletions
diff --git a/tests/rustdoc/alias-reexport.rs b/tests/rustdoc/alias-reexport.rs
new file mode 100644
index 000000000..a2a8e651c
--- /dev/null
+++ b/tests/rustdoc/alias-reexport.rs
@@ -0,0 +1,16 @@
+// aux-build:alias-reexport.rs
+// aux-build:alias-reexport2.rs
+
+#![crate_name = "foo"]
+#![feature(lazy_type_alias)]
+
+extern crate alias_reexport2;
+
+// @has 'foo/reexport/fn.foo.html'
+// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> Reexported'
+// @has 'foo/reexport/fn.foo2.html'
+// @has - '//*[@class="rust item-decl"]' 'pub fn foo2() -> Result<Reexported, ()>'
+// @has 'foo/reexport/type.Reexported.html'
+// @has - '//*[@class="rust item-decl"]' 'pub type Reexported = u8;'
+#[doc(inline)]
+pub use alias_reexport2 as reexport;
diff --git a/tests/rustdoc/alias-reexport2.rs b/tests/rustdoc/alias-reexport2.rs
new file mode 100644
index 000000000..85d3cdad9
--- /dev/null
+++ b/tests/rustdoc/alias-reexport2.rs
@@ -0,0 +1,16 @@
+// gate-test-lazy_type_alias
+// aux-build:alias-reexport.rs
+
+#![crate_name = "foo"]
+#![feature(lazy_type_alias)]
+
+extern crate alias_reexport;
+
+use alias_reexport::Reexported;
+
+// @has 'foo/fn.foo.html'
+// @has - '//*[@class="rust item-decl"]' 'pub fn foo() -> Reexported'
+pub fn foo() -> Reexported { 0 }
+// @has 'foo/fn.foo2.html'
+// @has - '//*[@class="rust item-decl"]' 'pub fn foo2() -> Result<Reexported, ()>'
+pub fn foo2() -> Result<Reexported, ()> { Ok(0) }
diff --git a/tests/rustdoc/anchors.no_type_anchor2.html b/tests/rustdoc/anchors.no_type_anchor2.html
index f8b59160f..71e93990e 100644
--- a/tests/rustdoc/anchors.no_type_anchor2.html
+++ b/tests/rustdoc/anchors.no_type_anchor2.html
@@ -1 +1 @@
-<section id="associatedtype.Y" class="associatedtype"><h4 class="code-header">type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section> \ No newline at end of file
+<section id="associatedtype.Y" class="associatedtype"><h4 class="code-header">pub type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section> \ No newline at end of file
diff --git a/tests/rustdoc/assoc-consts.rs b/tests/rustdoc/assoc-consts.rs
index 68a11c57b..08dfa879d 100644
--- a/tests/rustdoc/assoc-consts.rs
+++ b/tests/rustdoc/assoc-consts.rs
@@ -46,7 +46,6 @@ pub fn f(_: &(ToString + 'static)) {}
impl Bar {
// @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
// "const F: fn(_: &(dyn ToString + 'static))"
- // FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)"
pub const F: fn(_: &(ToString + 'static)) = f;
}
diff --git a/tests/rustdoc/auxiliary/alias-reexport.rs b/tests/rustdoc/auxiliary/alias-reexport.rs
new file mode 100644
index 000000000..14fafc02d
--- /dev/null
+++ b/tests/rustdoc/auxiliary/alias-reexport.rs
@@ -0,0 +1,3 @@
+#![feature(lazy_type_alias)]
+
+pub type Reexported = u8;
diff --git a/tests/rustdoc/auxiliary/alias-reexport2.rs b/tests/rustdoc/auxiliary/alias-reexport2.rs
new file mode 100644
index 000000000..9f6910572
--- /dev/null
+++ b/tests/rustdoc/auxiliary/alias-reexport2.rs
@@ -0,0 +1,12 @@
+#![feature(lazy_type_alias)]
+
+extern crate alias_reexport;
+
+pub use alias_reexport::Reexported;
+
+// @has 'foo/fn.foo.html'
+// @has - '//*[@class="docblock item-decl"]' 'pub fn foo() -> Reexported'
+pub fn foo() -> Reexported { 0 }
+// @has 'foo/fn.foo2.html'
+// @has - '//*[@class="docblock item-decl"]' 'pub fn foo2() -> Result<Reexported, ()>'
+pub fn foo2() -> Result<Reexported, ()> { Ok(0) }
diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html b/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html
new file mode 100644
index 000000000..29c08c5bd
--- /dev/null
+++ b/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html
@@ -0,0 +1,2 @@
+<pre class="rust item-decl"><code>pub fn create(
+) -&gt; <a class="struct" href="struct.Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000.html" title="struct decl_line_wrapping_empty_arg_list::Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000">Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000</a></code></pre> \ No newline at end of file
diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.rs b/tests/rustdoc/decl-line-wrapping-empty-arg-list.rs
new file mode 100644
index 000000000..4cfb87496
--- /dev/null
+++ b/tests/rustdoc/decl-line-wrapping-empty-arg-list.rs
@@ -0,0 +1,12 @@
+// Ensure that we don't add an extra line containing nothing but whitespace in between the two
+// parentheses of an empty argument list when line-wrapping a function declaration.
+
+// ignore-tidy-linelength
+
+pub struct Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000;
+
+// @has 'decl_line_wrapping_empty_arg_list/fn.create.html'
+// @snapshot decl - '//pre[@class="rust item-decl"]'
+pub fn create() -> Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000 {
+ loop {}
+}
diff --git a/tests/rustdoc/double-hyphen-to-dash.rs b/tests/rustdoc/double-hyphen-to-dash.rs
new file mode 100644
index 000000000..66905f90c
--- /dev/null
+++ b/tests/rustdoc/double-hyphen-to-dash.rs
@@ -0,0 +1,9 @@
+// This test ensures that `--` (double-hyphen) is correctly converted into `–` (dash).
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html' '//*[@class="desc docblock-short"]' '–'
+// @has 'foo/struct.Bar.html' '//*[@class="docblock"]' '–'
+
+/// --
+pub struct Bar;
diff --git a/tests/rustdoc/files-creation-hidden.rs b/tests/rustdoc/files-creation-hidden.rs
new file mode 100644
index 000000000..498d9cdae
--- /dev/null
+++ b/tests/rustdoc/files-creation-hidden.rs
@@ -0,0 +1,24 @@
+#![crate_name="foo"]
+
+// @files foo '["index.html", "all.html", "sidebar-items.js"]'
+// @!has "foo/struct.Foo.html"
+#[doc(hidden)]
+pub struct Foo;
+
+// @!has "foo/struct.Bar.html"
+pub use crate::Foo as Bar;
+
+// @!has "foo/struct.Baz.html"
+#[doc(hidden)]
+pub use crate::Foo as Baz;
+
+// @!has "foo/foo/index.html"
+#[doc(hidden)]
+pub mod foo {}
+
+// @!has "foo/bar/index.html"
+pub use crate::foo as bar;
+
+// @!has "foo/baz/index.html"
+#[doc(hidden)]
+pub use crate::foo as baz;
diff --git a/tests/rustdoc/files-creation-private.rs b/tests/rustdoc/files-creation-private.rs
new file mode 100644
index 000000000..e2fdbc068
--- /dev/null
+++ b/tests/rustdoc/files-creation-private.rs
@@ -0,0 +1,22 @@
+#![crate_name="foo"]
+
+// @files "foo" \
+// '["index.html", "all.html", "sidebar-items.js", "foo", "bar", "private", "struct.Bar.html"]'
+// @files "foo/bar" '["index.html", "sidebar-items.js"]'
+
+// @!has "foo/priv/index.html"
+// @!has "foo/priv/struct.Foo.html"
+mod private {
+ pub struct Foo;
+}
+
+// @has "foo/struct.Bar.html"
+pub use crate::private::Foo as Bar;
+
+// @!has "foo/foo/index.html"
+mod foo {
+ pub mod subfoo {}
+}
+
+// @has "foo/bar/index.html"
+pub use crate::foo::subfoo as bar;
diff --git a/tests/rustdoc/generic-associated-types/gats.rs b/tests/rustdoc/generic-associated-types/gats.rs
index 7ab82bb58..605176e5f 100644
--- a/tests/rustdoc/generic-associated-types/gats.rs
+++ b/tests/rustdoc/generic-associated-types/gats.rs
@@ -23,9 +23,9 @@ impl LendingIterator for () {
pub struct Infinite<T>(T);
// @has foo/trait.LendingIterator.html
-// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> where Self: 'a = &'a T"
+// @has - '//*[@id="associatedtype.Item-2"]//h4[@class="code-header"]' "type Item<'a> = &'a T where Self: 'a"
impl<T> LendingIterator for Infinite<T> {
- type Item<'a> where Self: 'a = &'a T;
+ type Item<'a> = &'a T where Self: 'a;
fn next<'a>(&'a self) -> Self::Item<'a> {
&self.0
diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs
new file mode 100644
index 000000000..e382940a4
--- /dev/null
+++ b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs
@@ -0,0 +1,23 @@
+// This test ensures that if a private item is re-exported with an intermediate
+// `#[doc(hidden)]` re-export, it'll still be inlined (and not include any attribute
+// from the doc hidden re-export.
+
+#![crate_name = "foo"]
+
+// @has 'foo/index.html'
+// There should only be one struct displayed.
+// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
+// @has - '//*[@id="main-content"]//a[@href="struct.Reexport.html"]' 'Reexport'
+// @has - '//*[@id="main-content"]//*[@class="desc docblock-short"]' 'Visible. Original.'
+
+mod private {
+ /// Original.
+ pub struct Bar3;
+}
+
+/// Hidden.
+#[doc(hidden)]
+pub use crate::private::Bar3;
+/// Visible.
+pub use self::Bar3 as Reexport;
diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc/inline_cross/assoc-const-equality.rs
new file mode 100644
index 000000000..1d3ce9e31
--- /dev/null
+++ b/tests/rustdoc/inline_cross/assoc-const-equality.rs
@@ -0,0 +1,8 @@
+// aux-crate:assoc_const_equality=assoc-const-equality.rs
+// edition:2021
+
+#![crate_name = "user"]
+
+// @has user/fn.accept.html
+// @has - '//pre[@class="rust item-decl"]' 'fn accept(_: impl Trait<K = 0>)'
+pub use assoc_const_equality::accept;
diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs
index db2491b87..74ceb697a 100644
--- a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs
+++ b/tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs
@@ -42,3 +42,15 @@ pub use aux::Main;
// @has main/trait.Aid.html
// @has - '//*[@id="associatedtype.Result"]' "type Result<'inter: 'src>"
pub use aux::Aid;
+
+// Below, ensure that we correctly display generic parameters and where-clauses on
+// associated types inside trait *impls*. More particularly, check that we don't render
+// any bounds (here `Self::Alias<T>: ...`) as item bounds unlike all the trait test cases above.
+
+// @has main/struct.Implementor.html
+// @has - '//*[@id="associatedtype.Alias"]' \
+// "type Alias<T: Eq> = T \
+// where \
+// String: From<T>, \
+// <Implementor as Implementee>::Alias<T>: From<<Implementor as Implementee>::Alias<T>>"
+pub use aux::Implementor;
diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs
new file mode 100644
index 000000000..6a25dcea6
--- /dev/null
+++ b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs
@@ -0,0 +1,7 @@
+#![feature(associated_const_equality)]
+
+pub fn accept(_: impl Trait<K = 0>) {}
+
+pub trait Trait {
+ const K: i32;
+}
diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
index 6644c8e41..551e97a2f 100644
--- a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
@@ -44,3 +44,20 @@ pub trait Helper {
pub trait Aid<'src> {
type Result<'inter: 'src>;
}
+
+pub trait Implementee {
+ type Alias<T: Eq>
+ where
+ String: From<T>;
+}
+
+pub struct Implementor;
+
+impl Implementee for Implementor {
+ type Alias<T: Eq> = T
+ where
+ String: From<T>,
+ // We will check that this bound doesn't get turned into an item bound since
+ // associated types in impls are not allowed to have any.
+ Self::Alias<T>: From<Self::Alias<T>>;
+}
diff --git a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
index 9ac2e3d96..df8853007 100644
--- a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool;
pub type Ty1<'obj> = dyn std::fmt::Display + 'obj;
@@ -6,12 +8,79 @@ pub type Ty2 = dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;
pub type Ty3<'s> = &'s dyn ToString;
-pub fn func0(_: &(dyn Fn() + '_)) {}
-
-pub fn func1<'func>(_: &(dyn Fn() + 'func)) {}
-
pub trait Container<'r> {
type Item<'a, 'ctx>;
}
-pub trait Shape<'a> {}
+// Trait-object types inside of a container type that has lifetime bounds ("wrapped").
+
+pub fn late_bound_wrapped_elided(_: &(dyn Fn() + '_)) {}
+pub fn late_bound_wrapped_late0<'f>(_: &mut (dyn Fn() + 'f)) {}
+pub fn late_bound_wrapped_defaulted0<'f>(_: &'f mut dyn Fn()) {}
+pub type EarlyBoundWrappedDefaulted0<'x> = std::cell::Ref<'x, dyn Trait>;
+pub type EarlyBoundWrappedDefaulted1<'x> = &'x dyn Trait;
+pub type EarlyBoundWrappedEarly<'x, 'y> = std::cell::Ref<'x, dyn Trait + 'y>;
+pub type EarlyBoundWrappedStatic<'x> = std::cell::Ref<'x, dyn Trait + 'static>;
+pub fn late_bound_wrapped_defaulted1<'l>(_: std::cell::Ref<'l, dyn Trait>) {}
+pub fn late_bound_wrapped_late1<'l, 'm>(_: std::cell::Ref<'l, dyn Trait + 'm>) {}
+pub fn late_bound_wrapped_early<'e, 'l>(_: std::cell::Ref<'l, dyn Trait + 'e>) where 'e: {} // `'e` is early-bound
+pub fn elided_bound_wrapped_defaulted(_: std::cell::Ref<'_, dyn Trait>) {}
+pub type StaticBoundWrappedDefaulted0 = std::cell::Ref<'static, dyn Trait>;
+pub type StaticBoundWrappedDefaulted1 = &'static dyn Trait;
+pub type AmbiguousBoundWrappedEarly0<'r, 's> = AmbiguousBoundWrapper<'s, 'r, dyn Trait + 's>;
+pub type AmbiguousBoundWrappedEarly1<'r, 's> = AmbiguousBoundWrapper<'s, 'r, dyn Trait + 'r>;
+pub type AmbiguousBoundWrappedStatic<'q> = AmbiguousBoundWrapper<'q, 'q, dyn Trait + 'static>;
+
+// Trait-object types inside of a container type that doesn't have lifetime bounds ("wrapped").
+
+pub type NoBoundsWrappedDefaulted = Box<dyn Trait>;
+pub type NoBoundsWrappedEarly<'e> = Box<dyn Trait + 'e>;
+pub fn no_bounds_wrapped_late<'l>(_: Box<dyn Trait + 'l>) {}
+pub fn no_bounds_wrapped_elided(_: Box<dyn Trait + '_>) {}
+
+// Trait-object types outside of a container (“bare”).
+
+pub type BareNoBoundsDefaulted = dyn Trait;
+pub type BareNoBoundsEarly<'p> = dyn Trait + 'p;
+pub type BareEarlyBoundDefaulted0<'u> = dyn EarlyBoundTrait0<'u>;
+pub type BareEarlyBoundDefaulted1 = dyn for<'any> EarlyBoundTrait0<'any>;
+pub type BareEarlyBoundDefaulted2<'w> = dyn EarlyBoundTrait1<'static, 'w>;
+pub type BareEarlyBoundEarly<'i, 'j> = dyn EarlyBoundTrait0<'i> + 'j;
+pub type BareEarlyBoundStatic<'i> = dyn EarlyBoundTrait0<'i> + 'static;
+pub type BareStaticBoundDefaulted = dyn StaticBoundTrait;
+pub type BareHigherRankedBoundDefaulted0 = dyn HigherRankedBoundTrait0;
+pub type BareHigherRankedBoundDefaulted1<'r> = dyn HigherRankedBoundTrait1<'r>;
+pub type BareAmbiguousBoundEarly0<'m, 'n> = dyn AmbiguousBoundTrait<'m, 'n> + 'm;
+pub type BareAmbiguousBoundEarly1<'m, 'n> = dyn AmbiguousBoundTrait<'m, 'n> + 'n;
+pub type BareAmbiguousBoundStatic<'o> = dyn AmbiguousBoundTrait<'o, 'o> + 'static;
+
+// Trait and container definitions.
+
+pub trait Trait {} // no bounds
+pub trait EarlyBoundTrait0<'b>: 'b {}
+pub trait EarlyBoundTrait1<'unused, 'c>: 'c {}
+pub trait StaticBoundTrait: 'static {}
+pub trait HigherRankedBoundTrait0 where for<'a> Self: 'a {}
+pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
+pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
+
+pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
+
+// Trait objects inside of another trait object, a trait bound or an associated type.
+
+pub trait Inner {}
+pub trait Outer<T: ?Sized> {}
+pub trait Base {
+ type Type<T: ?Sized>;
+}
+impl Base for () {
+ type Type<T: ?Sized> = ();
+}
+
+pub type NestedTraitObjects = dyn Outer<dyn Inner>;
+
+pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> {
+ o
+}
+
+pub type AssocTy = <() as Base>::Type<dyn Inner>;
diff --git a/tests/rustdoc/inline_cross/dyn_trait.rs b/tests/rustdoc/inline_cross/dyn_trait.rs
index 649d98f71..679972f03 100644
--- a/tests/rustdoc/inline_cross/dyn_trait.rs
+++ b/tests/rustdoc/inline_cross/dyn_trait.rs
@@ -1,31 +1,145 @@
#![crate_name = "user"]
+// In each test case, we include the trailing semicolon to ensure that nothing extra comes
+// after the type like an unwanted outlives-bound.
+
// aux-crate:dyn_trait=dyn_trait.rs
// edition:2021
// @has user/type.Ty0.html
-// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static"
-// FIXME(fmease): Hide default lifetime bound `'static`
+// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool;"
pub use dyn_trait::Ty0;
// @has user/type.Ty1.html
-// @has - '//*[@class="rust item-decl"]//code' "dyn Display + 'obj"
+// @has - '//*[@class="rust item-decl"]//code' "dyn Display + 'obj;"
pub use dyn_trait::Ty1;
// @has user/type.Ty2.html
-// @has - '//*[@class="rust item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>"
+// @has - '//*[@class="rust item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;"
pub use dyn_trait::Ty2;
// @has user/type.Ty3.html
-// @has - '//*[@class="rust item-decl"]//code' "&'s (dyn ToString + 's)"
-// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString"
+// @has - '//*[@class="rust item-decl"]//code' "&'s dyn ToString;"
pub use dyn_trait::Ty3;
-// @has user/fn.func0.html
-// @has - '//pre[@class="rust item-decl"]' "func0(_: &dyn Fn())"
-// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))"
-pub use dyn_trait::func0;
+// Below we check if we correctly elide trait-object lifetime bounds if they coincide with their
+// default (known as "object lifetime default" or "default trait object lifetime").
+
+// @has user/fn.lbwel.html
+// @has - '//pre[@class="rust item-decl"]' "lbwel(_: &dyn Fn())"
+pub use dyn_trait::late_bound_wrapped_elided as lbwel;
+// @has user/fn.lbwl0.html
+// has - '//pre[@class="rust item-decl"]' "lbwl0<'f>(_: &mut (dyn Fn() + 'f))"
+pub use dyn_trait::late_bound_wrapped_late0 as lbwl0;
+// @has user/fn.lbwd0.html
+// has - '//pre[@class="rust item-decl"]' "lbwd0<'f>(_: &'f mut dyn Fn())"
+pub use dyn_trait::late_bound_wrapped_defaulted0 as lbwd0;
+// @has user/type.EarlyBoundWrappedDefaulted0.html
+// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait>;"
+pub use dyn_trait::EarlyBoundWrappedDefaulted0;
+// @has user/type.EarlyBoundWrappedDefaulted1.html
+// @has - '//*[@class="rust item-decl"]//code' "&'x dyn Trait;"
+pub use dyn_trait::EarlyBoundWrappedDefaulted1;
+// @has user/type.EarlyBoundWrappedEarly.html
+// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait + 'y>"
+pub use dyn_trait::EarlyBoundWrappedEarly;
+// @has user/type.EarlyBoundWrappedStatic.html
+// @has - '//*[@class="rust item-decl"]//code' "Ref<'x, dyn Trait + 'static>"
+pub use dyn_trait::EarlyBoundWrappedStatic;
+// @has user/fn.lbwd1.html
+// @has - '//pre[@class="rust item-decl"]' "lbwd1<'l>(_: Ref<'l, dyn Trait>)"
+pub use dyn_trait::late_bound_wrapped_defaulted1 as lbwd1;
+// @has user/fn.lbwl1.html
+// @has - '//pre[@class="rust item-decl"]' "lbwl1<'l, 'm>(_: Ref<'l, dyn Trait + 'm>)"
+pub use dyn_trait::late_bound_wrapped_late1 as lbwl1;
+// @has user/fn.lbwe.html
+// @has - '//pre[@class="rust item-decl"]' "lbwe<'e, 'l>(_: Ref<'l, dyn Trait + 'e>)"
+pub use dyn_trait::late_bound_wrapped_early as lbwe;
+// @has user/fn.ebwd.html
+// @has - '//pre[@class="rust item-decl"]' "ebwd(_: Ref<'_, dyn Trait>)"
+pub use dyn_trait::elided_bound_wrapped_defaulted as ebwd;
+// @has user/type.StaticBoundWrappedDefaulted0.html
+// @has - '//*[@class="rust item-decl"]//code' "Ref<'static, dyn Trait>;"
+pub use dyn_trait::StaticBoundWrappedDefaulted0;
+// @has user/type.StaticBoundWrappedDefaulted1.html
+// @has - '//*[@class="rust item-decl"]//code' "&'static dyn Trait;"
+pub use dyn_trait::StaticBoundWrappedDefaulted1;
+// @has user/type.AmbiguousBoundWrappedEarly0.html
+// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'s, 'r, dyn Trait + 's>;"
+pub use dyn_trait::AmbiguousBoundWrappedEarly0;
+// @has user/type.AmbiguousBoundWrappedEarly1.html
+// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'s, 'r, dyn Trait + 'r>;"
+pub use dyn_trait::AmbiguousBoundWrappedEarly1;
+// @has user/type.AmbiguousBoundWrappedStatic.html
+// @has - '//*[@class="rust item-decl"]//code' "AmbiguousBoundWrapper<'q, 'q, dyn Trait + 'static>;"
+pub use dyn_trait::AmbiguousBoundWrappedStatic;
+
+// @has user/type.NoBoundsWrappedDefaulted.html
+// @has - '//*[@class="rust item-decl"]//code' "Box<dyn Trait, Global>;"
+pub use dyn_trait::NoBoundsWrappedDefaulted;
+// @has user/type.NoBoundsWrappedEarly.html
+// @has - '//*[@class="rust item-decl"]//code' "Box<dyn Trait + 'e, Global>;"
+pub use dyn_trait::NoBoundsWrappedEarly;
+// @has user/fn.nbwl.html
+// @has - '//pre[@class="rust item-decl"]' "nbwl<'l>(_: Box<dyn Trait + 'l, Global>)"
+pub use dyn_trait::no_bounds_wrapped_late as nbwl;
+// @has user/fn.nbwel.html
+// @has - '//pre[@class="rust item-decl"]' "nbwel(_: Box<dyn Trait + '_, Global>)"
+// NB: It might seem counterintuitive to display the explicitly elided lifetime `'_` here instead of
+// eliding it but this behavior is correct: The default is `'static` here which != `'_`.
+pub use dyn_trait::no_bounds_wrapped_elided as nbwel;
+
+// @has user/type.BareNoBoundsDefaulted.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn Trait;"
+pub use dyn_trait::BareNoBoundsDefaulted;
+// @has user/type.BareNoBoundsEarly.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn Trait + 'p;"
+pub use dyn_trait::BareNoBoundsEarly;
+// @has user/type.BareEarlyBoundDefaulted0.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'u>;"
+pub use dyn_trait::BareEarlyBoundDefaulted0;
+// @has user/type.BareEarlyBoundDefaulted1.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn for<'any> EarlyBoundTrait0<'any>;"
+pub use dyn_trait::BareEarlyBoundDefaulted1;
+// @has user/type.BareEarlyBoundDefaulted2.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait1<'static, 'w>;"
+pub use dyn_trait::BareEarlyBoundDefaulted2;
+// @has user/type.BareEarlyBoundEarly.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'i> + 'j;"
+pub use dyn_trait::BareEarlyBoundEarly;
+// @has user/type.BareEarlyBoundStatic.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn EarlyBoundTrait0<'i> + 'static;"
+pub use dyn_trait::BareEarlyBoundStatic;
+// @has user/type.BareStaticBoundDefaulted.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn StaticBoundTrait;"
+pub use dyn_trait::BareStaticBoundDefaulted;
+// @has user/type.BareHigherRankedBoundDefaulted0.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn HigherRankedBoundTrait0;"
+pub use dyn_trait::BareHigherRankedBoundDefaulted0;
+// @has user/type.BareHigherRankedBoundDefaulted1.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn HigherRankedBoundTrait1<'r>;"
+pub use dyn_trait::BareHigherRankedBoundDefaulted1;
+// @has user/type.BareAmbiguousBoundEarly0.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'m, 'n> + 'm;"
+pub use dyn_trait::BareAmbiguousBoundEarly0;
+// @has user/type.BareAmbiguousBoundEarly1.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'m, 'n> + 'n;"
+pub use dyn_trait::BareAmbiguousBoundEarly1;
+// @has user/type.BareAmbiguousBoundStatic.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
+pub use dyn_trait::BareAmbiguousBoundStatic;
+
+// Regression test for issue #115179:
+
+// @has user/type.NestedTraitObjects.html
+// @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;"
+pub use dyn_trait::NestedTraitObjects;
+
+// @has user/fn.apit_rpit.html
+// @has - '//pre[@class="rust item-decl"]' \
+// "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>"
+pub use dyn_trait::apit_rpit;
-// @has user/fn.func1.html
-// @has - '//pre[@class="rust item-decl"]' "func1<'func>(_: &(dyn Fn() + 'func))"
-pub use dyn_trait::func1;
+// @has user/type.AssocTy.html
+// @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>"
+pub use dyn_trait::AssocTy;
diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/issue-108459.rs
new file mode 100644
index 000000000..eb1c7a05e
--- /dev/null
+++ b/tests/rustdoc/intra-doc/issue-108459.rs
@@ -0,0 +1,37 @@
+#![deny(rustdoc::broken_intra_doc_links)]
+
+pub struct S;
+pub mod char {}
+
+// Ensure this doesn't ICE due to trying to slice off non-existent backticks from "S"
+
+/// See [S] and [`S`]
+pub struct MyStruct1;
+
+// Ensure that link texts are replaced correctly even if there are multiple links with
+// the same target but different text
+
+/// See also [crate::char] and [mod@char] and [prim@char]
+// @has issue_108459/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char'
+// @has - '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct2;
+
+/// See also [mod@char] and [prim@char] and [crate::char]
+// @has issue_108459/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char'
+// @has - '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct3;
+
+// Ensure that links are correct even if there are multiple links with the same text but
+// different targets
+
+/// See also [char][mod@char] and [char][prim@char]
+// @has issue_108459/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct4;
+
+/// See also [char][prim@char] and [char][crate::char]
+// @has issue_108459/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct5;
diff --git a/tests/rustdoc/intra-doc/prim-precedence.rs b/tests/rustdoc/intra-doc/prim-precedence.rs
index 25625b952..c5a64e42a 100644
--- a/tests/rustdoc/intra-doc/prim-precedence.rs
+++ b/tests/rustdoc/intra-doc/prim-precedence.rs
@@ -12,5 +12,5 @@ pub struct MyString;
/// See also [crate::char] and [mod@char]
// @has prim_precedence/struct.MyString2.html '//*[@href="char/index.html"]' 'crate::char'
-// @has - '//*[@href="char/index.html"]' 'mod@char'
+// @has - '//*[@href="char/index.html"]' 'char'
pub struct MyString2;
diff --git a/tests/rustdoc/issue-109449-doc-hidden-reexports.rs b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
new file mode 100644
index 000000000..b0c225401
--- /dev/null
+++ b/tests/rustdoc/issue-109449-doc-hidden-reexports.rs
@@ -0,0 +1,143 @@
+// Test to enforce rules over re-exports inlining from
+// <https://github.com/rust-lang/rust/issues/109449>.
+
+#![crate_name = "foo"]
+
+mod private_module {
+ #[doc(hidden)]
+ pub struct Public;
+ #[doc(hidden)]
+ pub type Bar = ();
+}
+
+#[doc(hidden)]
+mod module {
+ pub struct Public2;
+ pub type Bar2 = ();
+}
+
+#[doc(hidden)]
+pub type Bar3 = ();
+#[doc(hidden)]
+pub struct FooFoo;
+
+// Checking that re-exporting a `#[doc(hidden)]` item will NOT inline it.
+pub mod single_reexport {
+ // @has 'foo/single_reexport/index.html'
+
+ // First we check that we have 4 type aliases.
+ // @count - '//*[@id="main-content"]/*[@class="item-table"]//code' 4
+
+ // Then we check that we have the correct link for each re-export.
+
+ // @!has - '//*[@href="struct.Foo.html"]' 'Foo'
+ // @has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
+ pub use crate::private_module::Public as Foo;
+ // @!has - '//*[@href="type.Foo2.html"]' 'Foo2'
+ // @has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;'
+ pub use crate::private_module::Bar as Foo2;
+ // @!has - '//*[@href="type.Yo.html"]' 'Yo'
+ // @has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;'
+ pub use crate::Bar3 as Yo;
+ // @!has - '//*[@href="struct.Yo2.html"]' 'Yo2'
+ // @has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;'
+ pub use crate::FooFoo as Yo2;
+
+ // Checking that each file is also created as expected.
+ // @!has 'foo/single_reexport/struct.Foo.html'
+ // @!has 'foo/single_reexport/type.Foo2.html'
+ // @!has 'foo/single_reexport/type.Yo.html'
+ // @!has 'foo/single_reexport/struct.Yo2.html'
+}
+
+// However, re-exporting an item inheriting `#[doc(hidden)]` will inline it.
+pub mod single_reexport_inherit_hidden {
+ // @has 'foo/single_reexport_inherit_hidden/index.html'
+
+ // @has - '//*[@href="struct.Foo3.html"]' 'Foo3'
+ pub use crate::module::Public2 as Foo3;
+ // @has - '//*[@href="type.Foo4.html"]' 'Foo4'
+ pub use crate::module::Bar2 as Foo4;
+
+ // @has 'foo/single_reexport_inherit_hidden/struct.Foo3.html'
+ // @has 'foo/single_reexport_inherit_hidden/type.Foo4.html'
+}
+
+pub mod single_reexport_no_inline {
+ // First we ensure that we only have re-exports and no inlined items.
+ // @has 'foo/single_reexport_no_inline/index.html'
+ // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
+ // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
+
+ // Now we check that we don't have links to the items, just `pub use`.
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;'
+ // @!has - '//*[@id="main-content"]//a' 'XFoo'
+ #[doc(no_inline)]
+ pub use crate::private_module::Public as XFoo;
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;'
+ // @!has - '//*[@id="main-content"]//a' 'Foo2'
+ #[doc(no_inline)]
+ pub use crate::private_module::Bar as Foo2;
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;'
+ // @!has - '//*[@id="main-content"]//a' 'Yo'
+ #[doc(no_inline)]
+ pub use crate::Bar3 as Yo;
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;'
+ // @!has - '//*[@id="main-content"]//a' 'Yo2'
+ #[doc(no_inline)]
+ pub use crate::FooFoo as Yo2;
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::module::Public2 as Foo3;'
+ // @!has - '//*[@id="main-content"]//a' 'Foo3'
+ #[doc(no_inline)]
+ pub use crate::module::Public2 as Foo3;
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::module::Bar2 as Foo4;'
+ // @!has - '//*[@id="main-content"]//a' 'Foo4'
+ #[doc(no_inline)]
+ pub use crate::module::Bar2 as Foo4;
+}
+
+// Checking that glob re-exports don't inline `#[doc(hidden)]` items.
+pub mod glob_reexport {
+ // With glob re-exports, we don't inline `#[doc(hidden)]` items so only `module` items
+ // should be inlined.
+ // @has 'foo/glob_reexport/index.html'
+ // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
+ // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
+ // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
+ // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Definitions'
+
+ // Now we check we have 1 re-export and 2 inlined items.
+ // If not item from a glob re-export is visible, we don't show the re-export.
+ // @!has - '//*[@id="main-content"]//*' 'pub use crate::private_module::*;'
+ pub use crate::private_module::*;
+ // @has - '//*[@id="main-content"]//*' 'pub use crate::*;'
+ pub use crate::*;
+ // This one should be inlined.
+ // @!has - '//*[@id="main-content"]//*' 'pub use crate::module::*;'
+ // @has - '//*[@id="main-content"]//a[@href="struct.Public2.html"]' 'Public2'
+ // @has - '//*[@id="main-content"]//a[@href="type.Bar2.html"]' 'Bar2'
+ // And we check that the two files were created too.
+ // @has 'foo/glob_reexport/struct.Public2.html'
+ // @has 'foo/glob_reexport/type.Bar2.html'
+ pub use crate::module::*;
+}
+
+mod private {
+ /// Original.
+ pub struct Bar3;
+}
+
+// Checking that `#[doc(hidden)]` re-exports documentation isn't generated.
+pub mod doc_hidden_reexport {
+ // @has 'foo/doc_hidden_reexport/index.html'
+ // Ensure there is only one item in this page and that it's a struct.
+ // @count - '//*[@class="item-name"]' 1
+ // @has - '//a[@class="struct"]' 'Reexport'
+ // Check that the `#[doc(hidden)]` re-export's attributes are not taken into account.
+ // @has - '//*[@class="desc docblock-short"]' 'Visible. Original.'
+ /// Hidden.
+ #[doc(hidden)]
+ pub use crate::private::Bar3;
+ /// Visible.
+ pub use self::Bar3 as Reexport;
+}
diff --git a/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs
index 8e1029a1c..65c26d6a8 100644
--- a/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs
+++ b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs
@@ -2,11 +2,17 @@
#![no_core]
#![crate_name = "foo"]
+// @files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \
+// 'visible']"
+// @files "foo/hidden" "['inner']"
+// @files "foo/hidden/inner" "['trait.Foo.html']"
+// @files "foo/visible" "['index.html', 'sidebar-items.js', 'trait.Foo.html']"
+
// @!has 'foo/hidden/index.html'
-// FIXME: add missing `@` for the two next tests once issue is fixed!
-// To be done in <https://github.com/rust-lang/rust/issues/111249>.
-// !has 'foo/hidden/inner/index.html'
-// !has 'foo/hidden/inner/trait.Foo.html'
+// @!has 'foo/hidden/inner/index.html'
+// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249
+// @has 'foo/hidden/inner/trait.Foo.html'
+// @matchesraw - '<meta http-equiv="refresh" content="0;URL=../../../foo/visible/trait.Foo.html">'
#[doc(hidden)]
pub mod hidden {
pub mod inner {
diff --git a/tests/rustdoc/issue-111249-file-creation.rs b/tests/rustdoc/issue-111249-file-creation.rs
new file mode 100644
index 000000000..afd65ddaf
--- /dev/null
+++ b/tests/rustdoc/issue-111249-file-creation.rs
@@ -0,0 +1,40 @@
+#![crate_name = "foo"]
+#![feature(no_core)]
+#![no_core]
+
+// @files "foo" "['all.html', 'visible', 'index.html', 'sidebar-items.js', 'hidden', \
+// 'struct.Bar.html']"
+// @files "foo/visible" "['trait.Foo.html', 'index.html', 'sidebar-items.js']"
+// @files "foo/hidden" "['inner']"
+// @files "foo/hidden/inner" "['trait.Foo.html']"
+
+// The following five should not fail!
+// @!has 'foo/hidden/index.html'
+// @!has 'foo/hidden/inner/index.html'
+// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249
+// @has 'foo/hidden/inner/trait.Foo.html'
+// @matchesraw - '<meta http-equiv="refresh" content="0;URL=../../../foo/visible/trait.Foo.html">'
+// @!has 'foo/hidden/inner/inner_hidden/index.html'
+// @!has 'foo/hidden/inner/inner_hidden/trait.HiddenFoo.html'
+#[doc(hidden)]
+pub mod hidden {
+ pub mod inner {
+ pub trait Foo {}
+
+ #[doc(hidden)]
+ pub mod inner_hidden {
+ pub trait HiddenFoo {}
+ }
+ }
+}
+
+// @has 'foo/visible/index.html'
+// @has 'foo/visible/trait.Foo.html'
+#[doc(inline)]
+pub use hidden::inner as visible;
+
+// @has 'foo/struct.Bar.html'
+// @count - '//*[@id="impl-Foo-for-Bar"]' 1
+pub struct Bar;
+
+impl visible::Foo for Bar {}
diff --git a/tests/rustdoc/issue-112515-impl-ty-alias.rs b/tests/rustdoc/issue-112515-impl-ty-alias.rs
new file mode 100644
index 000000000..161188ee5
--- /dev/null
+++ b/tests/rustdoc/issue-112515-impl-ty-alias.rs
@@ -0,0 +1,30 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/112515>.
+// It's to ensure that this code doesn't have infinite loop in rustdoc when
+// trying to retrive type alias implementations.
+
+// ignore-tidy-linelength
+
+pub type Boom = S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<S<u64, u8>, ()>, ()>, ()>, u8>, ()>, u8>, ()>, u8>, u8>, ()>, ()>, ()>, u8>, u8>, u8>, ()>, ()>, u8>, ()>, ()>, ()>, u8>, u8>, ()>, ()>, ()>, ()>, ()>, u8>, ()>, ()>, u8>, ()>, ()>, ()>, u8>, ()>, ()>, u8>, u8>, u8>, u8>, ()>, u8>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>, ()>;
+pub struct S<T, U>(T, U);
+
+pub trait A {}
+
+pub trait B<T> {
+ type P;
+}
+
+impl A for u64 {}
+
+impl<T, U> A for S<T, U> {}
+
+impl<T> B<u8> for S<T, ()>
+where
+ T: B<u8>,
+ <T as B<u8>>::P: A,
+{
+ type P = ();
+}
+
+impl<T: A, U, V> B<T> for S<U, V> {
+ type P = ();
+}
diff --git a/tests/rustdoc/redirect.rs b/tests/rustdoc/redirect.rs
index 5b7a76e1a..4fb81c23d 100644
--- a/tests/rustdoc/redirect.rs
+++ b/tests/rustdoc/redirect.rs
@@ -10,7 +10,9 @@ pub trait Foo {}
// @has - '//code' 'pub use reexp_stripped::Bar'
// @has - '//code/a' 'Bar'
// @has - '//a[@href="../reexp_stripped/hidden/struct.Bar.html"]' 'Bar'
+// FIXME: Should be `@!has`: https://github.com/rust-lang/rust/issues/111249
// @has reexp_stripped/hidden/struct.Bar.html
+// @matchesraw - '<meta http-equiv="refresh" content="0;URL=../../reexp_stripped/struct.Bar.html">'
// @has 'reexp_stripped/struct.Bar.html'
// @has - '//a[@href="struct.Bar.html"]' 'Bar'
#[doc(no_inline)]
diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs
index f6c23a136..6cc054e7a 100644
--- a/tests/rustdoc/reexport-attr-merge.rs
+++ b/tests/rustdoc/reexport-attr-merge.rs
@@ -19,9 +19,9 @@ pub use Foo1 as Foo2;
// First we ensure that only the reexport `Bar2` and the inlined struct `Bar`
// are inlined.
// @count - '//a[@class="struct"]' 2
-// Then we check that both `cfg` are displayed.
+// Then we check that `cfg` is displayed for base item, but not for intermediate re-exports.
// @has - '//*[@class="stab portability"]' 'foo'
-// @has - '//*[@class="stab portability"]' 'bar'
+// @!has - '//*[@class="stab portability"]' 'bar'
// And finally we check that the only element displayed is `Bar`.
// @has - '//a[@class="struct"]' 'Bar'
#[doc(inline)]
diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport-doc-hidden-inside-private.rs
new file mode 100644
index 000000000..e9d243d8a
--- /dev/null
+++ b/tests/rustdoc/reexport-doc-hidden-inside-private.rs
@@ -0,0 +1,16 @@
+// This test ensures that a re-export of `#[doc(hidden)]` item inside a private
+// module will still be displayed (the re-export, not the item).
+
+#![crate_name = "foo"]
+
+mod private_module {
+ #[doc(hidden)]
+ pub struct Public;
+}
+
+// @has 'foo/index.html'
+// @has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
+pub use crate::private_module::Public as Foo;
+// Glob re-exports with no visible items should not be displayed.
+// @count - '//*[@class="item-table"]/li' 1
+pub use crate::private_module::*;
diff --git a/tests/rustdoc/union-fields-html.rs b/tests/rustdoc/union-fields-html.rs
new file mode 100644
index 000000000..1ac01232c
--- /dev/null
+++ b/tests/rustdoc/union-fields-html.rs
@@ -0,0 +1,11 @@
+#![crate_name = "foo"]
+
+// @has 'foo/union.Union.html'
+// Checking that there is a whitespace after `:`.
+// @has - '//*[@id="structfield.a"]/code' 'a: u8'
+// @has - '//*[@id="structfield.b"]/code' 'b: u32'
+pub union Union {
+ pub a: u8,
+ /// tadam
+ pub b: u32,
+}
diff --git a/tests/rustdoc/visibility.rs b/tests/rustdoc/visibility.rs
index 4099b54f0..4f9b06fd7 100644
--- a/tests/rustdoc/visibility.rs
+++ b/tests/rustdoc/visibility.rs
@@ -1,6 +1,8 @@
// compile-flags: --document-private-items
#![crate_name = "foo"]
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
// @!has 'foo/index.html' '//a[@href="struct.FooPublic.html"]/..' 'FooPublic 🔒'
// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
@@ -103,3 +105,26 @@ impl PubTrait for FooPublic {
const CONST: usize = 0;
fn function() {}
}
+
+pub struct Assoc;
+
+// @has foo/struct.Assoc.html
+impl Assoc {
+ // @has - '//*[@id="associatedtype.TypePub"]' 'pub type TypePub'
+ pub type TypePub = usize;
+
+ // @has - '//*[@id="associatedtype.TypePriv"]' 'pub(crate) type TypePriv'
+ type TypePriv = usize;
+
+ // @has - '//*[@id="associatedconstant.CONST_PUB"]' 'pub const CONST_PUB'
+ pub const CONST_PUB: usize = 0;
+
+ // @has - '//*[@id="associatedconstant.CONST_PRIV"]' 'pub(crate) const CONST_PRIV'
+ const CONST_PRIV: usize = 0;
+
+ // @has - '//*[@id="method.function_pub"]' 'pub fn function_pub()'
+ pub fn function_pub() {}
+
+ // @has - '//*[@id="method.function_priv"]' 'pub(crate) fn function_priv()'
+ fn function_priv() {}
+}
diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc/where.SWhere_Echo_impl.html
new file mode 100644
index 000000000..7517eb090
--- /dev/null
+++ b/tests/rustdoc/where.SWhere_Echo_impl.html
@@ -0,0 +1,2 @@
+<h3 class="code-header">impl&lt;D&gt; <a class="struct" href="struct.Delta.html" title="struct foo::Delta">Delta</a>&lt;D&gt;<span class="where fmt-newline">where
+ D: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></h3> \ No newline at end of file
diff --git a/tests/rustdoc/where.SWhere_Simd_item-decl.html b/tests/rustdoc/where.SWhere_Simd_item-decl.html
index ef4294c8f..3e72ba2b7 100644
--- a/tests/rustdoc/where.SWhere_Simd_item-decl.html
+++ b/tests/rustdoc/where.SWhere_Simd_item-decl.html
@@ -1,3 +1,3 @@
<pre class="rust item-decl"><code>pub struct Simd&lt;T&gt;(_)
<span class="where">where
- T: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code></pre> \ No newline at end of file
+ T: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code></pre>
diff --git a/tests/rustdoc/where.alpha_trait_decl.html b/tests/rustdoc/where.alpha_trait_decl.html
new file mode 100644
index 000000000..a7700055c
--- /dev/null
+++ b/tests/rustdoc/where.alpha_trait_decl.html
@@ -0,0 +1,3 @@
+<code>pub struct Alpha&lt;A&gt;(_)
+<span class="where">where
+ A: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code> \ No newline at end of file
diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc/where.bravo_trait_decl.html
new file mode 100644
index 000000000..00524201a
--- /dev/null
+++ b/tests/rustdoc/where.bravo_trait_decl.html
@@ -0,0 +1,5 @@
+<code>pub trait Bravo&lt;B&gt;<span class="where fmt-newline">where
+ B: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span>{
+ // Required method
+ fn <a href="#tymethod.get" class="fn">get</a>(&amp;self, B: B);
+}</code> \ No newline at end of file
diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc/where.charlie_fn_decl.html
new file mode 100644
index 000000000..8e3bc8b01
--- /dev/null
+++ b/tests/rustdoc/where.charlie_fn_decl.html
@@ -0,0 +1,2 @@
+<code>pub fn charlie&lt;C&gt;()<span class="where fmt-newline">where
+ C: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></code> \ No newline at end of file
diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc/where.golf_type_alias_decl.html
new file mode 100644
index 000000000..8da5402f9
--- /dev/null
+++ b/tests/rustdoc/where.golf_type_alias_decl.html
@@ -0,0 +1,2 @@
+<code>pub type Golf&lt;T&gt;<span class="where fmt-newline">where
+ T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span> = <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>;</code> \ No newline at end of file
diff --git a/tests/rustdoc/where.rs b/tests/rustdoc/where.rs
index 8b8a126e8..2aa9c8b54 100644
--- a/tests/rustdoc/where.rs
+++ b/tests/rustdoc/where.rs
@@ -5,16 +5,20 @@ use std::io::Lines;
pub trait MyTrait { fn dummy(&self) { } }
// @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_) where A: MyTrait"
+// @snapshot alpha_trait_decl - '//*[@class="rust item-decl"]/code'
pub struct Alpha<A>(A) where A: MyTrait;
// @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B>where B: MyTrait"
+// @snapshot bravo_trait_decl - '//*[@class="rust item-decl"]/code'
pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
// @has foo/fn.charlie.html '//pre' "pub fn charlie<C>()where C: MyTrait"
+// @snapshot charlie_fn_decl - '//*[@class="rust item-decl"]/code'
pub fn charlie<C>() where C: MyTrait {}
pub struct Delta<D>(D);
// @has foo/struct.Delta.html '//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<D> Delta<D>where D: MyTrait"
+// @snapshot SWhere_Echo_impl - '//*[@id="impl-Delta%3CD%3E"]/h3[@class="code-header"]'
impl<D> Delta<D> where D: MyTrait {
pub fn delta() {}
}
@@ -65,4 +69,5 @@ impl<F> MyTrait for Foxtrot<F>where F: MyTrait {}
// @has foo/type.Golf.html '//pre[@class="rust item-decl"]' \
// "type Golf<T>where T: Clone, = (T, T)"
+// @snapshot golf_type_alias_decl - '//*[@class="rust item-decl"]/code'
pub type Golf<T> where T: Clone = (T, T);