diff options
Diffstat (limited to 'tests/rustdoc/impl')
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 |
