diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/rustdoc/intra-doc | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/rustdoc/intra-doc')
80 files changed, 1489 insertions, 0 deletions
diff --git a/src/test/rustdoc/intra-doc/anchors.rs b/src/test/rustdoc/intra-doc/anchors.rs new file mode 100644 index 000000000..3d4c46496 --- /dev/null +++ b/src/test/rustdoc/intra-doc/anchors.rs @@ -0,0 +1,24 @@ +/// I want... +/// +/// # Anchor! +pub struct Something; + +// @has anchors/struct.SomeOtherType.html +// @has - '//a/@href' 'struct.Something.html#Anchor!' + +/// I want... +/// +/// To link to [Something#Anchor!] +pub struct SomeOtherType; + +/// Primitives? +/// +/// [u32#hello] +// @has anchors/fn.x.html +// @has - '//a/@href' '{{channel}}/std/primitive.u32.html#hello' +pub fn x() {} + +/// [prim@usize#x] +// @has anchors/usize/index.html +// @has - '//a/@href' '{{channel}}/std/primitive.usize.html#x' +pub mod usize {} diff --git a/src/test/rustdoc/intra-doc/associated-defaults.rs b/src/test/rustdoc/intra-doc/associated-defaults.rs new file mode 100644 index 000000000..c7e66c826 --- /dev/null +++ b/src/test/rustdoc/intra-doc/associated-defaults.rs @@ -0,0 +1,26 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![feature(associated_type_defaults)] + +pub trait TraitWithDefault { + type T = usize; + fn f() -> Self::T { + 0 + } +} + +/// Link to [UsesDefaults::T] and [UsesDefaults::f] +// @has 'associated_defaults/struct.UsesDefaults.html' '//a[@href="struct.UsesDefaults.html#associatedtype.T"]' 'UsesDefaults::T' +// @has 'associated_defaults/struct.UsesDefaults.html' '//a[@href="struct.UsesDefaults.html#method.f"]' 'UsesDefaults::f' +pub struct UsesDefaults; +impl TraitWithDefault for UsesDefaults {} + +/// Link to [OverridesDefaults::T] and [OverridesDefaults::f] +// @has 'associated_defaults/struct.OverridesDefaults.html' '//a[@href="struct.OverridesDefaults.html#associatedtype.T"]' 'OverridesDefaults::T' +// @has 'associated_defaults/struct.OverridesDefaults.html' '//a[@href="struct.OverridesDefaults.html#method.f"]' 'OverridesDefaults::f' +pub struct OverridesDefaults; +impl TraitWithDefault for OverridesDefaults { + type T = bool; + fn f() -> bool { + true + } +} diff --git a/src/test/rustdoc/intra-doc/associated-items.rs b/src/test/rustdoc/intra-doc/associated-items.rs new file mode 100644 index 000000000..0b958eb8e --- /dev/null +++ b/src/test/rustdoc/intra-doc/associated-items.rs @@ -0,0 +1,68 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// [`std::collections::BTreeMap::into_iter`] +/// [`String::from`] is ambiguous as to which `From` impl +/// [Vec::into_iter()] uses a disambiguator +// @has 'associated_items/fn.foo.html' '//a[@href="{{channel}}/alloc/collections/btree/map/struct.BTreeMap.html#method.into_iter"]' 'std::collections::BTreeMap::into_iter' +// @has 'associated_items/fn.foo.html' '//a[@href="{{channel}}/alloc/string/struct.String.html#method.from"]' 'String::from' +// @has 'associated_items/fn.foo.html' '//a[@href="{{channel}}/alloc/vec/struct.Vec.html#method.into_iter"]' 'Vec::into_iter' +pub fn foo() {} + +/// Link to [MyStruct], [link from struct][MyStruct::method], [MyStruct::clone], [MyStruct::Input] +// @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html"]' 'MyStruct' +// @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from struct' +// @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.clone"]' 'MyStruct::clone' +// @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#associatedtype.Input"]' 'MyStruct::Input' +pub struct MyStruct { foo: () } + +impl Clone for MyStruct { + fn clone(&self) -> Self { + MyStruct + } +} + +pub trait T { + type Input; + fn method(i: Self::Input); +} + +impl T for MyStruct { + type Input = usize; + + /// [link from method][MyStruct::method] on method + // @has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from method' + fn method(i: usize) { + } +} + +/// Ambiguity between which trait to use +pub trait T1 { + fn ambiguous_method(); +} + +pub trait T2 { + fn ambiguous_method(); +} + +/// Link to [S::ambiguous_method] +// FIXME: there is no way to disambiguate these. +// Since we have `#[deny(intra_doc_failure)]`, we still know it was one or the other. +pub struct S; + +impl T1 for S { + fn ambiguous_method() {} +} + +impl T2 for S { + fn ambiguous_method() {} +} + +// @has associated_items/enum.MyEnum.html '//a/@href' 'enum.MyEnum.html#variant.MyVariant' +/// Link to [MyEnumAlias::MyVariant] +pub enum MyEnum { + MyVariant, +} + +pub type MyEnumAlias = MyEnum; + +fn main() {} diff --git a/src/test/rustdoc/intra-doc/auxiliary/empty.rs b/src/test/rustdoc/intra-doc/auxiliary/empty.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/empty.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/rustdoc/intra-doc/auxiliary/empty2.rs b/src/test/rustdoc/intra-doc/auxiliary/empty2.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/empty2.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs b/src/test/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs new file mode 100644 index 000000000..d9a08cb41 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs @@ -0,0 +1,28 @@ +// no-prefer-dynamic + +#![feature(lang_items, rustc_attrs)] +#![crate_type = "rlib"] +#![no_std] + +pub struct DerefsToF64(f64); + +impl core::ops::Deref for DerefsToF64 { + type Target = f64; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +mod inner { + impl f64 { + /// [f64::clone] + #[rustc_allow_incoherent_impl] + pub fn method() {} + } +} + +#[lang = "eh_personality"] +fn foo() {} + +#[panic_handler] +fn bar(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs b/src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs new file mode 100644 index 000000000..ee4138b68 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs @@ -0,0 +1,11 @@ +#[derive(Clone)] +pub struct PublicStruct; + +mod inner { + use super::PublicStruct; + + impl PublicStruct { + /// [PublicStruct::clone] + pub fn method() {} + } +} diff --git a/src/test/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs b/src/test/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs new file mode 100644 index 000000000..db3bb38ad --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs @@ -0,0 +1,3 @@ +#![crate_name="inner"] + +//! ooh, i'm a rebel just for [kicks] diff --git a/src/test/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs b/src/test/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs new file mode 100644 index 000000000..a4db2ffc4 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs @@ -0,0 +1,4 @@ +#![crate_name = "inner"] + +/// Documentation, including a link to [std::ptr] +pub fn f() {} diff --git a/src/test/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs b/src/test/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs new file mode 100644 index 000000000..fc51995a9 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs @@ -0,0 +1,6 @@ +#![crate_name = "inner"] + +/// Links to [f()] +pub struct Inner; + +pub fn f() {} diff --git a/src/test/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs b/src/test/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs new file mode 100644 index 000000000..6142dcda9 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs @@ -0,0 +1,6 @@ +pub trait ThisTrait { + fn asdf(&self); + + /// let's link to [`asdf`](ThisTrait::asdf) + fn qwop(&self); +} diff --git a/src/test/rustdoc/intra-doc/auxiliary/issue-66159-1.rs b/src/test/rustdoc/intra-doc/auxiliary/issue-66159-1.rs new file mode 100644 index 000000000..2f3d069bd --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/issue-66159-1.rs @@ -0,0 +1,2 @@ +/// This will be referred to by the test docstring +pub struct Something; diff --git a/src/test/rustdoc/intra-doc/auxiliary/my-core.rs b/src/test/rustdoc/intra-doc/auxiliary/my-core.rs new file mode 100644 index 000000000..e22feb03a --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/my-core.rs @@ -0,0 +1,23 @@ +#![feature(no_core, lang_items, rustdoc_internals, rustc_attrs)] +#![no_core] +#![rustc_coherence_is_core] +#![crate_type="rlib"] + +#[doc(primitive = "char")] +/// Some char docs +mod char {} + +impl char { + pub fn len_utf8(self) -> usize { + 42 + } +} + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized {} + +#[lang = "copy"] +pub trait Copy: Clone {} diff --git a/src/test/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs b/src/test/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs new file mode 100644 index 000000000..5ba132f25 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs @@ -0,0 +1,34 @@ +// force-host +// no-prefer-dynamic +// compile-flags: --crate-type proc-macro + +#![crate_type="proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(DeriveA)] +pub fn a_derive(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(DeriveB)] +pub fn b_derive(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(DeriveTrait)] +pub fn trait_derive(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn attr_a(input: TokenStream, _args: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn attr_b(input: TokenStream, _args: TokenStream) -> TokenStream { + input +} diff --git a/src/test/rustdoc/intra-doc/auxiliary/pub-struct.rs b/src/test/rustdoc/intra-doc/auxiliary/pub-struct.rs new file mode 100644 index 000000000..75d428932 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/pub-struct.rs @@ -0,0 +1 @@ +pub struct SomeStruct; diff --git a/src/test/rustdoc/intra-doc/basic.rs b/src/test/rustdoc/intra-doc/basic.rs new file mode 100644 index 000000000..39f5c298b --- /dev/null +++ b/src/test/rustdoc/intra-doc/basic.rs @@ -0,0 +1,84 @@ +// @has basic/index.html +// @has - '//a/@href' 'struct.ThisType.html' +// @has - '//a/@href' 'struct.ThisType.html#method.this_method' +// @has - '//a/@href' 'enum.ThisEnum.html' +// @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant' +// @has - '//a/@href' 'trait.ThisTrait.html' +// @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_method' +// @has - '//a/@href' 'trait.ThisTrait.html#associatedtype.ThisAssociatedType' +// @has - '//a/@href' 'trait.ThisTrait.html#associatedconstant.THIS_ASSOCIATED_CONST' +// @has - '//a/@href' 'trait.ThisTrait.html' +// @has - '//a/@href' 'type.ThisAlias.html' +// @has - '//a/@href' 'union.ThisUnion.html' +// @has - '//a/@href' 'fn.this_function.html' +// @has - '//a/@href' 'constant.THIS_CONST.html' +// @has - '//a/@href' 'static.THIS_STATIC.html' +// @has - '//a/@href' 'macro.this_macro.html' +// @has - '//a/@href' 'trait.SoAmbiguous.html' +// @has - '//a/@href' 'fn.SoAmbiguous.html' +//! In this crate we would like to link to: +//! +//! * [`ThisType`](ThisType) +//! * [`ThisType::this_method`](ThisType::this_method) +//! * [`ThisEnum`](ThisEnum) +//! * [`ThisEnum::ThisVariant`](ThisEnum::ThisVariant) +//! * [`ThisEnum::ThisVariantCtor`](ThisEnum::ThisVariantCtor) +//! * [`ThisTrait`](ThisTrait) +//! * [`ThisTrait::this_associated_method`](ThisTrait::this_associated_method) +//! * [`ThisTrait::ThisAssociatedType`](ThisTrait::ThisAssociatedType) +//! * [`ThisTrait::THIS_ASSOCIATED_CONST`](ThisTrait::THIS_ASSOCIATED_CONST) +//! * [`ThisAlias`](ThisAlias) +//! * [`ThisUnion`](ThisUnion) +//! * [`this_function`](this_function()) +//! * [`THIS_CONST`](const@THIS_CONST) +//! * [`THIS_STATIC`](static@THIS_STATIC) +//! * [`this_macro`](this_macro!) +//! +//! In addition, there's some specifics we want to look at. There's [a trait called +//! SoAmbiguous][ambig-trait], but there's also [a function called SoAmbiguous][ambig-fn] too! +//! Whatever shall we do? +//! +//! [ambig-trait]: trait@SoAmbiguous +//! [ambig-fn]: SoAmbiguous() + +#[macro_export] +macro_rules! this_macro { + () => {}; +} + +// @has basic/struct.ThisType.html '//a/@href' 'macro.this_macro.html' +/// another link to [`this_macro!()`] +pub struct ThisType; + +impl ThisType { + pub fn this_method() {} +} +pub enum ThisEnum { ThisVariant, ThisVariantCtor(u32), } +pub trait ThisTrait { + type ThisAssociatedType; + const THIS_ASSOCIATED_CONST: u8; + fn this_associated_method(); +} +pub type ThisAlias = Result<(), ()>; +pub union ThisUnion { this_field: usize, } + +pub fn this_function() {} +pub const THIS_CONST: usize = 5usize; +pub static THIS_STATIC: usize = 5usize; + +pub trait SoAmbiguous {} + +#[allow(nonstandard_style)] +pub fn SoAmbiguous() {} + + +// @has basic/struct.SomeOtherType.html '//a/@href' 'struct.ThisType.html' +// @has - '//a/@href' 'struct.ThisType.html#method.this_method' +// @has - '//a/@href' 'enum.ThisEnum.html' +// @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant' +/// Shortcut links for: +/// * [`ThisType`] +/// * [`ThisType::this_method`] +/// * [ThisEnum] +/// * [ThisEnum::ThisVariant] +pub struct SomeOtherType; diff --git a/src/test/rustdoc/intra-doc/builtin-macros.rs b/src/test/rustdoc/intra-doc/builtin-macros.rs new file mode 100644 index 000000000..bbdbe246b --- /dev/null +++ b/src/test/rustdoc/intra-doc/builtin-macros.rs @@ -0,0 +1,3 @@ +// @has builtin_macros/index.html +// @has - '//a/@href' '{{channel}}/core/macro.cfg.html' +//! [cfg] diff --git a/src/test/rustdoc/intra-doc/crate-relative-assoc.rs b/src/test/rustdoc/intra-doc/crate-relative-assoc.rs new file mode 100644 index 000000000..d4a0ecc35 --- /dev/null +++ b/src/test/rustdoc/intra-doc/crate-relative-assoc.rs @@ -0,0 +1,17 @@ +pub mod io { + pub trait Read { + fn read(&mut self); + } +} + +pub mod bufreader { + // @has crate_relative_assoc/bufreader/index.html '//a/@href' 'struct.TcpStream.html#method.read' + //! [`crate::TcpStream::read`] + use crate::io::Read; +} + +pub struct TcpStream; + +impl crate::io::Read for TcpStream { + fn read(&mut self) {} +} diff --git a/src/test/rustdoc/intra-doc/crate-relative.rs b/src/test/rustdoc/intra-doc/crate-relative.rs new file mode 100644 index 000000000..bacbcabfc --- /dev/null +++ b/src/test/rustdoc/intra-doc/crate-relative.rs @@ -0,0 +1,13 @@ +pub struct Test<'a> { + data: &'a (), +} + +impl<'a> Test<'a> { + pub fn do_test(&self) {} +} + +// @has crate_relative/demo/index.html +// @has - '//a/@href' '../struct.Test.html#method.do_test' +pub mod demo { + //! [`crate::Test::do_test`] +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/additional_doc.rs b/src/test/rustdoc/intra-doc/cross-crate/additional_doc.rs new file mode 100644 index 000000000..e52fb9b1c --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/additional_doc.rs @@ -0,0 +1,10 @@ +// aux-build:additional_doc.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate my_rand; + +// @has 'additional_doc/trait.Rng.html' '//a[@href="trait.Rng.html"]' 'Rng' +// @has 'additional_doc/trait.Rng.html' '//a[@href="../my_rand/trait.RngCore.html"]' 'RngCore' +/// This is an [`Rng`]. +pub use my_rand::Rng; diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs new file mode 100644 index 000000000..684fdd449 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs @@ -0,0 +1,6 @@ +#![crate_name = "my_rand"] +#![deny(rustdoc::broken_intra_doc_links)] + +pub trait RngCore {} +/// Rng extends [`RngCore`]. +pub trait Rng: RngCore {} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs new file mode 100644 index 000000000..34f4e9f63 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs @@ -0,0 +1,19 @@ +#![crate_name = "hidden_dep"] +#![deny(rustdoc::broken_intra_doc_links)] + +#[doc(hidden)] +pub mod __reexport { + pub use crate::*; +} + +pub mod future { + mod ready { + + /// Link to [`ready`](function@ready) + pub struct Ready; + pub fn ready() {} + + } + pub use self::ready::{ready, Ready}; + +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs new file mode 100644 index 000000000..d6a829966 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs @@ -0,0 +1,7 @@ +#![crate_name = "a"] +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct Foo; + +/// Link to [Foo] +pub struct Bar; diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs new file mode 100644 index 000000000..a37848e23 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs @@ -0,0 +1,5 @@ +#![crate_name = "inner"] + +/// Links to [crate::g] +pub fn f() {} +pub fn g() {} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs new file mode 100644 index 000000000..cb7a8afb6 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs @@ -0,0 +1,10 @@ +#![crate_name = "macro_inner"] +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct Foo; + +/// See also [`Foo`] +#[macro_export] +macro_rules! my_macro { + () => {} +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/module.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/module.rs new file mode 100644 index 000000000..018fdedd9 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/module.rs @@ -0,0 +1,7 @@ +#![crate_name = "module_inner"] +#![deny(rustdoc::broken_intra_doc_links)] +/// [SomeType] links to [bar] +pub struct SomeType; +pub trait SomeTrait {} +/// [bar] links to [SomeTrait] and also [SomeType] +pub mod bar {} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs new file mode 100644 index 000000000..0d5a95407 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs @@ -0,0 +1,20 @@ +// force-host +// no-prefer-dynamic +// compile-flags: --crate-type proc-macro +#![crate_type="proc-macro"] +#![crate_name="proc_macro_inner"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +/// Links to [`OtherDerive`] +#[proc_macro_derive(DeriveA)] +pub fn a_derive(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(OtherDerive)] +pub fn other_derive(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs new file mode 100644 index 000000000..0612f53d6 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs @@ -0,0 +1,12 @@ +#![crate_name = "a"] +#![deny(rustdoc::broken_intra_doc_links)] + +pub mod bar { + pub struct Bar; +} + +pub mod foo { + use crate::bar; + /// link to [bar::Bar] + pub struct Foo; +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs new file mode 100644 index 000000000..105eb8e11 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs @@ -0,0 +1,13 @@ +#![crate_name = "bar"] +#![deny(rustdoc::broken_intra_doc_links)] + +pub trait Foo { + /// [`Bar`] [`Baz`] + fn foo(); +} + +pub trait Bar { +} + +pub trait Baz { +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs new file mode 100644 index 000000000..c16e39d56 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs @@ -0,0 +1,16 @@ +#![crate_name = "inner"] +/// this is a trait +pub trait SomeTrait { + /// this is a method for [a trait][SomeTrait] + fn foo(); +} + +pub mod bar { + use super::SomeTrait; + + pub struct BarStruct; + + impl SomeTrait for BarStruct { + fn foo() {} + } +} diff --git a/src/test/rustdoc/intra-doc/cross-crate/basic.rs b/src/test/rustdoc/intra-doc/cross-crate/basic.rs new file mode 100644 index 000000000..ad7454918 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/basic.rs @@ -0,0 +1,9 @@ +// aux-build:intra-doc-basic.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] + +// from https://github.com/rust-lang/rust/issues/65983 +extern crate a; + +// @has 'basic/struct.Bar.html' '//a[@href="../a/struct.Foo.html"]' 'Foo' +pub use a::Bar; diff --git a/src/test/rustdoc/intra-doc/cross-crate/crate.rs b/src/test/rustdoc/intra-doc/cross-crate/crate.rs new file mode 100644 index 000000000..edf544708 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/crate.rs @@ -0,0 +1,6 @@ +// aux-build:intra-link-cross-crate-crate.rs +// build-aux-docs +#![crate_name = "outer"] +extern crate inner; +// @has outer/fn.f.html '//a[@href="../inner/fn.g.html"]' "crate::g" +pub use inner::f; diff --git a/src/test/rustdoc/intra-doc/cross-crate/hidden.rs b/src/test/rustdoc/intra-doc/cross-crate/hidden.rs new file mode 100644 index 000000000..4f7d075ba --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/hidden.rs @@ -0,0 +1,10 @@ +// aux-build:hidden.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] + +// tests https://github.com/rust-lang/rust/issues/73363 + +extern crate hidden_dep; + +// @has 'hidden/struct.Ready.html' '//a/@href' 'fn.ready.html' +pub use hidden_dep::future::{ready, Ready}; diff --git a/src/test/rustdoc/intra-doc/cross-crate/macro.rs b/src/test/rustdoc/intra-doc/cross-crate/macro.rs new file mode 100644 index 000000000..32f0a55d3 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/macro.rs @@ -0,0 +1,11 @@ +// aux-build:macro_inner.rs +// aux-build:proc_macro.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] +extern crate macro_inner; +extern crate proc_macro_inner; + +// @has 'macro/macro.my_macro.html' '//a[@href="../macro_inner/struct.Foo.html"]' 'Foo' +pub use macro_inner::my_macro; +// @has 'macro/derive.DeriveA.html' '//a[@href="../proc_macro_inner/derive.OtherDerive.html"]' 'OtherDerive' +pub use proc_macro_inner::DeriveA; diff --git a/src/test/rustdoc/intra-doc/cross-crate/module.rs b/src/test/rustdoc/intra-doc/cross-crate/module.rs new file mode 100644 index 000000000..fde932265 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/module.rs @@ -0,0 +1,8 @@ +// outer.rs +// aux-build: module.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] +extern crate module_inner; +// @has 'module/bar/index.html' '//a[@href="../../module_inner/trait.SomeTrait.html"]' 'SomeTrait' +// @has 'module/bar/index.html' '//a[@href="../../module_inner/struct.SomeType.html"]' 'SomeType' +pub use module_inner::bar; diff --git a/src/test/rustdoc/intra-doc/cross-crate/submodule-inner.rs b/src/test/rustdoc/intra-doc/cross-crate/submodule-inner.rs new file mode 100644 index 000000000..577fe78a5 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/submodule-inner.rs @@ -0,0 +1,8 @@ +// aux-build:submodule-inner.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate a; + +// @has 'submodule_inner/struct.Foo.html' '//a[@href="../a/bar/struct.Bar.html"]' 'Bar' +pub use a::foo::Foo; diff --git a/src/test/rustdoc/intra-doc/cross-crate/submodule-outer.rs b/src/test/rustdoc/intra-doc/cross-crate/submodule-outer.rs new file mode 100644 index 000000000..d0c0b7e85 --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/submodule-outer.rs @@ -0,0 +1,16 @@ +// aux-build:submodule-outer.rs +// edition:2018 +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate bar as bar_; + +// from https://github.com/rust-lang/rust/issues/60883 +pub mod bar { + pub use ::bar_::Bar; +} + +// NOTE: we re-exported both `Foo` and `Bar` here, +// NOTE: so they are inlined and therefore we link to the current module. +// @has 'submodule_outer/trait.Foo.html' '//a[@href="bar/trait.Bar.html"]' 'Bar' +// @has 'submodule_outer/trait.Foo.html' '//a[@href="trait.Baz.html"]' 'Baz' +pub use ::bar_::{Foo, Baz}; diff --git a/src/test/rustdoc/intra-doc/cross-crate/traits.rs b/src/test/rustdoc/intra-doc/cross-crate/traits.rs new file mode 100644 index 000000000..7b9554bfd --- /dev/null +++ b/src/test/rustdoc/intra-doc/cross-crate/traits.rs @@ -0,0 +1,14 @@ +// aux-build:traits.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate inner; +use inner::SomeTrait; + +pub struct SomeStruct; + + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'SomeTrait' +impl SomeTrait for SomeStruct { + // @has 'traits/struct.SomeStruct.html' '//a[@href="../inner/trait.SomeTrait.html"]' 'a trait' + fn foo() {} +} diff --git a/src/test/rustdoc/intra-doc/disambiguators-removed.rs b/src/test/rustdoc/intra-doc/disambiguators-removed.rs new file mode 100644 index 000000000..331a31413 --- /dev/null +++ b/src/test/rustdoc/intra-doc/disambiguators-removed.rs @@ -0,0 +1,50 @@ +#![deny(rustdoc::broken_intra_doc_links)] +// first try backticks +/// Trait: [`trait@Name`], fn: [`fn@Name`], [`Name`][`macro@Name`] +// @has disambiguators_removed/struct.AtDisambiguator.html +// @has - '//a[@href="trait.Name.html"][code]' "Name" +// @has - '//a[@href="fn.Name.html"][code]' "Name" +// @has - '//a[@href="macro.Name.html"][code]' "Name" +pub struct AtDisambiguator; + +/// fn: [`Name()`], macro: [`Name!`] +// @has disambiguators_removed/struct.SymbolDisambiguator.html +// @has - '//a[@href="fn.Name.html"][code]' "Name()" +// @has - '//a[@href="macro.Name.html"][code]' "Name!" +pub struct SymbolDisambiguator; + +// Now make sure that backticks aren't added if they weren't already there +/// [fn@Name] +// @has disambiguators_removed/trait.Name.html +// @has - '//a[@href="fn.Name.html"]' "Name" +// @!has - '//a[@href="fn.Name.html"][code]' "Name" + +// FIXME: this will turn !() into ! alone +/// [Name!()] +// @has - '//a[@href="macro.Name.html"]' "Name!" +pub trait Name {} + +#[allow(non_snake_case)] + +// Try collapsed reference links +/// [macro@Name][] +// @has disambiguators_removed/fn.Name.html +// @has - '//a[@href="macro.Name.html"]' "Name" + +// Try links that have the same text as a generated URL +/// Weird URL aligned [macro.Name.html][trait@Name] +// @has - '//a[@href="trait.Name.html"]' "macro.Name.html" +pub fn Name() {} + +#[macro_export] +// Rustdoc doesn't currently handle links that have weird interspersing of inline code blocks. +/// [fn@Na`m`e] +// @has disambiguators_removed/macro.Name.html +// @has - '//a[@href="fn.Name.html"]' "fn@Name" + +// It also doesn't handle any case where the code block isn't the whole link text: +/// [trait@`Name`] +// @has - '//a[@href="trait.Name.html"]' "trait@Name" +macro_rules! Name { + () => () +} diff --git a/src/test/rustdoc/intra-doc/email-address.rs b/src/test/rustdoc/intra-doc/email-address.rs new file mode 100644 index 000000000..24161c3bb --- /dev/null +++ b/src/test/rustdoc/intra-doc/email-address.rs @@ -0,0 +1,10 @@ +#![forbid(rustdoc::broken_intra_doc_links)] + +//! Email me at <hello@example.com>. +//! Email me at <hello-world@example.com>. +//! Email me at <hello@localhost>. +//! Email me at <prim@i32>. +// @has email_address/index.html '//a[@href="mailto:hello@example.com"]' 'hello@example.com' +// @has email_address/index.html '//a[@href="mailto:hello-world@example.com"]' 'hello-world@example.com' +// @has email_address/index.html '//a[@href="mailto:hello@localhost"]' 'hello@localhost' +// @has email_address/index.html '//a[@href="mailto:prim@i32"]' 'prim@i32' diff --git a/src/test/rustdoc/intra-doc/enum-struct-field.rs b/src/test/rustdoc/intra-doc/enum-struct-field.rs new file mode 100644 index 000000000..2270a1faf --- /dev/null +++ b/src/test/rustdoc/intra-doc/enum-struct-field.rs @@ -0,0 +1,14 @@ +#![crate_name = "foo"] + +pub enum Foo { + X { + y: u8, + } +} + +/// Hello +/// +/// I want [Foo::X::y]. +pub fn foo() {} + +// @has foo/fn.foo.html '//a/@href' 'enum.Foo.html#variant.X.field.y' diff --git a/src/test/rustdoc/intra-doc/extern-builtin-type-impl.rs b/src/test/rustdoc/intra-doc/extern-builtin-type-impl.rs new file mode 100644 index 000000000..7bb1ded3f --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-builtin-type-impl.rs @@ -0,0 +1,11 @@ +// Reexport of a structure that derefs to a type with lang item impls having doc links in their +// comments. The doc link points to an associated item, so we check that traits in scope for that +// link are populated. + +// aux-build:extern-builtin-type-impl-dep.rs + +#![no_std] + +extern crate extern_builtin_type_impl_dep; + +pub use extern_builtin_type_impl_dep::DerefsToF64; diff --git a/src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs b/src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs new file mode 100644 index 000000000..5d8dcf8bc --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-crate-only-used-in-link.rs @@ -0,0 +1,19 @@ +// This test is just a little cursed. +// aux-build:issue-66159-1.rs +// aux-crate:priv:issue_66159_1=issue-66159-1.rs +// aux-build:empty.rs +// aux-crate:priv:empty=empty.rs +// aux-build:empty2.rs +// aux-crate:priv:empty2=empty2.rs +// build-aux-docs +// compile-flags:-Z unstable-options --edition 2018 + +// @has extern_crate_only_used_in_link/index.html +// @has - '//a[@href="../issue_66159_1/struct.Something.html"]' 'issue_66159_1::Something' +//! [issue_66159_1::Something] + +// @has - '//a[@href="../empty/index.html"]' 'empty' +//! [`empty`] + +// @has - '//a[@href="../empty2/index.html"]' 'empty2' +//! [empty2<x>] diff --git a/src/test/rustdoc/intra-doc/extern-crate.rs b/src/test/rustdoc/intra-doc/extern-crate.rs new file mode 100644 index 000000000..4e4438dea --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-crate.rs @@ -0,0 +1,9 @@ +// aux-build:intra-link-extern-crate.rs + +// When loading `extern crate` statements, we would pull in their docs at the same time, even +// though they would never actually get displayed. This tripped intra-doc-link resolution failures, +// for items that aren't under our control, and not actually getting documented! + +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate inner; diff --git a/src/test/rustdoc/intra-doc/extern-inherent-impl.rs b/src/test/rustdoc/intra-doc/extern-inherent-impl.rs new file mode 100644 index 000000000..2e41c2214 --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-inherent-impl.rs @@ -0,0 +1,8 @@ +// Reexport of a structure with public inherent impls having doc links in their comments. The doc +// link points to an associated item, so we check that traits in scope for that link are populated. + +// aux-build:extern-inherent-impl-dep.rs + +extern crate extern_inherent_impl_dep; + +pub use extern_inherent_impl_dep::PublicStruct; diff --git a/src/test/rustdoc/intra-doc/extern-reference-link.rs b/src/test/rustdoc/intra-doc/extern-reference-link.rs new file mode 100644 index 000000000..bad6ec755 --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-reference-link.rs @@ -0,0 +1,7 @@ +// compile-flags: --extern pub_struct +// aux-build:pub-struct.rs + +/// [SomeStruct] +/// +/// [SomeStruct]: pub_struct::SomeStruct +pub fn foo() {} diff --git a/src/test/rustdoc/intra-doc/extern-type.rs b/src/test/rustdoc/intra-doc/extern-type.rs new file mode 100644 index 000000000..ab088ab78 --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-type.rs @@ -0,0 +1,37 @@ +#![feature(extern_types)] + +extern { + pub type ExternType; +} + +pub trait T { + fn test(&self) {} +} + +pub trait G<N> { + fn g(&self, n: N) {} +} + +impl ExternType { + pub fn f(&self) {} +} + +impl T for ExternType { + fn test(&self) {} +} + +impl G<usize> for ExternType { + fn g(&self, n: usize) {} +} + +// @has 'extern_type/foreigntype.ExternType.html' +// @has 'extern_type/fn.links_to_extern_type.html' \ +// 'href="foreigntype.ExternType.html#method.f"' +// @has 'extern_type/fn.links_to_extern_type.html' \ +// 'href="foreigntype.ExternType.html#method.test"' +// @has 'extern_type/fn.links_to_extern_type.html' \ +// 'href="foreigntype.ExternType.html#method.g"' +/// See also [ExternType::f] +/// See also [ExternType::test] +/// See also [ExternType::g] +pub fn links_to_extern_type() {} diff --git a/src/test/rustdoc/intra-doc/external-traits.rs b/src/test/rustdoc/intra-doc/external-traits.rs new file mode 100644 index 000000000..a0a66f242 --- /dev/null +++ b/src/test/rustdoc/intra-doc/external-traits.rs @@ -0,0 +1,12 @@ +// aux-build:intra-links-external-traits.rs +// ignore-cross-compile + +#![crate_name = "outer"] +#![deny(rustdoc::broken_intra_doc_links)] + +// using a trait that has intra-doc links on it from another crate (whether re-exporting or just +// implementing it) used to give spurious resolution failure warnings + +extern crate intra_links_external_traits; + +pub use intra_links_external_traits::ThisTrait; diff --git a/src/test/rustdoc/intra-doc/field.rs b/src/test/rustdoc/intra-doc/field.rs new file mode 100644 index 000000000..001143489 --- /dev/null +++ b/src/test/rustdoc/intra-doc/field.rs @@ -0,0 +1,4 @@ +// @has field/index.html '//a[@href="{{channel}}/core/ops/range/struct.Range.html#structfield.start"]' 'start' +// @has field/index.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found' +//! [start][std::ops::Range::start] +//! [not_found][std::io::ErrorKind::NotFound] diff --git a/src/test/rustdoc/intra-doc/generic-params.rs b/src/test/rustdoc/intra-doc/generic-params.rs new file mode 100644 index 000000000..fbc9fc6a9 --- /dev/null +++ b/src/test/rustdoc/intra-doc/generic-params.rs @@ -0,0 +1,62 @@ +// ignore-tidy-linelength + +#![crate_name = "foo"] + +//! Here's a link to [`Vec<T>`] and one to [`Box<Vec<Option<T>>>`]. +//! Here's a link to [`Iterator<Box<T>>::Item`]. +//! +// @has foo/index.html '//a[@href="{{channel}}/alloc/vec/struct.Vec.html"]' 'Vec<T>' +// @has foo/index.html '//a[@href="{{channel}}/alloc/boxed/struct.Box.html"]' 'Box<Vec<Option<T>>>' +// @has foo/index.html '//a[@href="{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item"]' 'Iterator<Box<T>>::Item' + +//! And what about a link to [just `Option`](Option) and, [with the generic, `Option<T>`](Option<T>)? +//! +// @has foo/index.html '//a[@href="{{channel}}/core/option/enum.Option.html"]' 'just Option' +// @has foo/index.html '//a[@href="{{channel}}/core/option/enum.Option.html"]' 'with the generic, Option<T>' + +//! We should also try linking to [`Result<T, E>`]; it has *two* generics! +//! And [`Result<T, !>`] and [`Result<!, E>`]. +//! +// @has foo/index.html '//a[@href="{{channel}}/core/result/enum.Result.html"]' 'Result<T, E>' +// @has foo/index.html '//a[@href="{{channel}}/core/result/enum.Result.html"]' 'Result<T, !>' +// @has foo/index.html '//a[@href="{{channel}}/core/result/enum.Result.html"]' 'Result<!, E>' + +//! Now let's test a trickier case: [`Vec::<T>::new`], or you could write it +//! [with parentheses as `Vec::<T>::new()`][Vec::<T>::new()]. +//! And what about something even harder? That would be [`Vec::<Box<T>>::new()`]. +//! +// @has foo/index.html '//a[@href="{{channel}}/alloc/vec/struct.Vec.html#method.new"]' 'Vec::<T>::new' +// @has foo/index.html '//a[@href="{{channel}}/alloc/vec/struct.Vec.html#method.new"]' 'with parentheses as Vec::<T>::new()' +// @has foo/index.html '//a[@href="{{channel}}/alloc/vec/struct.Vec.html#method.new"]' 'Vec::<Box<T>>::new()' + +//! This is also pretty tricky: [`TypeId::of::<String>()`]. +//! And this too: [`Vec::<std::error::Error>::len`]. +//! +// @has foo/index.html '//a[@href="{{channel}}/core/any/struct.TypeId.html#method.of"]' 'TypeId::of::<String>()' +// @has foo/index.html '//a[@href="{{channel}}/alloc/vec/struct.Vec.html#method.len"]' 'Vec::<std::error::Error>::len' + +//! We unofficially and implicitly support things that aren't valid in the actual Rust syntax, like +//! [`Box::<T>new()`]. We may not support them in the future! +//! +// @has foo/index.html '//a[@href="{{channel}}/alloc/boxed/struct.Box.html#method.new"]' 'Box::<T>new()' + +//! These will be resolved as regular links: +//! - [`this is <invalid syntax> first`](https://www.rust-lang.org) +//! - [`this is <invalid syntax> twice`] +//! - [`<invalid syntax> thrice`](https://www.rust-lang.org) +//! - [`<invalid syntax> four times`][rlo] +//! - [a < b][rlo] +//! - [c > d] +//! +//! [`this is <invalid syntax> twice`]: https://www.rust-lang.org +//! [rlo]: https://www.rust-lang.org +//! [c > d]: https://www.rust-lang.org +//! +// @has foo/index.html '//a[@href="https://www.rust-lang.org"]' 'this is <invalid syntax> first' +// @has foo/index.html '//a[@href="https://www.rust-lang.org"]' 'this is <invalid syntax> twice' +// @has foo/index.html '//a[@href="https://www.rust-lang.org"]' '<invalid syntax> thrice' +// @has foo/index.html '//a[@href="https://www.rust-lang.org"]' '<invalid syntax> four times' +// @has foo/index.html '//a[@href="https://www.rust-lang.org"]' 'a < b' +// @has foo/index.html '//a[@href="https://www.rust-lang.org"]' 'c > d' + +use std::any::TypeId; diff --git a/src/test/rustdoc/intra-doc/generic-trait-impl.rs b/src/test/rustdoc/intra-doc/generic-trait-impl.rs new file mode 100644 index 000000000..ba8595abf --- /dev/null +++ b/src/test/rustdoc/intra-doc/generic-trait-impl.rs @@ -0,0 +1,20 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +// Test intra-doc links on trait implementations with generics +// regression test for issue #92662 + +use std::marker::PhantomData; + +pub trait Bar<T> { + fn bar(&self); +} + +pub struct Foo<U>(PhantomData<U>); + +impl<T, U> Bar<T> for Foo<U> { + fn bar(&self) {} +} + +// @has generic_trait_impl/fn.main.html '//a[@href="struct.Foo.html#method.bar"]' 'Foo::bar' +/// link to [`Foo::bar`] +pub fn main() {} diff --git a/src/test/rustdoc/intra-doc/in-bodies.rs b/src/test/rustdoc/intra-doc/in-bodies.rs new file mode 100644 index 000000000..55169e5d3 --- /dev/null +++ b/src/test/rustdoc/intra-doc/in-bodies.rs @@ -0,0 +1,30 @@ +// we need to make sure that intra-doc links on trait impls get resolved in the right scope + +#![deny(rustdoc::broken_intra_doc_links)] + +pub mod inner { + pub struct SomethingOutOfScope; +} + +pub mod other { + use inner::SomethingOutOfScope; + use SomeTrait; + + pub struct OtherStruct; + + /// Let's link to [SomethingOutOfScope] while we're at it. + impl SomeTrait for OtherStruct {} +} + +pub trait SomeTrait {} + +pub struct SomeStruct; + +fn __implementation_details() { + use inner::SomethingOutOfScope; + + // FIXME: intra-links resolve in their nearest module scope, not their actual scope in cases + // like this + // Let's link to [SomethingOutOfScope] while we're at it. + impl SomeTrait for SomeStruct {} +} diff --git a/src/test/rustdoc/intra-doc/issue-66159.rs b/src/test/rustdoc/intra-doc/issue-66159.rs new file mode 100644 index 000000000..56742b397 --- /dev/null +++ b/src/test/rustdoc/intra-doc/issue-66159.rs @@ -0,0 +1,10 @@ +// aux-crate:priv:pub_struct=pub-struct.rs +// compile-flags:-Z unstable-options + +// The issue was an ICE which meant that we never actually generated the docs +// so if we have generated the docs, we're okay. +// Since we don't generate the docs for the auxiliary files, we can't actually +// verify that the struct is linked correctly. + +// @has issue_66159/index.html +//! [pub_struct::SomeStruct] diff --git a/src/test/rustdoc/intra-doc/issue-82209.rs b/src/test/rustdoc/intra-doc/issue-82209.rs new file mode 100644 index 000000000..a5fe855cb --- /dev/null +++ b/src/test/rustdoc/intra-doc/issue-82209.rs @@ -0,0 +1,11 @@ +#![crate_name = "foo"] +#![deny(rustdoc::broken_intra_doc_links)] +pub enum Foo { + Bar { + abc: i32, + /// [Self::Bar::abc] + xyz: i32, + }, +} + +// @has foo/enum.Foo.html '//a/@href' 'enum.Foo.html#variant.Bar.field.abc' diff --git a/src/test/rustdoc/intra-doc/libstd-re-export.rs b/src/test/rustdoc/intra-doc/libstd-re-export.rs new file mode 100644 index 000000000..6c41eb2b5 --- /dev/null +++ b/src/test/rustdoc/intra-doc/libstd-re-export.rs @@ -0,0 +1,4 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![feature(intra_doc_pointers)] + +pub use std::*; diff --git a/src/test/rustdoc/intra-doc/macros-disambiguators.rs b/src/test/rustdoc/intra-doc/macros-disambiguators.rs new file mode 100644 index 000000000..cd4caa6a8 --- /dev/null +++ b/src/test/rustdoc/intra-doc/macros-disambiguators.rs @@ -0,0 +1,25 @@ +#![crate_name = "foo"] +#![deny(rustdoc::broken_intra_doc_links)] + +//! [foo!()] +// @has foo/index.html '//a[@href="macro.foo.html"]' 'foo!()' + +//! [foo!{}] +// @has - '//a[@href="macro.foo.html"]' 'foo!{}' + +//! [foo![]](foo![]) +// @has - '//a[@href="macro.foo.html"]' 'foo![]' + +//! [foo1](foo!()) +// @has - '//a[@href="macro.foo.html"]' 'foo1' + +//! [foo2](foo!{}) +// @has - '//a[@href="macro.foo.html"]' 'foo2' + +//! [foo3](foo![]) +// @has - '//a[@href="macro.foo.html"]' 'foo3' + +#[macro_export] +macro_rules! foo { + () => {}; +} diff --git a/src/test/rustdoc/intra-doc/mod-ambiguity.rs b/src/test/rustdoc/intra-doc/mod-ambiguity.rs new file mode 100644 index 000000000..0c7acbaf0 --- /dev/null +++ b/src/test/rustdoc/intra-doc/mod-ambiguity.rs @@ -0,0 +1,16 @@ +#![deny(rustdoc::broken_intra_doc_links)] + + +pub fn foo() { + +} + +pub mod foo {} +// @has mod_ambiguity/struct.A.html '//a/@href' 'foo/index.html' +/// Module is [`module@foo`] +pub struct A; + + +// @has mod_ambiguity/struct.B.html '//a/@href' 'fn.foo.html' +/// Function is [`fn@foo`] +pub struct B; diff --git a/src/test/rustdoc/intra-doc/mod-relative.rs b/src/test/rustdoc/intra-doc/mod-relative.rs new file mode 100644 index 000000000..49d3399b9 --- /dev/null +++ b/src/test/rustdoc/intra-doc/mod-relative.rs @@ -0,0 +1,17 @@ +pub mod wrapper { + + pub struct Test<'a> { + data: &'a (), + } + + impl<'a> Test<'a> { + pub fn do_test(&self) {} + } + + // @has mod_relative/wrapper/demo/index.html + // @has - '//a/@href' '../struct.Test.html#method.do_test' + /// [`Test::do_test`] + pub mod demo { + } + +} diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs new file mode 100644 index 000000000..be4b44b31 --- /dev/null +++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs @@ -0,0 +1,46 @@ +#![crate_name = "foo"] +#![feature(intra_doc_pointers)] +#![deny(rustdoc::broken_intra_doc_links)] + +// @has foo/index.html '//a[@href="{{channel}}/std/primitive.slice.html#method.rotate_left"]' 'slice::rotate_left' +//! [slice::rotate_left] + +// @has - '//a[@href="{{channel}}/std/primitive.array.html#method.map"]' 'array::map' +//! [array::map] + +// @has - '//a[@href="{{channel}}/std/primitive.str.html"]' 'owned str' +// @has - '//a[@href="{{channel}}/std/primitive.str.html"]' 'str ref' +// @has - '//a[@href="{{channel}}/std/primitive.str.html#method.is_empty"]' 'str::is_empty' +// @has - '//a[@href="{{channel}}/std/primitive.str.html#method.len"]' '&str::len' +//! [owned str][str] +//! [str ref][&str] +//! [str::is_empty] +//! [&str::len] + +// @has - '//a[@href="{{channel}}/std/primitive.pointer.html#method.is_null"]' 'pointer::is_null' +// @has - '//a[@href="{{channel}}/std/primitive.pointer.html#method.is_null"]' '*const::is_null' +// @has - '//a[@href="{{channel}}/std/primitive.pointer.html#method.is_null"]' '*mut::is_null' +//! [pointer::is_null] +//! [*const::is_null] +//! [*mut::is_null] + +// @has - '//a[@href="{{channel}}/std/primitive.unit.html"]' 'unit' +//! [unit] + +// @has - '//a[@href="{{channel}}/std/primitive.tuple.html"]' 'tuple' +//! [tuple] + +// @has - '//a[@href="{{channel}}/std/primitive.reference.html"]' 'reference' +// @has - '//a[@href="{{channel}}/std/primitive.reference.html"]' '&' +// @has - '//a[@href="{{channel}}/std/primitive.reference.html"]' '&mut' +//! [reference] +//! [&] +//! [&mut] + +// @has - '//a[@href="{{channel}}/std/primitive.fn.html"]' 'fn' +//! [fn] + +// @has - '//a[@href="{{channel}}/std/primitive.never.html"]' 'never' +// @has - '//a[@href="{{channel}}/std/primitive.never.html"]' '!' +//! [never] +//! [!] diff --git a/src/test/rustdoc/intra-doc/prim-assoc.rs b/src/test/rustdoc/intra-doc/prim-assoc.rs new file mode 100644 index 000000000..dfa7db8a5 --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-assoc.rs @@ -0,0 +1,4 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +//! [i32::MAX] +// @has prim_assoc/index.html '//a[@href="{{channel}}/std/primitive.i32.html#associatedconstant.MAX"]' "i32::MAX" diff --git a/src/test/rustdoc/intra-doc/prim-associated-traits.rs b/src/test/rustdoc/intra-doc/prim-associated-traits.rs new file mode 100644 index 000000000..8639a24f7 --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-associated-traits.rs @@ -0,0 +1,46 @@ +#![feature(never_type)] +use std::str::FromStr; + +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.f64.html#method.from_str"]' 'f64::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.f32.html#method.from_str"]' 'f32::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.isize.html#method.from_str"]' 'isize::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.i8.html#method.from_str"]' 'i8::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.i16.html#method.from_str"]' 'i16::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.i32.html#method.from_str"]' 'i32::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.i64.html#method.from_str"]' 'i64::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.i128.html#method.from_str"]' 'i128::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.usize.html#method.from_str"]' 'usize::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.u8.html#method.from_str"]' 'u8::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.u16.html#method.from_str"]' 'u16::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.u32.html#method.from_str"]' 'u32::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.u64.html#method.from_str"]' 'u64::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.u128.html#method.from_str"]' 'u128::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.char.html#method.from_str"]' 'char::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.bool.html#method.from_str"]' 'bool::from_str()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.str.html#method.eq"]' 'str::eq()' +// @has 'prim_associated_traits/struct.Number.html' '//a[@href="{{channel}}/std/primitive.never.html#method.eq"]' 'never::eq()' +/// [`f64::from_str()`] [`f32::from_str()`] [`isize::from_str()`] [`i8::from_str()`] +/// [`i16::from_str()`] [`i32::from_str()`] [`i64::from_str()`] [`i128::from_str()`] +/// [`u16::from_str()`] [`u32::from_str()`] [`u64::from_str()`] [`u128::from_str()`] +/// [`usize::from_str()`] [`u8::from_str()`] [`char::from_str()`] [`bool::from_str()`] +/// [`str::eq()`] [`never::eq()`] +pub struct Number { + pub f_64: f64, + pub f_32: f32, + pub i_size: isize, + pub i_8: i8, + pub i_16: i16, + pub i_32: i32, + pub i_64: i64, + pub i_128: i128, + pub u_size: usize, + pub u_8: u8, + pub u_16: u16, + pub u_32: u32, + pub u_64: u64, + pub u_128: u128, + pub ch: char, + pub boolean: bool, + pub string: str, + pub n: !, +} diff --git a/src/test/rustdoc/intra-doc/prim-methods-external-core.rs b/src/test/rustdoc/intra-doc/prim-methods-external-core.rs new file mode 100644 index 000000000..c3340af33 --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-methods-external-core.rs @@ -0,0 +1,17 @@ +// aux-build:my-core.rs +// build-aux-docs +// ignore-cross-compile +// only-linux + +#![deny(rustdoc::broken_intra_doc_links)] +#![feature(no_core, lang_items)] +#![no_core] +#![crate_type = "rlib"] + +// @has prim_methods_external_core/index.html +// @has - '//*[@id="main-content"]//a[@href="../my_core/primitive.char.html"]' 'char' +// @has - '//*[@id="main-content"]//a[@href="../my_core/primitive.char.html#method.len_utf8"]' 'char::len_utf8' + +//! A [`char`] and its [`char::len_utf8`]. + +extern crate my_core; diff --git a/src/test/rustdoc/intra-doc/prim-methods-local.rs b/src/test/rustdoc/intra-doc/prim-methods-local.rs new file mode 100644 index 000000000..79d8df045 --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-methods-local.rs @@ -0,0 +1,29 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![feature(no_core, lang_items, rustc_attrs, rustdoc_internals)] +#![no_core] +#![rustc_coherence_is_core] +#![crate_type = "rlib"] + +// @has prim_methods_local/index.html +// @has - '//*[@id="main-content"]//a[@href="primitive.char.html"]' 'char' +// @has - '//*[@id="main-content"]//a[@href="primitive.char.html#method.len_utf8"]' 'char::len_utf8' + +//! A [prim@`char`] and its [`char::len_utf8`]. + +#[doc(primitive = "char")] +mod char {} + +impl char { + pub fn len_utf8(self) -> usize { + 42 + } +} + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized {} + +#[lang = "copy"] +pub trait Copy: Clone {} diff --git a/src/test/rustdoc/intra-doc/prim-methods.rs b/src/test/rustdoc/intra-doc/prim-methods.rs new file mode 100644 index 000000000..a412a23fd --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-methods.rs @@ -0,0 +1,7 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +// @has prim_methods/index.html +// @has - '//*[@id="main-content"]//a[@href="{{channel}}/std/primitive.char.html"]' 'char' +// @has - '//*[@id="main-content"]//a[@href="{{channel}}/std/primitive.char.html#method.len_utf8"]' 'char::len_utf8' + +//! A [`char`] and its [`char::len_utf8`]. diff --git a/src/test/rustdoc/intra-doc/prim-precedence.rs b/src/test/rustdoc/intra-doc/prim-precedence.rs new file mode 100644 index 000000000..25625b952 --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-precedence.rs @@ -0,0 +1,16 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +pub mod char { + /// [char] + // @has prim_precedence/char/struct.Inner.html '//a/@href' '{{channel}}/std/primitive.char.html' + pub struct Inner; +} + +/// See [prim@char] +// @has prim_precedence/struct.MyString.html '//a/@href' '{{channel}}/std/primitive.char.html' +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' +pub struct MyString2; diff --git a/src/test/rustdoc/intra-doc/prim-self.rs b/src/test/rustdoc/intra-doc/prim-self.rs new file mode 100644 index 000000000..c7ce71b15 --- /dev/null +++ b/src/test/rustdoc/intra-doc/prim-self.rs @@ -0,0 +1,41 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![rustc_coherence_is_core] +#![allow(incomplete_features)] // inherent_associated_types +#![feature(rustc_attrs)] +#![feature(no_core)] +#![feature(rustdoc_internals)] +#![feature(inherent_associated_types)] +#![feature(lang_items)] +#![no_core] + +/// [Self::f] +/// [Self::MAX] +// @has prim_self/primitive.usize.html +// @has - '//a[@href="primitive.usize.html#method.f"]' 'Self::f' +// @has - '//a[@href="primitive.usize.html#associatedconstant.MAX"]' 'Self::MAX' +impl usize { + /// Some docs + pub fn f() {} + + /// 10 and 2^32 are basically the same. + pub const MAX: usize = 10; + + // @has - '//a[@href="primitive.usize.html#associatedtype.ME"]' 'Self::ME' + /// [Self::ME] + pub type ME = usize; +} + +#[doc(primitive = "usize")] +/// This has some docs. +mod usize {} + +/// [S::f] +/// [Self::f] +pub struct S; + +impl S { + pub fn f() {} +} + +#[lang = "sized"] +pub trait Sized {} diff --git a/src/test/rustdoc/intra-doc/primitive-disambiguators.rs b/src/test/rustdoc/intra-doc/primitive-disambiguators.rs new file mode 100644 index 000000000..adcab767d --- /dev/null +++ b/src/test/rustdoc/intra-doc/primitive-disambiguators.rs @@ -0,0 +1,4 @@ +#![deny(rustdoc::broken_intra_doc_links)] +// @has primitive_disambiguators/index.html +// @has - '//a/@href' '{{channel}}/std/primitive.str.html#method.trim' +//! [str::trim()] diff --git a/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs b/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs new file mode 100644 index 000000000..474bf3477 --- /dev/null +++ b/src/test/rustdoc/intra-doc/primitive-non-default-impl.rs @@ -0,0 +1,31 @@ +#![deny(rustdoc::broken_intra_doc_links)] + + +// @has primitive_non_default_impl/fn.str_methods.html +/// [`str::trim`] +// @has - '//*[@href="{{channel}}/std/primitive.str.html#method.trim"]' 'str::trim' +/// [`str::to_lowercase`] +// @has - '//*[@href="{{channel}}/std/primitive.str.html#method.to_lowercase"]' 'str::to_lowercase' +/// [`str::into_boxed_bytes`] +// @has - '//*[@href="{{channel}}/std/primitive.str.html#method.into_boxed_bytes"]' 'str::into_boxed_bytes' +/// [`str::replace`] +// @has - '//*[@href="{{channel}}/std/primitive.str.html#method.replace"]' 'str::replace' +pub fn str_methods() {} + +// @has primitive_non_default_impl/fn.f32_methods.html +/// [f32::powi] +// @has - '//*[@href="{{channel}}/std/primitive.f32.html#method.powi"]' 'f32::powi' +/// [f32::sqrt] +// @has - '//*[@href="{{channel}}/std/primitive.f32.html#method.sqrt"]' 'f32::sqrt' +/// [f32::mul_add] +// @has - '//*[@href="{{channel}}/std/primitive.f32.html#method.mul_add"]' 'f32::mul_add' +pub fn f32_methods() {} + +// @has primitive_non_default_impl/fn.f64_methods.html +/// [`f64::powi`] +// @has - '//*[@href="{{channel}}/std/primitive.f64.html#method.powi"]' 'f64::powi' +/// [`f64::sqrt`] +// @has - '//*[@href="{{channel}}/std/primitive.f64.html#method.sqrt"]' 'f64::sqrt' +/// [`f64::mul_add`] +// @has - '//*[@href="{{channel}}/std/primitive.f64.html#method.mul_add"]' 'f64::mul_add' +pub fn f64_methods() {} diff --git a/src/test/rustdoc/intra-doc/private-failures-ignored.rs b/src/test/rustdoc/intra-doc/private-failures-ignored.rs new file mode 100644 index 000000000..b272bfb5a --- /dev/null +++ b/src/test/rustdoc/intra-doc/private-failures-ignored.rs @@ -0,0 +1,8 @@ +// Rustdoc would previously report resolution failures on items that weren't in the public docs. +// These failures were legitimate, but not truly relevant - the docs in question couldn't be +// checked for accuracy anyway. + +#![deny(rustdoc::broken_intra_doc_links)] + +/// ooh, i'm a [rebel] just for kicks +struct SomeStruct; diff --git a/src/test/rustdoc/intra-doc/private.rs b/src/test/rustdoc/intra-doc/private.rs new file mode 100644 index 000000000..349091e93 --- /dev/null +++ b/src/test/rustdoc/intra-doc/private.rs @@ -0,0 +1,20 @@ +// compile-flags: --document-private-items + +// make sure to update `rustdoc-ui/intra-doc/private.rs` if you update this file + +#![allow(rustdoc::private_intra_doc_links)] + +#![crate_name = "private"] + +/// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] +// @has private/struct.DocMe.html '//*a[@href="struct.DontDocMe.html"]' 'DontDocMe' +// @has private/struct.DocMe.html '//*a[@href="struct.DontDocMe.html#method.f"]' 'DontDocMe::f' +// @has private/struct.DocMe.html '//*a[@href="struct.DontDocMe.html#structfield.x"]' 'DontDocMe::x' +pub struct DocMe; +struct DontDocMe { + x: usize, +} + +impl DontDocMe { + fn f() {} +} diff --git a/src/test/rustdoc/intra-doc/proc-macro.rs b/src/test/rustdoc/intra-doc/proc-macro.rs new file mode 100644 index 000000000..78379a902 --- /dev/null +++ b/src/test/rustdoc/intra-doc/proc-macro.rs @@ -0,0 +1,27 @@ +// aux-build:proc-macro-macro.rs +// build-aux-docs +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate proc_macro_macro; + + +pub use proc_macro_macro::{DeriveA, attr_a}; +use proc_macro_macro::{DeriveB, attr_b}; + +// @has proc_macro/struct.Foo.html +// @has - '//a/@href' 'derive.DeriveA.html' +// @has - '//a/@href' 'attr.attr_a.html' +// @has - '//a/@href' 'trait.DeriveTrait.html' +// @has - '//a/@href' '../proc_macro_macro/derive.DeriveB.html' +// @has - '//a/@href' '../proc_macro_macro/attr.attr_b.html' +/// Link to [DeriveA], [attr_a], [DeriveB], [attr_b], [DeriveTrait] +pub struct Foo; + +// @has proc_macro/struct.Bar.html +// @has - '//a/@href' 'derive.DeriveA.html' +// @has - '//a/@href' 'attr.attr_a.html' +/// Link to [deriveA](derive@DeriveA) [attr](macro@attr_a) +pub struct Bar; + +// this should not cause ambiguity errors +pub trait DeriveTrait {} diff --git a/src/test/rustdoc/intra-doc/pub-use.rs b/src/test/rustdoc/intra-doc/pub-use.rs new file mode 100644 index 000000000..8a998496c --- /dev/null +++ b/src/test/rustdoc/intra-doc/pub-use.rs @@ -0,0 +1,17 @@ +// aux-build: intra-link-pub-use.rs +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "outer"] + +extern crate inner; + +/// [mod@std::env] [g] +// @has outer/index.html +// @has - '//a[@href="{{channel}}/std/env/index.html"]' "std::env" +// @has - '//a[@href="fn.f.html"]' "g" +pub use f as g; + +// Make sure the documentation is actually correct by documenting an inlined re-export +/// [mod@std::env] +// @has outer/fn.f.html +// @has - '//a[@href="{{channel}}/std/env/index.html"]' "std::env" +pub use inner::f; diff --git a/src/test/rustdoc/intra-doc/raw-ident-self.rs b/src/test/rustdoc/intra-doc/raw-ident-self.rs new file mode 100644 index 000000000..1ed33db93 --- /dev/null +++ b/src/test/rustdoc/intra-doc/raw-ident-self.rs @@ -0,0 +1,13 @@ +#![deny(rustdoc::broken_intra_doc_links)] +pub mod r#impl { + pub struct S; + + impl S { + /// See [Self::b]. + // @has raw_ident_self/impl/struct.S.html + // @has - '//a[@href="struct.S.html#method.b"]' 'Self::b' + pub fn a() {} + + pub fn b() {} + } +} diff --git a/src/test/rustdoc/intra-doc/reexport-additional-docs.rs b/src/test/rustdoc/intra-doc/reexport-additional-docs.rs new file mode 100644 index 000000000..64683bacd --- /dev/null +++ b/src/test/rustdoc/intra-doc/reexport-additional-docs.rs @@ -0,0 +1,23 @@ +// aux-build:intra-link-reexport-additional-docs.rs +// build-aux-docs +#![crate_name = "foo"] +extern crate inner; + +// @has foo/struct.Inner.html '//a[@href="fn.with_code.html"]' 'crate::with_code' +/// [crate::with_code] +// @has - '//a[@href="fn.with_code.html"]' 'different text' +/// [different text][with_code] +// @has - '//a[@href="fn.me_too.html"]' 'me_too' +#[doc = "[me_too]"] +// @has - '//a[@href="fn.me_three.html"]' 'reference link' +/// This [reference link] +#[doc = "has an attr in the way"] +/// +/// [reference link]: me_three +// Should still resolve links from the original module in that scope +// @has - '//a[@href="../inner/fn.f.html"]' 'f()' +pub use inner::Inner; + +pub fn with_code() {} +pub fn me_too() {} +pub fn me_three() {} diff --git a/src/test/rustdoc/intra-doc/self-cache.rs b/src/test/rustdoc/intra-doc/self-cache.rs new file mode 100644 index 000000000..63bf7fa57 --- /dev/null +++ b/src/test/rustdoc/intra-doc/self-cache.rs @@ -0,0 +1,14 @@ +#![crate_name = "foo"] +// @has foo/enum.E1.html '//a/@href' 'enum.E1.html#variant.A' + +/// [Self::A::b] +pub enum E1 { + A { b: usize } +} + +// @has foo/enum.E2.html '//a/@href' 'enum.E2.html#variant.A' + +/// [Self::A::b] +pub enum E2 { + A { b: usize } +} diff --git a/src/test/rustdoc/intra-doc/self.rs b/src/test/rustdoc/intra-doc/self.rs new file mode 100644 index 000000000..0ba7df8a7 --- /dev/null +++ b/src/test/rustdoc/intra-doc/self.rs @@ -0,0 +1,116 @@ +#![crate_name = "foo"] + + +// @has foo/index.html '//a/@href' 'struct.Foo.html#method.new' +// @has foo/struct.Foo.html '//a/@href' 'struct.Foo.html#method.new' + +/// Use [`new`] to create a new instance. +/// +/// [`new`]: Self::new +pub struct Foo; + +impl Foo { + pub fn new() -> Self { + unimplemented!() + } +} + +// @has foo/index.html '//a/@href' 'struct.Bar.html#method.new2' +// @has foo/struct.Bar.html '//a/@href' 'struct.Bar.html#method.new2' + +/// Use [`new2`] to create a new instance. +/// +/// [`new2`]: Self::new2 +pub struct Bar; + +impl Bar { + pub fn new2() -> Self { + unimplemented!() + } +} + +pub struct MyStruct { + // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#structfield.struct_field' + + /// [`struct_field`] + /// + /// [`struct_field`]: Self::struct_field + pub struct_field: u8, +} + +pub enum MyEnum { + // @has foo/enum.MyEnum.html '//a/@href' 'enum.MyEnum.html#variant.EnumVariant' + + /// [`EnumVariant`] + /// + /// [`EnumVariant`]: Self::EnumVariant + EnumVariant, +} + +pub union MyUnion { + // @has foo/union.MyUnion.html '//a/@href' 'union.MyUnion.html#structfield.union_field' + + /// [`union_field`] + /// + /// [`union_field`]: Self::union_field + pub union_field: f32, +} + +pub trait MyTrait { + // @has foo/trait.MyTrait.html '//a/@href' 'trait.MyTrait.html#associatedtype.AssoType' + + /// [`AssoType`] + /// + /// [`AssoType`]: Self::AssoType + type AssoType; + + // @has foo/trait.MyTrait.html '//a/@href' 'trait.MyTrait.html#associatedconstant.ASSO_CONST' + + /// [`ASSO_CONST`] + /// + /// [`ASSO_CONST`]: Self::ASSO_CONST + const ASSO_CONST: i32 = 1; + + // @has foo/trait.MyTrait.html '//a/@href' 'trait.MyTrait.html#method.asso_fn' + + /// [`asso_fn`] + /// + /// [`asso_fn`]: Self::asso_fn + fn asso_fn() {} +} + +impl MyStruct { + // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#method.for_impl' + + /// [`for_impl`] + /// + /// [`for_impl`]: Self::for_impl + pub fn for_impl() { + unimplemented!() + } +} + +impl MyTrait for MyStruct { + // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedtype.AssoType' + + /// [`AssoType`] + /// + /// [`AssoType`]: Self::AssoType + type AssoType = u32; + + // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedconstant.ASSO_CONST' + + /// [`ASSO_CONST`] + /// + /// [`ASSO_CONST`]: Self::ASSO_CONST + const ASSO_CONST: i32 = 10; + + // @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#method.asso_fn' + + /// [`asso_fn`] + /// + /// [`asso_fn`]: Self::asso_fn + fn asso_fn() { + unimplemented!() + } +} diff --git a/src/test/rustdoc/intra-doc/trait-impl.rs b/src/test/rustdoc/intra-doc/trait-impl.rs new file mode 100644 index 000000000..cf60dc1db --- /dev/null +++ b/src/test/rustdoc/intra-doc/trait-impl.rs @@ -0,0 +1,34 @@ +#![crate_name = "foo"] + + +pub struct MyStruct; + +impl MyTrait for MyStruct { + +// @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedtype.AssoType' + + /// [`AssoType`] + /// + /// [`AssoType`]: MyStruct::AssoType + type AssoType = u32; + +// @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#associatedconstant.ASSO_CONST' + + /// [`ASSO_CONST`] + /// + /// [`ASSO_CONST`]: MyStruct::ASSO_CONST + const ASSO_CONST: i32 = 10; + +// @has foo/struct.MyStruct.html '//a/@href' 'struct.MyStruct.html#method.trait_fn' + + /// [`trait_fn`] + /// + /// [`trait_fn`]: MyStruct::trait_fn + fn trait_fn() { } +} + +pub trait MyTrait { + type AssoType; + const ASSO_CONST: i32 = 1; + fn trait_fn(); +} diff --git a/src/test/rustdoc/intra-doc/trait-item.rs b/src/test/rustdoc/intra-doc/trait-item.rs new file mode 100644 index 000000000..e95dba33b --- /dev/null +++ b/src/test/rustdoc/intra-doc/trait-item.rs @@ -0,0 +1,11 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// Link to [S::assoc_fn()] +/// Link to [Default::default()] +// @has trait_item/struct.S.html '//*[@href="struct.S.html#method.assoc_fn"]' 'S::assoc_fn()' +// @has - '//*[@href="{{channel}}/core/default/trait.Default.html#tymethod.default"]' 'Default::default()' +pub struct S; + +impl S { + pub fn assoc_fn() {} +} diff --git a/src/test/rustdoc/intra-doc/true-false.rs b/src/test/rustdoc/intra-doc/true-false.rs new file mode 100644 index 000000000..e02be9cab --- /dev/null +++ b/src/test/rustdoc/intra-doc/true-false.rs @@ -0,0 +1,8 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +// @has foo/index.html +// @has - '//*[@id="main-content"]//a[@href="{{channel}}/std/primitive.bool.html"]' 'true' +// @has - '//*[@id="main-content"]//a[@href="{{channel}}/std/primitive.bool.html"]' 'false' + +//! A `bool` is either [`true`] or [`false`]. diff --git a/src/test/rustdoc/intra-doc/type-alias.rs b/src/test/rustdoc/intra-doc/type-alias.rs new file mode 100644 index 000000000..6c52082a2 --- /dev/null +++ b/src/test/rustdoc/intra-doc/type-alias.rs @@ -0,0 +1,19 @@ +// Regression test for issue #86120. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Foo; + +/// You should really try [`Self::bar`]! +pub type Bar = Foo; + +impl Bar { + pub fn bar() {} +} + +/// The minimum is [`Self::MIN`]. +pub type Int = i32; + +// @has foo/type.Bar.html '//a[@href="struct.Foo.html#method.bar"]' 'Self::bar' +// @has foo/type.Int.html '//a[@href="{{channel}}/std/primitive.i32.html#associatedconstant.MIN"]' 'Self::MIN' |