diff options
Diffstat (limited to 'tests/rustdoc-ui/intra-doc')
67 files changed, 2132 insertions, 0 deletions
diff --git a/tests/rustdoc-ui/intra-doc/alias-ice.rs b/tests/rustdoc-ui/intra-doc/alias-ice.rs new file mode 100644 index 000000000..51922caeb --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/alias-ice.rs @@ -0,0 +1,6 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +pub type TypeAlias = usize; + +/// [broken cross-reference](TypeAlias::hoge) //~ ERROR +pub fn some_public_item() {} diff --git a/tests/rustdoc-ui/intra-doc/alias-ice.stderr b/tests/rustdoc-ui/intra-doc/alias-ice.stderr new file mode 100644 index 000000000..5e7ffeeb8 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/alias-ice.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `TypeAlias::hoge` + --> $DIR/alias-ice.rs:5:30 + | +LL | /// [broken cross-reference](TypeAlias::hoge) + | ^^^^^^^^^^^^^^^ the type alias `TypeAlias` has no associated item named `hoge` + | +note: the lint level is defined here + --> $DIR/alias-ice.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/intra-doc/ambiguity.rs b/tests/rustdoc-ui/intra-doc/ambiguity.rs new file mode 100644 index 000000000..1f3dc722e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ambiguity.rs @@ -0,0 +1,40 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +pub fn ambiguous() {} + +pub struct ambiguous {} + +#[macro_export] +macro_rules! multi_conflict { () => {} } + +#[allow(non_camel_case_types)] +pub struct multi_conflict {} + +pub fn multi_conflict() {} + +pub mod type_and_value {} + +pub const type_and_value: i32 = 0; + +pub mod foo { + pub enum bar {} + + pub fn bar() {} +} + +/// [`ambiguous`] is ambiguous. //~ERROR `ambiguous` +/// +/// [ambiguous] is ambiguous. //~ERROR ambiguous +/// +/// [`multi_conflict`] is a three-way conflict. //~ERROR `multi_conflict` +/// +/// Ambiguous [type_and_value]. //~ERROR type_and_value +/// +/// Ambiguous non-implied shortcut link [`foo::bar`]. //~ERROR `foo::bar` +pub struct Docs {} + +/// [true] //~ ERROR `true` is both a module and a builtin type +/// [primitive@true] +pub mod r#true {} diff --git a/tests/rustdoc-ui/intra-doc/ambiguity.stderr b/tests/rustdoc-ui/intra-doc/ambiguity.stderr new file mode 100644 index 000000000..7974796e4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ambiguity.stderr @@ -0,0 +1,101 @@ +error: `true` is both a module and a builtin type + --> $DIR/ambiguity.rs:38:6 + | +LL | /// [true] + | ^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/ambiguity.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@true] + | ++++ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@true] + | +++++ + +error: `ambiguous` is both a struct and a function + --> $DIR/ambiguity.rs:27:7 + | +LL | /// [`ambiguous`] is ambiguous. + | ^^^^^^^^^ ambiguous link + | +help: to link to the struct, prefix with `struct@` + | +LL | /// [`struct@ambiguous`] is ambiguous. + | +++++++ +help: to link to the function, add parentheses + | +LL | /// [`ambiguous()`] is ambiguous. + | ++ + +error: `ambiguous` is both a struct and a function + --> $DIR/ambiguity.rs:29:6 + | +LL | /// [ambiguous] is ambiguous. + | ^^^^^^^^^ ambiguous link + | +help: to link to the struct, prefix with `struct@` + | +LL | /// [struct@ambiguous] is ambiguous. + | +++++++ +help: to link to the function, add parentheses + | +LL | /// [ambiguous()] is ambiguous. + | ++ + +error: `multi_conflict` is a struct, a function, and a macro + --> $DIR/ambiguity.rs:31:7 + | +LL | /// [`multi_conflict`] is a three-way conflict. + | ^^^^^^^^^^^^^^ ambiguous link + | +help: to link to the struct, prefix with `struct@` + | +LL | /// [`struct@multi_conflict`] is a three-way conflict. + | +++++++ +help: to link to the function, add parentheses + | +LL | /// [`multi_conflict()`] is a three-way conflict. + | ++ +help: to link to the macro, add an exclamation mark + | +LL | /// [`multi_conflict!`] is a three-way conflict. + | + + +error: `type_and_value` is both a module and a constant + --> $DIR/ambiguity.rs:33:16 + | +LL | /// Ambiguous [type_and_value]. + | ^^^^^^^^^^^^^^ ambiguous link + | +help: to link to the module, prefix with `mod@` + | +LL | /// Ambiguous [mod@type_and_value]. + | ++++ +help: to link to the constant, prefix with `const@` + | +LL | /// Ambiguous [const@type_and_value]. + | ++++++ + +error: `foo::bar` is both an enum and a function + --> $DIR/ambiguity.rs:35:43 + | +LL | /// Ambiguous non-implied shortcut link [`foo::bar`]. + | ^^^^^^^^ ambiguous link + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Ambiguous non-implied shortcut link [`enum@foo::bar`]. + | +++++ +help: to link to the function, add parentheses + | +LL | /// Ambiguous non-implied shortcut link [`foo::bar()`]. + | ++ + +error: aborting due to 6 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/anchors.rs b/tests/rustdoc-ui/intra-doc/anchors.rs new file mode 100644 index 000000000..34e11c7c7 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/anchors.rs @@ -0,0 +1,39 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +// A few tests on anchors. + +/// Hello people. +/// +/// You can anchors? Here's one! +/// +/// # hola +/// +/// Isn't it amazing? +pub struct Foo { + pub f: u8, +} + +pub enum Enum { + A, + B, +} + +/// Have you heard about stuff? +/// +/// Like [Foo#hola]. +/// +/// Or maybe [Foo::f#hola]. +//~^ ERROR `Foo::f#hola` contains an anchor +pub fn foo() {} + +/// Empty. +/// +/// Another anchor error: [hello#people#!]. +//~^ ERROR `hello#people#!` contains multiple anchors +pub fn bar() {} + +/// Empty? +/// +/// Damn enum's variants: [Enum::A#whatever]. +//~^ ERROR `Enum::A#whatever` contains an anchor +pub fn enum_link() {} diff --git a/tests/rustdoc-ui/intra-doc/anchors.stderr b/tests/rustdoc-ui/intra-doc/anchors.stderr new file mode 100644 index 000000000..0d226b277 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/anchors.stderr @@ -0,0 +1,32 @@ +error: `Foo::f#hola` contains an anchor, but links to fields are already anchored + --> $DIR/anchors.rs:25:15 + | +LL | /// Or maybe [Foo::f#hola]. + | ^^^^^^----- + | | + | invalid anchor + | +note: the lint level is defined here + --> $DIR/anchors.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `hello#people#!` contains multiple anchors + --> $DIR/anchors.rs:31:28 + | +LL | /// Another anchor error: [hello#people#!]. + | ^^^^^^^^^^^^-- + | | + | invalid anchor + +error: `Enum::A#whatever` contains an anchor, but links to variants are already anchored + --> $DIR/anchors.rs:37:28 + | +LL | /// Damn enum's variants: [Enum::A#whatever]. + | ^^^^^^^--------- + | | + | invalid anchor + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/assoc-field.rs b/tests/rustdoc-ui/intra-doc/assoc-field.rs new file mode 100644 index 000000000..e18404e44 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/assoc-field.rs @@ -0,0 +1,26 @@ +// Traits in scope are collected for doc links in field attributes. + +// check-pass +// aux-build: assoc-field-dep.rs + +extern crate assoc_field_dep; +pub use assoc_field_dep::*; + +#[derive(Clone)] +pub struct Struct; + +pub mod mod1 { + pub struct Fields { + /// [crate::Struct::clone] + pub field: u8, + } +} + +pub mod mod2 { + pub enum Fields { + V { + /// [crate::Struct::clone] + field: u8, + }, + } +} diff --git a/tests/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs b/tests/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs new file mode 100644 index 000000000..b4ce3443c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs @@ -0,0 +1,19 @@ +// Traits in scope are collected for doc links in both outer and inner module attributes. + +// check-pass +// aux-build: assoc-mod-inner-outer-dep.rs + +extern crate assoc_mod_inner_outer_dep; +pub use assoc_mod_inner_outer_dep::*; + +#[derive(Clone)] +pub struct Struct; + +pub mod outer1 { + /// [crate::Struct::clone] + pub mod inner {} +} + +pub mod outer2 { + //! [crate::Struct::clone] +} diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs b/tests/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs new file mode 100644 index 000000000..cfb24fc2c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs @@ -0,0 +1,18 @@ +#[derive(Clone)] +pub struct Struct; + +pub mod dep_mod1 { + pub struct Fields { + /// [crate::Struct::clone] + pub field: u8, + } +} + +pub mod dep_mod2 { + pub enum Fields { + V { + /// [crate::Struct::clone] + field: u8, + }, + } +} diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs b/tests/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs new file mode 100644 index 000000000..7a11a1657 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs @@ -0,0 +1,11 @@ +#[derive(Clone)] +pub struct Struct; + +pub mod dep_outer1 { + /// [crate::Struct::clone] + pub mod inner {} +} + +pub mod dep_outer2 { + //! [crate::Struct::clone] +} diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/dep1.rs b/tests/rustdoc-ui/intra-doc/auxiliary/dep1.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/dep1.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/dep2.rs b/tests/rustdoc-ui/intra-doc/auxiliary/dep2.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/dep2.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/dep3.rs b/tests/rustdoc-ui/intra-doc/auxiliary/dep3.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/dep3.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/dep4.rs b/tests/rustdoc-ui/intra-doc/auxiliary/dep4.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/dep4.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/intra-doc-broken.rs b/tests/rustdoc-ui/intra-doc/auxiliary/intra-doc-broken.rs new file mode 100644 index 000000000..31a8310d4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/intra-doc-broken.rs @@ -0,0 +1,4 @@ +#![crate_name = "intra_doc_broken"] + +/// [not_found] +pub fn foo() {} diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/pointer-reexports-allowed.rs b/tests/rustdoc-ui/intra-doc/auxiliary/pointer-reexports-allowed.rs new file mode 100644 index 000000000..0a3dc57f1 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/pointer-reexports-allowed.rs @@ -0,0 +1,4 @@ +#![feature(intra_doc_pointers)] +#![crate_name = "inner"] +/// Link to [some pointer](*const::to_raw_parts) +pub fn foo() {} diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/through-proc-macro-aux.rs b/tests/rustdoc-ui/intra-doc/auxiliary/through-proc-macro-aux.rs new file mode 100644 index 000000000..5c4a01ee3 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/through-proc-macro-aux.rs @@ -0,0 +1,20 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] +#![crate_name="some_macros"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream { + item // This doesn't erase the spans. +} + +#[proc_macro_attribute] +pub fn second(_attr: TokenStream, item: TokenStream) -> TokenStream { + // Make a new `TokenStream` to erase the spans: + let mut out: TokenStream = TokenStream::new(); + out.extend(item); + out +} diff --git a/tests/rustdoc-ui/intra-doc/broken-reexport.rs b/tests/rustdoc-ui/intra-doc/broken-reexport.rs new file mode 100644 index 000000000..862faa50b --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/broken-reexport.rs @@ -0,0 +1,8 @@ +// aux-build:intra-doc-broken.rs +// check-pass + +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate intra_doc_broken; + +pub use intra_doc_broken::foo; diff --git a/tests/rustdoc-ui/intra-doc/crate-nonexistent.rs b/tests/rustdoc-ui/intra-doc/crate-nonexistent.rs new file mode 100644 index 000000000..ceecfa681 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/crate-nonexistent.rs @@ -0,0 +1,5 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// [crate::DoesNotExist] +//~^ ERROR unresolved link to `crate::DoesNotExist` +pub struct Item; diff --git a/tests/rustdoc-ui/intra-doc/crate-nonexistent.stderr b/tests/rustdoc-ui/intra-doc/crate-nonexistent.stderr new file mode 100644 index 000000000..a69b1c52a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/crate-nonexistent.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `crate::DoesNotExist` + --> $DIR/crate-nonexistent.rs:3:6 + | +LL | /// [crate::DoesNotExist] + | ^^^^^^^^^^^^^^^^^^^ no item named `DoesNotExist` in module `crate_nonexistent` + | +note: the lint level is defined here + --> $DIR/crate-nonexistent.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs new file mode 100644 index 000000000..2d6656611 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs @@ -0,0 +1,81 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined +pub enum S {} +fn S() {} + +#[macro_export] +macro_rules! m { + () => {}; +} + +static s: usize = 0; +const c: usize = 0; + +trait T {} + +/// Link to [struct@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [mod@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [union@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [trait@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [struct@T] +//~^ ERROR incompatible link kind for `T` +//~| NOTE this link resolved +//~| HELP prefix with `trait@` + +/// Link to [derive@m] +//~^ ERROR incompatible link kind for `m` +//~| NOTE this link resolved +//~| HELP add an exclamation mark + +/// Link to [m()] +//~^ ERROR unresolved link to `m` +//~| NOTE this link resolves to the macro `m` +//~| HELP add an exclamation mark +/// and to [m!()] + +/// Link to [const@s] +//~^ ERROR incompatible link kind for `s` +//~| NOTE this link resolved +//~| HELP prefix with `static@` + +/// Link to [static@c] +//~^ ERROR incompatible link kind for `c` +//~| NOTE this link resolved +//~| HELP prefix with `const@` + +/// Link to [fn@c] +//~^ ERROR incompatible link kind for `c` +//~| NOTE this link resolved +//~| HELP prefix with `const@` + +/// Link to [c()] +//~^ ERROR incompatible link kind for `c` +//~| NOTE this link resolved +//~| HELP prefix with `const@` + +/// Link to [const@f] +//~^ ERROR incompatible link kind for `f` +//~| NOTE this link resolved +//~| HELP add parentheses + +/// Link to [fn@std] +//~^ ERROR unresolved link to `std` +//~| NOTE this link resolves to the crate `std` +//~| HELP to link to the crate, prefix with `mod@` +pub fn f() {} diff --git a/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr new file mode 100644 index 000000000..ee35749ce --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr @@ -0,0 +1,153 @@ +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:16:14 + | +LL | /// Link to [struct@S] + | ^^^^^^^^ this link resolved to an enum, which is not a struct + | +note: the lint level is defined here + --> $DIR/disambiguator-mismatch.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:21:14 + | +LL | /// Link to [mod@S] + | ^^^^^ this link resolved to an enum, which is not a module + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:26:14 + | +LL | /// Link to [union@S] + | ^^^^^^^ this link resolved to an enum, which is not a union + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:31:14 + | +LL | /// Link to [trait@S] + | ^^^^^^^ this link resolved to an enum, which is not a trait + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `T` + --> $DIR/disambiguator-mismatch.rs:36:14 + | +LL | /// Link to [struct@T] + | ^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL | /// Link to [trait@T] + | ~~~~~~ + +error: incompatible link kind for `m` + --> $DIR/disambiguator-mismatch.rs:41:14 + | +LL | /// Link to [derive@m] + | ^^^^^^^^ this link resolved to a macro, which is not a derive macro + | +help: to link to the macro, add an exclamation mark + | +LL - /// Link to [derive@m] +LL + /// Link to [m!] + | + +error: unresolved link to `m` + --> $DIR/disambiguator-mismatch.rs:46:14 + | +LL | /// Link to [m()] + | ^^^ this link resolves to the macro `m`, which is not in the value namespace + | +help: to link to the macro, add an exclamation mark + | +LL | /// Link to [m!()] + | + + +error: incompatible link kind for `s` + --> $DIR/disambiguator-mismatch.rs:52:14 + | +LL | /// Link to [const@s] + | ^^^^^^^ this link resolved to a static, which is not a constant + | +help: to link to the static, prefix with `static@` + | +LL | /// Link to [static@s] + | ~~~~~~~ + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:57:14 + | +LL | /// Link to [static@c] + | ^^^^^^^^ this link resolved to a constant, which is not a static + | +help: to link to the constant, prefix with `const@` + | +LL | /// Link to [const@c] + | ~~~~~~ + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:62:14 + | +LL | /// Link to [fn@c] + | ^^^^ this link resolved to a constant, which is not a function + | +help: to link to the constant, prefix with `const@` + | +LL | /// Link to [const@c] + | ~~~~~~ + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:67:14 + | +LL | /// Link to [c()] + | ^^^ this link resolved to a constant, which is not a function + | +help: to link to the constant, prefix with `const@` + | +LL - /// Link to [c()] +LL + /// Link to [const@c] + | + +error: incompatible link kind for `f` + --> $DIR/disambiguator-mismatch.rs:72:14 + | +LL | /// Link to [const@f] + | ^^^^^^^ this link resolved to a function, which is not a constant + | +help: to link to the function, add parentheses + | +LL - /// Link to [const@f] +LL + /// Link to [f()] + | + +error: unresolved link to `std` + --> $DIR/disambiguator-mismatch.rs:77:14 + | +LL | /// Link to [fn@std] + | ^^^^^^ this link resolves to the crate `std`, which is not in the value namespace + | +help: to link to the crate, prefix with `mod@` + | +LL | /// Link to [mod@std] + | ~~~~ + +error: aborting due to 13 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/double-anchor.rs b/tests/rustdoc-ui/intra-doc/double-anchor.rs new file mode 100644 index 000000000..a01211c4f --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/double-anchor.rs @@ -0,0 +1,7 @@ +// check-pass + +// regression test for #73264 +// should only give one error +/// docs [label][with#anchor#error] +//~^ WARNING multiple anchors +pub struct S; diff --git a/tests/rustdoc-ui/intra-doc/double-anchor.stderr b/tests/rustdoc-ui/intra-doc/double-anchor.stderr new file mode 100644 index 000000000..6addb010e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/double-anchor.stderr @@ -0,0 +1,12 @@ +warning: `with#anchor#error` contains multiple anchors + --> $DIR/double-anchor.rs:5:18 + | +LL | /// docs [label][with#anchor#error] + | ^^^^^^^^^^^------ + | | + | invalid anchor + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/intra-doc/email-address-localhost.rs b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs new file mode 100644 index 000000000..7a5156e81 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -0,0 +1,7 @@ +// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +// check-pass +#![deny(warnings)] + +//! Email me at <hello@localhost>. + +//! This should *not* warn: <hello@example.com>. diff --git a/tests/rustdoc-ui/intra-doc/errors.rs b/tests/rustdoc-ui/intra-doc/errors.rs new file mode 100644 index 000000000..b29f7c29b --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/errors.rs @@ -0,0 +1,105 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined + +// FIXME: this should say that it was skipped (maybe an allowed by default lint?) +/// [invalid intra-doc syntax!!] + +/// [path::to::nonexistent::module] +//~^ ERROR unresolved link +//~| NOTE no item named `path` in scope + +/// [path::to::nonexistent::macro!] +//~^ ERROR unresolved link +//~| NOTE no item named `path` in scope + +/// [type@path::to::nonexistent::type] +//~^ ERROR unresolved link +//~| NOTE no item named `path` in scope + +/// [std::io::not::here] +//~^ ERROR unresolved link +//~| NOTE no item named `not` in module `io` + +/// [type@std::io::not::here] +//~^ ERROR unresolved link +//~| NOTE no item named `not` in module `io` + +/// [std::io::Error::x] +//~^ ERROR unresolved link +//~| NOTE the struct `Error` has no field + +/// [std::io::ErrorKind::x] +//~^ ERROR unresolved link +//~| NOTE the enum `ErrorKind` has no variant + +/// [f::A] +//~^ ERROR unresolved link +//~| NOTE `f` is a function, not a module + +/// [f::A!] +//~^ ERROR unresolved link +//~| NOTE `f` is a function, not a module + +/// [S::A] +//~^ ERROR unresolved link +//~| NOTE struct `S` has no field or associated item + +/// [S::fmt] +//~^ ERROR unresolved link +//~| NOTE struct `S` has no field or associated item + +/// [E::D] +//~^ ERROR unresolved link +//~| NOTE enum `E` has no variant or associated item + +/// [u8::not_found] +//~^ ERROR unresolved link +//~| NOTE the builtin type `u8` has no associated item named `not_found` + +/// [std::primitive::u8::not_found] +//~^ ERROR unresolved link +//~| NOTE the builtin type `u8` has no associated item named `not_found` + +/// [type@Vec::into_iter] +//~^ ERROR unresolved link +//~| HELP to link to the associated function, add parentheses +//~| NOTE this link resolves to the associated function `into_iter` + +/// [S!] +//~^ ERROR unresolved link +//~| HELP to link to the struct, prefix with `struct@` +//~| NOTE this link resolves to the struct `S` +pub fn f() {} +#[derive(Debug)] +pub struct S; + +pub enum E { A, B, C } + +/// [type@S::h] +//~^ ERROR unresolved link +//~| HELP to link to the associated function +//~| NOTE not in the type namespace +impl S { + pub fn h() {} +} + +/// [type@T::g] +//~^ ERROR unresolved link +//~| HELP to link to the associated function +//~| NOTE not in the type namespace + +/// [T::h!] +//~^ ERROR unresolved link +//~| NOTE `T` has no macro named `h` +pub trait T { + fn g() {} +} + +/// [m()] +//~^ ERROR unresolved link +//~| HELP to link to the macro +//~| NOTE not in the value namespace +#[macro_export] +macro_rules! m { + () => {}; +} diff --git a/tests/rustdoc-ui/intra-doc/errors.stderr b/tests/rustdoc-ui/intra-doc/errors.stderr new file mode 100644 index 000000000..9a1896fb0 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/errors.stderr @@ -0,0 +1,157 @@ +error: unresolved link to `path::to::nonexistent::module` + --> $DIR/errors.rs:7:6 + | +LL | /// [path::to::nonexistent::module] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope + | +note: the lint level is defined here + --> $DIR/errors.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `path::to::nonexistent::macro` + --> $DIR/errors.rs:11:6 + | +LL | /// [path::to::nonexistent::macro!] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope + +error: unresolved link to `path::to::nonexistent::type` + --> $DIR/errors.rs:15:6 + | +LL | /// [type@path::to::nonexistent::type] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope + +error: unresolved link to `std::io::not::here` + --> $DIR/errors.rs:19:6 + | +LL | /// [std::io::not::here] + | ^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` + +error: unresolved link to `std::io::not::here` + --> $DIR/errors.rs:23:6 + | +LL | /// [type@std::io::not::here] + | ^^^^^^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` + +error: unresolved link to `std::io::Error::x` + --> $DIR/errors.rs:27:6 + | +LL | /// [std::io::Error::x] + | ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x` + +error: unresolved link to `std::io::ErrorKind::x` + --> $DIR/errors.rs:31:6 + | +LL | /// [std::io::ErrorKind::x] + | ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x` + +error: unresolved link to `f::A` + --> $DIR/errors.rs:35:6 + | +LL | /// [f::A] + | ^^^^ `f` is a function, not a module or type, and cannot have associated items + +error: unresolved link to `f::A` + --> $DIR/errors.rs:39:6 + | +LL | /// [f::A!] + | ^^^^^ `f` is a function, not a module or type, and cannot have associated items + +error: unresolved link to `S::A` + --> $DIR/errors.rs:43:6 + | +LL | /// [S::A] + | ^^^^ the struct `S` has no field or associated item named `A` + +error: unresolved link to `S::fmt` + --> $DIR/errors.rs:47:6 + | +LL | /// [S::fmt] + | ^^^^^^ the struct `S` has no field or associated item named `fmt` + +error: unresolved link to `E::D` + --> $DIR/errors.rs:51:6 + | +LL | /// [E::D] + | ^^^^ the enum `E` has no variant or associated item named `D` + +error: unresolved link to `u8::not_found` + --> $DIR/errors.rs:55:6 + | +LL | /// [u8::not_found] + | ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` + +error: unresolved link to `std::primitive::u8::not_found` + --> $DIR/errors.rs:59:6 + | +LL | /// [std::primitive::u8::not_found] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` + +error: unresolved link to `Vec::into_iter` + --> $DIR/errors.rs:63:6 + | +LL | /// [type@Vec::into_iter] + | ^^^^^^^^^^^^^^^^^^^ this link resolves to the associated function `into_iter`, which is not in the type namespace + | +help: to link to the associated function, add parentheses + | +LL - /// [type@Vec::into_iter] +LL + /// [Vec::into_iter()] + | + +error: unresolved link to `S` + --> $DIR/errors.rs:68:6 + | +LL | /// [S!] + | ^^ this link resolves to the struct `S`, which is not in the macro namespace + | +help: to link to the struct, prefix with `struct@` + | +LL - /// [S!] +LL + /// [struct@S] + | + +error: unresolved link to `S::h` + --> $DIR/errors.rs:78:6 + | +LL | /// [type@S::h] + | ^^^^^^^^^ this link resolves to the associated function `h`, which is not in the type namespace + | +help: to link to the associated function, add parentheses + | +LL - /// [type@S::h] +LL + /// [S::h()] + | + +error: unresolved link to `T::g` + --> $DIR/errors.rs:86:6 + | +LL | /// [type@T::g] + | ^^^^^^^^^ this link resolves to the associated function `g`, which is not in the type namespace + | +help: to link to the associated function, add parentheses + | +LL - /// [type@T::g] +LL + /// [T::g()] + | + +error: unresolved link to `T::h` + --> $DIR/errors.rs:91:6 + | +LL | /// [T::h!] + | ^^^^^ the trait `T` has no macro named `h` + +error: unresolved link to `m` + --> $DIR/errors.rs:98:6 + | +LL | /// [m()] + | ^^^ this link resolves to the macro `m`, which is not in the value namespace + | +help: to link to the macro, add an exclamation mark + | +LL | /// [m!()] + | + + +error: aborting due to 20 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/extern-crate-load.rs b/tests/rustdoc-ui/intra-doc/extern-crate-load.rs new file mode 100644 index 000000000..438c56aa5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/extern-crate-load.rs @@ -0,0 +1,26 @@ +// check-pass +// aux-crate:dep1=dep1.rs +// aux-crate:dep2=dep2.rs +// aux-crate:dep3=dep3.rs +// aux-crate:dep4=dep4.rs +#![deny(rustdoc::broken_intra_doc_links)] + +pub trait Trait { + /// [dep1] + type Item; +} + +pub struct S { + /// [dep2] + pub x: usize, +} + +extern "C" { + /// [dep3] + pub fn printf(); +} + +pub enum E { + /// [dep4] + A +} diff --git a/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs b/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs new file mode 100644 index 000000000..3cfac942c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs @@ -0,0 +1,6 @@ +//! [pointer::add] +//~^ ERROR: experimental +//! [pointer::wrapping_add] +//~^ ERROR: experimental +//! [pointer] // This is explicitly allowed +//! [reference] // This is explicitly allowed diff --git a/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr b/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr new file mode 100644 index 000000000..2c946ed48 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr @@ -0,0 +1,23 @@ +error[E0658]: linking to associated items of raw pointers is experimental + --> $DIR/feature-gate-intra-doc-pointers.rs:1:6 + | +LL | //! [pointer::add] + | ^^^^^^^^^^^^ + | + = note: see issue #80896 <https://github.com/rust-lang/rust/issues/80896> for more information + = help: add `#![feature(intra_doc_pointers)]` to the crate attributes to enable + = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does + +error[E0658]: linking to associated items of raw pointers is experimental + --> $DIR/feature-gate-intra-doc-pointers.rs:3:6 + | +LL | //! [pointer::wrapping_add] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #80896 <https://github.com/rust-lang/rust/issues/80896> for more information + = help: add `#![feature(intra_doc_pointers)]` to the crate attributes to enable + = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc-ui/intra-doc/field-ice.rs b/tests/rustdoc-ui/intra-doc/field-ice.rs new file mode 100644 index 000000000..c5d501e38 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/field-ice.rs @@ -0,0 +1,11 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^NOTE the lint level is defined here + +/// [`Foo::bar`] +/// [`Foo::bar()`] +//~^ERROR incompatible link kind for `Foo::bar` +//~|HELP to link to the field, remove the disambiguator +//~|NOTE this link resolved to a field, which is not a function +pub struct Foo { + pub bar: u8 +} diff --git a/tests/rustdoc-ui/intra-doc/field-ice.stderr b/tests/rustdoc-ui/intra-doc/field-ice.stderr new file mode 100644 index 000000000..f45a3ca61 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/field-ice.stderr @@ -0,0 +1,18 @@ +error: incompatible link kind for `Foo::bar` + --> $DIR/field-ice.rs:5:7 + | +LL | /// [`Foo::bar()`] + | ^^^^^^^^^^ this link resolved to a field, which is not a function + | +note: the lint level is defined here + --> $DIR/field-ice.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the field, remove the disambiguator + | +LL | /// [`Foo::bar`] + | ~~~~~~~~ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/intra-doc/global-path.rs b/tests/rustdoc-ui/intra-doc/global-path.rs new file mode 100644 index 000000000..cc7a5fa1c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/global-path.rs @@ -0,0 +1,8 @@ +// Doc link path with empty prefix that resolves to "extern prelude" instead of a module. + +// check-pass +// edition:2018 + +/// [::Unresolved] +//~^ WARN unresolved link to `::Unresolved` +pub struct Item; diff --git a/tests/rustdoc-ui/intra-doc/global-path.stderr b/tests/rustdoc-ui/intra-doc/global-path.stderr new file mode 100644 index 000000000..02379cd6c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/global-path.stderr @@ -0,0 +1,10 @@ +warning: unresolved link to `::Unresolved` + --> $DIR/global-path.rs:6:6 + | +LL | /// [::Unresolved] + | ^^^^^^^^^^^^ no item named `` in scope + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/intra-doc/html-as-generics-intra-doc.rs b/tests/rustdoc-ui/intra-doc/html-as-generics-intra-doc.rs new file mode 100644 index 000000000..b5470c859 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/html-as-generics-intra-doc.rs @@ -0,0 +1,25 @@ +#![deny(rustdoc::invalid_html_tags)] +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct ExistentStruct<T>(T); + +/// This [test][ExistentStruct<i32>] thing! +pub struct NoError; + +/// This [ExistentStruct<i32>] thing! +//~^ ERROR unclosed HTML tag `i32` +pub struct PartialErrorOnlyHtml; + +/// This [test][NonExistentStruct<i32>] thing! +//~^ ERROR unresolved link +pub struct PartialErrorOnlyResolve; + +/// This [NonExistentStruct2<i32>] thing! +//~^ ERROR unclosed HTML tag `i32` +//~| ERROR unresolved link +pub struct YesError; + +/// This [NonExistentStruct3<i32>][] thing! +//~^ ERROR unclosed HTML tag `i32` +//~| ERROR unresolved link +pub struct YesErrorCollapsed; diff --git a/tests/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr b/tests/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr new file mode 100644 index 000000000..7c81044db --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr @@ -0,0 +1,69 @@ +error: unresolved link to `NonExistentStruct` + --> $DIR/html-as-generics-intra-doc.rs:13:17 + | +LL | /// This [test][NonExistentStruct<i32>] thing! + | ^^^^^^^^^^^^^^^^^^^^^^ no item named `NonExistentStruct` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/html-as-generics-intra-doc.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `NonExistentStruct2` + --> $DIR/html-as-generics-intra-doc.rs:17:11 + | +LL | /// This [NonExistentStruct2<i32>] thing! + | ^^^^^^^^^^^^^^^^^^^^^^^ no item named `NonExistentStruct2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `NonExistentStruct3` + --> $DIR/html-as-generics-intra-doc.rs:22:11 + | +LL | /// This [NonExistentStruct3<i32>][] thing! + | ^^^^^^^^^^^^^^^^^^^^^^^ no item named `NonExistentStruct3` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-intra-doc.rs:9:25 + | +LL | /// This [ExistentStruct<i32>] thing! + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/html-as-generics-intra-doc.rs:1:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: try marking as source code + | +LL | /// This [`ExistentStruct<i32>`] thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-intra-doc.rs:17:29 + | +LL | /// This [NonExistentStruct2<i32>] thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This [`NonExistentStruct2<i32>`] thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-intra-doc.rs:22:29 + | +LL | /// This [NonExistentStruct3<i32>][] thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This [`NonExistentStruct3<i32>`][] thing! + | + + + +error: aborting due to 6 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs b/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs new file mode 100644 index 000000000..3088bcd46 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs @@ -0,0 +1,3 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//! [static@u8::MIN] +//~^ ERROR incompatible link kind diff --git a/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr b/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr new file mode 100644 index 000000000..c43cda3eb --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr @@ -0,0 +1,18 @@ +error: incompatible link kind for `u8::MIN` + --> $DIR/incompatible-primitive-disambiguator.rs:2:6 + | +LL | //! [static@u8::MIN] + | ^^^^^^^^^^^^^^ this link resolved to an associated constant, which is not a static + | +note: the lint level is defined here + --> $DIR/incompatible-primitive-disambiguator.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | //! [const@u8::MIN] + | ~~~~~~ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/intra-doc/macro-rules-error.rs b/tests/rustdoc-ui/intra-doc/macro-rules-error.rs new file mode 100644 index 000000000..8490584c1 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/macro-rules-error.rs @@ -0,0 +1,26 @@ +// `macro_rules` scopes are respected during doc link resolution. + +// compile-flags: --document-private-items + +#![deny(rustdoc::broken_intra_doc_links)] + +mod no_escape { + macro_rules! before_but_limited_to_module { + () => {}; + } +} + +/// [before_but_limited_to_module] +//~^ ERROR unresolved link to `before_but_limited_to_module` +/// [after] +//~^ ERROR unresolved link to `after` +/// [str] +fn check() {} + +macro_rules! after { + () => {}; +} + +macro_rules! str { + () => {}; +} diff --git a/tests/rustdoc-ui/intra-doc/macro-rules-error.stderr b/tests/rustdoc-ui/intra-doc/macro-rules-error.stderr new file mode 100644 index 000000000..6ad8084b0 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/macro-rules-error.stderr @@ -0,0 +1,23 @@ +error: unresolved link to `before_but_limited_to_module` + --> $DIR/macro-rules-error.rs:13:6 + | +LL | /// [before_but_limited_to_module] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `before_but_limited_to_module` in scope + | + = note: `macro_rules` named `before_but_limited_to_module` exists in this crate, but it is not in scope at this link's location +note: the lint level is defined here + --> $DIR/macro-rules-error.rs:5:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `after` + --> $DIR/macro-rules-error.rs:15:6 + | +LL | /// [after] + | ^^^^^ no item named `after` in scope + | + = note: `macro_rules` named `after` exists in this crate, but it is not in scope at this link's location + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/macro-rules.rs b/tests/rustdoc-ui/intra-doc/macro-rules.rs new file mode 100644 index 000000000..3aeb370ef --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/macro-rules.rs @@ -0,0 +1,24 @@ +// check-pass +#![allow(rustdoc::private_intra_doc_links)] + +macro_rules! foo { + () => {}; +} + +/// [foo!] +pub fn baz() {} + +#[macro_use] +mod macros { + macro_rules! escaping { + () => {}; + } +} + +pub mod inner { + /// [foo!] + /// [escaping] + pub fn baz() { + foo!(); + } +} diff --git a/tests/rustdoc-ui/intra-doc/malformed-generics.rs b/tests/rustdoc-ui/intra-doc/malformed-generics.rs new file mode 100644 index 000000000..161625ed2 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/malformed-generics.rs @@ -0,0 +1,28 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +//! [Vec<] //~ ERROR +//! [Vec<Box<T] //~ ERROR +//! [Vec<Box<T>] //~ ERROR +//~^ WARN +//! [Vec<Box<T>>>] //~ ERROR +//~^ WARN +//! [Vec<T>>>] //~ ERROR +//~^ WARN +//! [<Vec] //~ ERROR +//! [Vec::<] //~ ERROR +//! [<T>] //~ ERROR +//~^ WARN +//! [<invalid syntax>] //~ ERROR +//~^ WARN +//! [Vec:<T>:new()] //~ ERROR +//~^ WARN +//! [Vec<<T>>] //~ ERROR +//~^ WARN +//! [Vec<>] //~ ERROR +//! [Vec<<>>] //~ ERROR + +// FIXME(#74563) support UFCS +//! [<Vec as IntoIterator>::into_iter] //~ ERROR +//~^ WARN +//! [<Vec<T> as IntoIterator>::iter] //~ ERROR +//~^ WARN diff --git a/tests/rustdoc-ui/intra-doc/malformed-generics.stderr b/tests/rustdoc-ui/intra-doc/malformed-generics.stderr new file mode 100644 index 000000000..08349fef8 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/malformed-generics.stderr @@ -0,0 +1,158 @@ +error: unresolved link to `Vec<` + --> $DIR/malformed-generics.rs:3:6 + | +LL | //! [Vec<] + | ^^^^ unbalanced angle brackets + | +note: the lint level is defined here + --> $DIR/malformed-generics.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `Vec<Box<T` + --> $DIR/malformed-generics.rs:4:6 + | +LL | //! [Vec<Box<T] + | ^^^^^^^^^ unbalanced angle brackets + +error: unresolved link to `Vec<Box<T>` + --> $DIR/malformed-generics.rs:5:6 + | +LL | //! [Vec<Box<T>] + | ^^^^^^^^^^ unbalanced angle brackets + +error: unresolved link to `Vec<Box<T>>>` + --> $DIR/malformed-generics.rs:7:6 + | +LL | //! [Vec<Box<T>>>] + | ^^^^^^^^^^^^ unbalanced angle brackets + +error: unresolved link to `Vec<T>>>` + --> $DIR/malformed-generics.rs:9:6 + | +LL | //! [Vec<T>>>] + | ^^^^^^^^ unbalanced angle brackets + +error: unresolved link to `<Vec` + --> $DIR/malformed-generics.rs:11:6 + | +LL | //! [<Vec] + | ^^^^ unbalanced angle brackets + +error: unresolved link to `Vec::<` + --> $DIR/malformed-generics.rs:12:6 + | +LL | //! [Vec::<] + | ^^^^^^ unbalanced angle brackets + +error: unresolved link to `<T>` + --> $DIR/malformed-generics.rs:13:6 + | +LL | //! [<T>] + | ^^^ missing type for generic parameters + +error: unresolved link to `<invalid syntax>` + --> $DIR/malformed-generics.rs:15:6 + | +LL | //! [<invalid syntax>] + | ^^^^^^^^^^^^^^^^ missing type for generic parameters + +error: unresolved link to `Vec:<T>:new` + --> $DIR/malformed-generics.rs:17:6 + | +LL | //! [Vec:<T>:new()] + | ^^^^^^^^^^^^^ has invalid path separator + +error: unresolved link to `Vec<<T>>` + --> $DIR/malformed-generics.rs:19:6 + | +LL | //! [Vec<<T>>] + | ^^^^^^^^ too many angle brackets + +error: unresolved link to `Vec<>` + --> $DIR/malformed-generics.rs:21:6 + | +LL | //! [Vec<>] + | ^^^^^ empty angle brackets + +error: unresolved link to `Vec<<>>` + --> $DIR/malformed-generics.rs:22:6 + | +LL | //! [Vec<<>>] + | ^^^^^^^ too many angle brackets + +error: unresolved link to `<Vec as IntoIterator>::into_iter` + --> $DIR/malformed-generics.rs:25:6 + | +LL | //! [<Vec as IntoIterator>::into_iter] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fully-qualified syntax is unsupported + | + = note: see https://github.com/rust-lang/rust/issues/74563 for more information + +error: unresolved link to `<Vec<T> as IntoIterator>::iter` + --> $DIR/malformed-generics.rs:27:6 + | +LL | //! [<Vec<T> as IntoIterator>::iter] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fully-qualified syntax is unsupported + | + = note: see https://github.com/rust-lang/rust/issues/74563 for more information + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:5:13 + | +LL | //! [Vec<Box<T>] + | ^^^ + | + = note: `#[warn(rustdoc::invalid_html_tags)]` on by default + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:7:13 + | +LL | //! [Vec<Box<T>>>] + | ^^^ + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:9:9 + | +LL | //! [Vec<T>>>] + | ^^^ + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:13:6 + | +LL | //! [<T>] + | ^^^ + +warning: unclosed HTML tag `invalid` + --> $DIR/malformed-generics.rs:15:6 + | +LL | //! [<invalid syntax>] + | ^^^^^^^^ + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:17:10 + | +LL | //! [Vec:<T>:new()] + | ^^^ + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:19:10 + | +LL | //! [Vec<<T>>] + | ^^^ + +warning: unclosed HTML tag `Vec` + --> $DIR/malformed-generics.rs:25:6 + | +LL | //! [<Vec as IntoIterator>::into_iter] + | ^^^^ + +warning: unclosed HTML tag `T` + --> $DIR/malformed-generics.rs:27:10 + | +LL | //! [<Vec<T> as IntoIterator>::iter] + | ^^^ + +error: aborting due to 15 previous errors; 9 warnings emitted + diff --git a/tests/rustdoc-ui/intra-doc/non-path-primitives.rs b/tests/rustdoc-ui/intra-doc/non-path-primitives.rs new file mode 100644 index 000000000..587cbad68 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/non-path-primitives.rs @@ -0,0 +1,34 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![feature(intra_doc_pointers)] +// These are links that could reasonably expected to work, but don't. + +// `[]` isn't supported because it had too many false positives. +//! [X]([T]::not_here) +//! [Y](&[]::not_here) +//! [X]([]::not_here) +//! [Y]([T;N]::not_here) + +// These don't work because markdown syntax doesn't allow it. +//! [[T]::rotate_left] //~ ERROR unresolved link to `T` +//! [&[]::not_here] +//![Z]([T; N]::map) //~ ERROR unresolved link to `Z` +//! [`[T; N]::map`] +//! [[]::map] +//! [Z][] //~ ERROR unresolved link to `Z` +//! +//! [Z]: [T; N]::map //~ ERROR unresolved link to `Z` + +// `()` isn't supported because it had too many false positives. +//! [()::not_here] +//! [X]((,)::not_here) +//! [(,)::not_here] + +// FIXME: Associated items on some primitives aren't working, because the impls +// are part of the compiler instead of being part of the source code. +//! [unit::eq] //~ ERROR unresolved +//! [tuple::eq] //~ ERROR unresolved +//! [fn::eq] //~ ERROR unresolved + +// FIXME(#78800): This breaks because it's a blanket impl +// (I think? Might break for other reasons too.) +//! [reference::deref] //~ ERROR unresolved diff --git a/tests/rustdoc-ui/intra-doc/non-path-primitives.stderr b/tests/rustdoc-ui/intra-doc/non-path-primitives.stderr new file mode 100644 index 000000000..8ec894d10 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/non-path-primitives.stderr @@ -0,0 +1,63 @@ +error: unresolved link to `T` + --> $DIR/non-path-primitives.rs:12:7 + | +LL | //! [[T]::rotate_left] + | ^ no item named `T` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/non-path-primitives.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:14:5 + | +LL | //![Z]([T; N]::map) + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:17:6 + | +LL | //! [Z][] + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:19:6 + | +LL | //! [Z]: [T; N]::map + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `unit::eq` + --> $DIR/non-path-primitives.rs:28:6 + | +LL | //! [unit::eq] + | ^^^^^^^^ the builtin type `unit` has no associated item named `eq` + +error: unresolved link to `tuple::eq` + --> $DIR/non-path-primitives.rs:29:6 + | +LL | //! [tuple::eq] + | ^^^^^^^^^ the builtin type `tuple` has no associated item named `eq` + +error: unresolved link to `fn::eq` + --> $DIR/non-path-primitives.rs:30:6 + | +LL | //! [fn::eq] + | ^^^^^^ the builtin type `fn` has no associated item named `eq` + +error: unresolved link to `reference::deref` + --> $DIR/non-path-primitives.rs:34:6 + | +LL | //! [reference::deref] + | ^^^^^^^^^^^^^^^^ the builtin type `reference` has no associated item named `deref` + +error: aborting due to 8 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/pointer-reexports-allowed.rs b/tests/rustdoc-ui/intra-doc/pointer-reexports-allowed.rs new file mode 100644 index 000000000..8654a8e1b --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/pointer-reexports-allowed.rs @@ -0,0 +1,4 @@ +// aux-build:pointer-reexports-allowed.rs +// check-pass +extern crate inner; +pub use inner::foo; diff --git a/tests/rustdoc-ui/intra-doc/prim-conflict.rs b/tests/rustdoc-ui/intra-doc/prim-conflict.rs new file mode 100644 index 000000000..2c1a8b535 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/prim-conflict.rs @@ -0,0 +1,30 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined + +/// [char] +//~^ ERROR both a module and a builtin type +//~| NOTE ambiguous link +//~| HELP to link to the module +//~| HELP to link to the builtin type + +/// [type@char] +//~^ ERROR both a module and a builtin type +//~| NOTE ambiguous link +//~| HELP to link to the module +//~| HELP to link to the builtin type + +/// [mod@char] // ok +/// [prim@char] // ok + +/// [struct@char] +//~^ ERROR incompatible link +//~| HELP prefix with `mod@` +//~| NOTE resolved to a module +pub mod char {} + +pub mod inner { + //! [struct@char] + //~^ ERROR incompatible link + //~| HELP prefix with `prim@` + //~| NOTE resolved to a builtin type +} diff --git a/tests/rustdoc-ui/intra-doc/prim-conflict.stderr b/tests/rustdoc-ui/intra-doc/prim-conflict.stderr new file mode 100644 index 000000000..6ef3b7eab --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/prim-conflict.stderr @@ -0,0 +1,59 @@ +error: `char` is both a module and a builtin type + --> $DIR/prim-conflict.rs:4:6 + | +LL | /// [char] + | ^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/prim-conflict.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@char] + | ++++ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@char] + | +++++ + +error: `char` is both a module and a builtin type + --> $DIR/prim-conflict.rs:10:6 + | +LL | /// [type@char] + | ^^^^^^^^^ ambiguous link + | +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@char] + | ~~~~ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@char] + | ~~~~~ + +error: incompatible link kind for `char` + --> $DIR/prim-conflict.rs:19:6 + | +LL | /// [struct@char] + | ^^^^^^^^^^^ this link resolved to a module, which is not a struct + | +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@char] + | ~~~~ + +error: incompatible link kind for `char` + --> $DIR/prim-conflict.rs:26:10 + | +LL | //! [struct@char] + | ^^^^^^^^^^^ this link resolved to a builtin type, which is not a struct + | +help: to link to the builtin type, prefix with `prim@` + | +LL | //! [prim@char] + | ~~~~~ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/private-from-crate-level.rs b/tests/rustdoc-ui/intra-doc/private-from-crate-level.rs new file mode 100644 index 000000000..e429e75b2 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private-from-crate-level.rs @@ -0,0 +1,6 @@ +// check-pass + +//! [my_module] +//~^ WARN public documentation for `private_from_crate_level` links to private item `my_module` + +mod my_module {} diff --git a/tests/rustdoc-ui/intra-doc/private-from-crate-level.stderr b/tests/rustdoc-ui/intra-doc/private-from-crate-level.stderr new file mode 100644 index 000000000..4d5bd70bf --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private-from-crate-level.stderr @@ -0,0 +1,11 @@ +warning: public documentation for `private_from_crate_level` links to private item `my_module` + --> $DIR/private-from-crate-level.rs:3:6 + | +LL | //! [my_module] + | ^^^^^^^^^ this item is private + | + = note: this link will resolve properly if you pass `--document-private-items` + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/intra-doc/private.private.stderr b/tests/rustdoc-ui/intra-doc/private.private.stderr new file mode 100644 index 000000000..6661e9021 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private.private.stderr @@ -0,0 +1,27 @@ +warning: public documentation for `DocMe` links to private item `DontDocMe` + --> $DIR/private.rs:7:11 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^ this item is private + | + = note: this link resolves only because you passed `--document-private-items`, but will break without + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default + +warning: public documentation for `DocMe` links to private item `DontDocMe::f` + --> $DIR/private.rs:7:23 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^^^^ this item is private + | + = note: this link resolves only because you passed `--document-private-items`, but will break without + +warning: public documentation for `DocMe` links to private item `DontDocMe::x` + --> $DIR/private.rs:7:38 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^^^^ this item is private + | + = note: this link resolves only because you passed `--document-private-items`, but will break without + +warning: 3 warnings emitted + diff --git a/tests/rustdoc-ui/intra-doc/private.public.stderr b/tests/rustdoc-ui/intra-doc/private.public.stderr new file mode 100644 index 000000000..45b51e12e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private.public.stderr @@ -0,0 +1,27 @@ +warning: public documentation for `DocMe` links to private item `DontDocMe` + --> $DIR/private.rs:7:11 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^ this item is private + | + = note: this link will resolve properly if you pass `--document-private-items` + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default + +warning: public documentation for `DocMe` links to private item `DontDocMe::f` + --> $DIR/private.rs:7:23 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^^^^ this item is private + | + = note: this link will resolve properly if you pass `--document-private-items` + +warning: public documentation for `DocMe` links to private item `DontDocMe::x` + --> $DIR/private.rs:7:38 + | +LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] + | ^^^^^^^^^^^^ this item is private + | + = note: this link will resolve properly if you pass `--document-private-items` + +warning: 3 warnings emitted + diff --git a/tests/rustdoc-ui/intra-doc/private.rs b/tests/rustdoc-ui/intra-doc/private.rs new file mode 100644 index 000000000..525332dda --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private.rs @@ -0,0 +1,18 @@ +// check-pass +// revisions: public private +// [private]compile-flags: --document-private-items + +// make sure to update `rustdoc/intra-doc/private.rs` if you update this file + +/// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] +//~^ WARNING public documentation for `DocMe` links to private item `DontDocMe` +//~| WARNING public documentation for `DocMe` links to private item `DontDocMe::x` +//~| WARNING public documentation for `DocMe` links to private item `DontDocMe::f` +pub struct DocMe; +struct DontDocMe { + x: usize, +} + +impl DontDocMe { + fn f() {} +} diff --git a/tests/rustdoc-ui/intra-doc/span-ice-55723.rs b/tests/rustdoc-ui/intra-doc/span-ice-55723.rs new file mode 100644 index 000000000..041ec2932 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/span-ice-55723.rs @@ -0,0 +1,13 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +// An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to +// attempt to slice in the middle of a multibyte character. See +// https://github.com/rust-lang/rust/issues/55723 + +/// ## For example: +/// +/// (arr[i]) +//~^ ERROR `i` +pub fn test_ice() { + unimplemented!(); +} diff --git a/tests/rustdoc-ui/intra-doc/span-ice-55723.stderr b/tests/rustdoc-ui/intra-doc/span-ice-55723.stderr new file mode 100644 index 000000000..e8ee40ad4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/span-ice-55723.stderr @@ -0,0 +1,15 @@ +error: unresolved link to `i` + --> $DIR/span-ice-55723.rs:9:10 + | +LL | /// (arr[i]) + | ^ no item named `i` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/span-ice-55723.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/intra-doc/through-proc-macro.rs b/tests/rustdoc-ui/intra-doc/through-proc-macro.rs new file mode 100644 index 000000000..7628c3928 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/through-proc-macro.rs @@ -0,0 +1,18 @@ +// check-pass +// aux-build:through-proc-macro-aux.rs +// build-aux-docs + +// Ensure rustdoc doesn't panic on this code. + +#![warn(rustdoc::broken_intra_doc_links)] + +extern crate some_macros; + +#[some_macros::second] +pub enum Boom { + /// [Oooops] + //~^ WARNING unresolved link to `Oooops` + Bam, +} + +fn main() {} diff --git a/tests/rustdoc-ui/intra-doc/through-proc-macro.stderr b/tests/rustdoc-ui/intra-doc/through-proc-macro.stderr new file mode 100644 index 000000000..508d0683d --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/through-proc-macro.stderr @@ -0,0 +1,15 @@ +warning: unresolved link to `Oooops` + --> $DIR/through-proc-macro.rs:13:10 + | +LL | /// [Oooops] + | ^^^^^^ no item named `Oooops` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/through-proc-macro.rs:7:9 + | +LL | #![warn(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs new file mode 100644 index 000000000..0aa1e5a41 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -0,0 +1,14 @@ +// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +#![deny(warnings)] + +//! Linking to [foo@banana] and [`bar@banana!()`]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `bar` +//! And to [no disambiguator](@nectarine) and [another](@apricot!()). +//~^ ERROR unknown disambiguator `` +//~| ERROR unknown disambiguator `` +//! And with weird backticks: [``foo@hello``] [foo`@`hello]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `foo` + +fn main() {} diff --git a/tests/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.stderr new file mode 100644 index 000000000..19e541736 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -0,0 +1,56 @@ +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:4:17 + | +LL | //! Linking to [foo@banana] and [`bar@banana!()`]. + | ^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +note: the lint level is defined here + --> $DIR/unknown-disambiguator.rs:2:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` + +error: unknown disambiguator `bar` + --> $DIR/unknown-disambiguator.rs:4:35 + | +LL | //! Linking to [foo@banana] and [`bar@banana!()`]. + | ^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:10:34 + | +LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. + | ^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:10:48 + | +LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. + | ^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +error: unknown disambiguator `` + --> $DIR/unknown-disambiguator.rs:7:31 + | +LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). + | ^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +error: unknown disambiguator `` + --> $DIR/unknown-disambiguator.rs:7:57 + | +LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). + | ^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +error: aborting due to 6 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs new file mode 100644 index 000000000..c71e5bee1 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs @@ -0,0 +1,6 @@ +// Regression test for issue #95879. + +use unresolved_crate::module::Name; //~ ERROR failed to resolve + +/// [Name] +pub struct S; diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr new file mode 100644 index 000000000..b54f82006 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -0,0 +1,13 @@ +error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`? + --> $DIR/unresolved-import-recovery.rs:3:5 + | +LL | use unresolved_crate::module::Name; + | ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`? + | + = help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/rustdoc-ui/intra-doc/unused-extern-crate.rs b/tests/rustdoc-ui/intra-doc/unused-extern-crate.rs new file mode 100644 index 000000000..956583093 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unused-extern-crate.rs @@ -0,0 +1,5 @@ +// compile-flags: --extern zip=whatever.rlib +#![deny(rustdoc::broken_intra_doc_links)] +/// See [zip] crate. +//~^ ERROR unresolved +pub struct ArrayZip; diff --git a/tests/rustdoc-ui/intra-doc/unused-extern-crate.stderr b/tests/rustdoc-ui/intra-doc/unused-extern-crate.stderr new file mode 100644 index 000000000..815324563 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unused-extern-crate.stderr @@ -0,0 +1,15 @@ +error: unresolved link to `zip` + --> $DIR/unused-extern-crate.rs:3:10 + | +LL | /// See [zip] crate. + | ^^^ no item named `zip` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/unused-extern-crate.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/intra-doc/warning-crlf.rs b/tests/rustdoc-ui/intra-doc/warning-crlf.rs new file mode 100644 index 000000000..ceb62f6d1 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/warning-crlf.rs @@ -0,0 +1,26 @@ +// ignore-tidy-cr
+// check-pass
+
+// This file checks the spans of intra-link warnings in a file with CRLF line endings. The
+// .gitattributes file in this directory should enforce it.
+
+/// [error]
+pub struct A;
+//~^^ WARNING `error`
+
+///
+/// docs [error1]
+//~^ WARNING `error1`
+
+/// docs [error2]
+///
+pub struct B;
+//~^^^ WARNING `error2`
+
+/**
+ * This is a multi-line comment.
+ *
+ * It also has an [error].
+ */
+pub struct C;
+//~^^^ WARNING `error`
diff --git a/tests/rustdoc-ui/intra-doc/warning-crlf.stderr b/tests/rustdoc-ui/intra-doc/warning-crlf.stderr new file mode 100644 index 000000000..c309a55f4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/warning-crlf.stderr @@ -0,0 +1,35 @@ +warning: unresolved link to `error` + --> $DIR/warning-crlf.rs:7:6 + | +LL | /// [error] + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: unresolved link to `error1` + --> $DIR/warning-crlf.rs:12:11 + | +LL | /// docs [error1] + | ^^^^^^ no item named `error1` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error2` + --> $DIR/warning-crlf.rs:15:11 + | +LL | /// docs [error2] + | ^^^^^^ no item named `error2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning-crlf.rs:23:20 + | +LL | * It also has an [error]. + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: 4 warnings emitted + diff --git a/tests/rustdoc-ui/intra-doc/warning.rs b/tests/rustdoc-ui/intra-doc/warning.rs new file mode 100644 index 000000000..eab1f0348 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/warning.rs @@ -0,0 +1,84 @@ +// check-pass + + //! Test with [Foo::baz], [Bar::foo], ... +//~^ WARNING `Foo::baz` +//~| WARNING `Bar::foo` + //! , [Uniooon::X] and [Qux::Z]. +//~^ WARNING `Uniooon::X` +//~| WARNING `Qux::Z` + //! + //! , [Uniooon::X] and [Qux::Z]. +//~^ WARNING `Uniooon::X` +//~| WARNING `Qux::Z` + + /// [Qux:Y] +//~^ WARNING `Qux:Y` +pub struct Foo { + pub bar: usize, +} + +/// Foo +/// bar [BarA] bar //~ WARNING `BarA` +/// baz +pub fn a() {} + +/** + * Foo + * bar [BarB] bar //~ WARNING `BarB` + * baz + */ +pub fn b() {} + +/** Foo + +bar [BarC] bar //~ WARNING `BarC` +baz + + let bar_c_1 = 0; + let bar_c_2 = 0; + let g = [bar_c_1]; + let h = g[bar_c_2]; + +*/ +pub fn c() {} + +#[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `BarD` +pub fn d() {} + +macro_rules! f { + ($f:expr) => { + #[doc = $f] //~ WARNING `BarF` + pub fn f() {} + } +} +f!("Foo\nbar [BarF] bar\nbaz"); + +/** # for example, + * + * time to introduce a link [error]*/ //~ WARNING `error` +pub struct A; + +/** + * # for example, + * + * time to introduce a link [error] //~ WARNING `error` + */ +pub struct B; + +#[doc = "single line [error]"] //~ WARNING `error` +pub struct C; + +#[doc = "single line with \"escaping\" [error]"] //~ WARNING `error` +pub struct D; + +/// Item docs. //~ WARNING `error` +#[doc="Hello there!"] +/// [error] +pub struct E; + +/// +/// docs [error1] //~ WARNING `error1` + +/// docs [error2] //~ WARNING `error2` +/// +pub struct F; diff --git a/tests/rustdoc-ui/intra-doc/warning.stderr b/tests/rustdoc-ui/intra-doc/warning.stderr new file mode 100644 index 000000000..19399a0df --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/warning.stderr @@ -0,0 +1,175 @@ +warning: unresolved link to `Foo::baz` + --> $DIR/warning.rs:3:23 + | +LL | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ the struct `Foo` has no field or associated item named `baz` + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: unresolved link to `Bar::foo` + --> $DIR/warning.rs:3:35 + | +LL | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ no item named `Bar` in scope + +warning: unresolved link to `Uniooon::X` + --> $DIR/warning.rs:6:13 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ no item named `Uniooon` in scope + +warning: unresolved link to `Qux::Z` + --> $DIR/warning.rs:6:30 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ no item named `Qux` in scope + +warning: unresolved link to `Uniooon::X` + --> $DIR/warning.rs:10:14 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ no item named `Uniooon` in scope + +warning: unresolved link to `Qux::Z` + --> $DIR/warning.rs:10:31 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ no item named `Qux` in scope + +warning: unresolved link to `Qux:Y` + --> $DIR/warning.rs:14:13 + | +LL | /// [Qux:Y] + | ^^^^^ no item named `Qux:Y` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarA` + --> $DIR/warning.rs:21:10 + | +LL | /// bar [BarA] bar + | ^^^^ no item named `BarA` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarB` + --> $DIR/warning.rs:27:9 + | +LL | * bar [BarB] bar + | ^^^^ no item named `BarB` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarC` + --> $DIR/warning.rs:34:6 + | +LL | bar [BarC] bar + | ^^^^ no item named `BarC` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarD` + --> $DIR/warning.rs:45:1 + | +LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + bar [BarD] bar + ^^^^ + = note: no item named `BarD` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarF` + --> $DIR/warning.rs:50:9 + | +LL | #[doc = $f] + | ^^^^^^^^^^^ +... +LL | f!("Foo\nbar [BarF] bar\nbaz"); + | ------------------------------ in this macro invocation + | + = note: the link appears in this line: + + bar [BarF] bar + ^^^^ + = note: no item named `BarF` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: unresolved link to `error` + --> $DIR/warning.rs:58:30 + | +LL | * time to introduce a link [error]*/ + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:64:30 + | +LL | * time to introduce a link [error] + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:68:1 + | +LL | #[doc = "single line [error]"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + single line [error] + ^^^^^ + = note: no item named `error` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:71:1 + | +LL | #[doc = "single line with \"escaping\" [error]"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + single line with "escaping" [error] + ^^^^^ + = note: no item named `error` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:74:1 + | +LL | / /// Item docs. +LL | | #[doc="Hello there!"] +LL | | /// [error] + | |___________^ + | + = note: the link appears in this line: + + [error] + ^^^^^ + = note: no item named `error` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error1` + --> $DIR/warning.rs:80:11 + | +LL | /// docs [error1] + | ^^^^^^ no item named `error1` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error2` + --> $DIR/warning.rs:82:11 + | +LL | /// docs [error2] + | ^^^^^^ no item named `error2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: 19 warnings emitted + |