diff options
Diffstat (limited to 'tests/rustdoc-ui')
620 files changed, 17555 insertions, 0 deletions
diff --git a/tests/rustdoc-ui/2024-doctests-checks.rs b/tests/rustdoc-ui/2024-doctests-checks.rs new file mode 100644 index 00000000000..0c3a11771f3 --- /dev/null +++ b/tests/rustdoc-ui/2024-doctests-checks.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/// ``` +/// let x = 12; +/// ``` +/// +/// This one should not be a merged doctest (because of `$crate`). The output +/// will confirm it by displaying both merged and standalone doctest passes. +/// +/// ``` +/// macro_rules! bla { +/// () => {{ +/// $crate::foo(); +/// }} +/// } +/// +/// fn foo() {} +/// +/// fn main() { +/// bla!(); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/2024-doctests-checks.stdout b/tests/rustdoc-ui/2024-doctests-checks.stdout new file mode 100644 index 00000000000..534fe466fe7 --- /dev/null +++ b/tests/rustdoc-ui/2024-doctests-checks.stdout @@ -0,0 +1,12 @@ + +running 1 test +test $DIR/2024-doctests-checks.rs - Foo (line 8) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + + +running 1 test +test $DIR/2024-doctests-checks.rs - Foo (line 15) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs new file mode 100644 index 00000000000..c9887cbc63b --- /dev/null +++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs @@ -0,0 +1,23 @@ +//@ check-pass +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/// This doctest is used to ensure that if a crate attribute is present, +/// it will not be part of the merged doctests. +/// +/// ``` +/// #![doc(html_playground_url = "foo")] +/// +/// pub struct Bar; +/// ``` +/// +/// This one will allow us to confirm that the doctest above will be a +/// standalone one (there will be two separate doctests passes). +/// +/// ``` +/// let x = 12; +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout b/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout new file mode 100644 index 00000000000..c084ac4522e --- /dev/null +++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.stdout @@ -0,0 +1,12 @@ + +running 1 test +test $DIR/2024-doctests-crate-attribute.rs - Foo (line 20) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + + +running 1 test +test $DIR/2024-doctests-crate-attribute.rs - Foo (line 11) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/tests/rustdoc-ui/ambiguous-inherent-assoc-ty.rs new file mode 100644 index 00000000000..47e431d5cf1 --- /dev/null +++ b/tests/rustdoc-ui/ambiguous-inherent-assoc-ty.rs @@ -0,0 +1,13 @@ +//@ check-pass +// This test ensures that rustdoc does not panic on inherented associated types +// that are referred to without fully-qualified syntax. + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +pub struct Struct; + +impl Struct { + pub type AssocTy = usize; + pub const AssocConst: Self::AssocTy = 42; +} diff --git a/tests/rustdoc-ui/apit-46976.rs b/tests/rustdoc-ui/apit-46976.rs new file mode 100644 index 00000000000..515b5af9465 --- /dev/null +++ b/tests/rustdoc-ui/apit-46976.rs @@ -0,0 +1,4 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/46976 + +pub fn ice(f: impl Fn()) {} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs new file mode 100644 index 00000000000..eba17ca6f7e --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.rs @@ -0,0 +1,17 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr new file mode 100644 index 00000000000..b4c0d4c20d7 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8-windows.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args new file mode 100644 index 00000000000..c070b0c2400 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.args @@ -0,0 +1,2 @@ +--cfg +unbroken€ \ No newline at end of file diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs new file mode 100644 index 00000000000..1b2e52af762 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.rs @@ -0,0 +1,18 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr new file mode 100644 index 00000000000..b4c0d4c20d7 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-badutf8.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs new file mode 100644 index 00000000000..1a1cf6b9e75 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs @@ -0,0 +1,19 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr new file mode 100644 index 00000000000..28a20debf1c --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs new file mode 100644 index 00000000000..8d9335f5add --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs @@ -0,0 +1,20 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr new file mode 100644 index 00000000000..28a20debf1c --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.stderr @@ -0,0 +1,2 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs new file mode 100644 index 00000000000..9cbbd505c57 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs @@ -0,0 +1,20 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. This test uses backslash as the path separator for the command +// line arguments and is only run on windows. +// +//@ only-windows +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr new file mode 100644 index 00000000000..ad3b445c958 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.stderr @@ -0,0 +1,6 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs new file mode 100644 index 00000000000..f211a50892c --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs @@ -0,0 +1,21 @@ +// Check to see if we can get parameters from an @argsfile file +// +// Path replacement in .stderr files (i.e. `$DIR`) doesn't handle mixed path +// separators. We have a duplicated version of this test that uses backslash as +// the path separator for the command line arguments that is only run on +// windows. +// +//@ ignore-windows +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr new file mode 100644 index 00000000000..ad3b445c958 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.stderr @@ -0,0 +1,6 @@ +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + +error: failed to load argument file: UTF-8 error in $DIR/commandline-argfile-badutf8.args + +error: failed to load argument file: IO error: $DIR/commandline-argfile-missing2.args: $FILE_MISSING (os error $ERR) + diff --git a/tests/rustdoc-ui/argfile/commandline-argfile.args b/tests/rustdoc-ui/argfile/commandline-argfile.args new file mode 100644 index 00000000000..972938bf6c8 --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile.args @@ -0,0 +1,2 @@ +--cfg +unbroken \ No newline at end of file diff --git a/tests/rustdoc-ui/argfile/commandline-argfile.rs b/tests/rustdoc-ui/argfile/commandline-argfile.rs new file mode 100644 index 00000000000..d5a1cd0a5ed --- /dev/null +++ b/tests/rustdoc-ui/argfile/commandline-argfile.rs @@ -0,0 +1,13 @@ +// Check to see if we can get parameters from an @argsfile file +// +//@ check-pass +//@ compile-flags: --cfg cmdline_set --check-cfg=cfg(cmdline_set,unbroken) +//@ compile-flags: @{{src-base}}/argfile/commandline-argfile.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() {} diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs new file mode 100644 index 00000000000..d9bd48103d2 --- /dev/null +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs @@ -0,0 +1,16 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/102467>. +// It ensures that the expected error is displayed. + +#![feature(associated_const_equality)] + +trait T { + type A: S<C<X = 0i32> = 34>; + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here +} + +trait S { + const C: i32; +} + +fn main() {} diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr b/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr new file mode 100644 index 00000000000..5c8f08afe7a --- /dev/null +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.stderr @@ -0,0 +1,28 @@ +error[E0229]: associated item constraints are not allowed here + --> $DIR/associated-constant-not-allowed-102467.rs:7:17 + | +LL | type A: S<C<X = 0i32> = 34>; + | ^^^^^^^^ associated item constraint not allowed here + | +help: consider removing this associated item binding + | +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | + +error[E0229]: associated item constraints are not allowed here + --> $DIR/associated-constant-not-allowed-102467.rs:7:17 + | +LL | type A: S<C<X = 0i32> = 34>; + | ^^^^^^^^ associated item constraint not allowed here + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider removing this associated item binding + | +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/rustdoc-ui/auxiliary/include-str-bare-urls.md b/tests/rustdoc-ui/auxiliary/include-str-bare-urls.md new file mode 100644 index 00000000000..b07717d8f02 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/include-str-bare-urls.md @@ -0,0 +1,10 @@ +HEADS UP! https://example.com MUST SHOW UP IN THE STDERR FILE! + +Normally, a line with errors on it will also have a comment +marking it up as something that needs to generate an error. + +The test harness doesn't gather hot comments from this file. +Rustdoc will generate an error for the line, and the `.stderr` +snapshot includes this error, but Compiletest doesn't see it. + +If the stderr file changes, make sure the warning points at the URL! diff --git a/tests/rustdoc-ui/auxiliary/issue-36031.rs b/tests/rustdoc-ui/auxiliary/issue-36031.rs new file mode 100644 index 00000000000..da688139e34 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/issue-36031.rs @@ -0,0 +1,9 @@ +pub trait Foo { + const FOO: usize; +} + +pub struct Bar; + +impl Bar { + pub const BAR: usize = 3; +} diff --git a/tests/rustdoc-ui/auxiliary/issue-40936.rs b/tests/rustdoc-ui/auxiliary/issue-40936.rs new file mode 100644 index 00000000000..b921e520173 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/issue-40936.rs @@ -0,0 +1,5 @@ +pub mod outermod { + pub mod innermod { + pub use super::*; + } +} diff --git a/tests/rustdoc-ui/auxiliary/issue-48414.rs b/tests/rustdoc-ui/auxiliary/issue-48414.rs new file mode 100644 index 00000000000..f442ac72212 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/issue-48414.rs @@ -0,0 +1,5 @@ +/// Woah, this trait links to [OtherTrait](OtherTrait)! +pub trait SomeTrait {} + +/// Woah, this trait links to [SomeTrait](SomeTrait)! +pub trait OtherTrait {} diff --git a/tests/rustdoc-ui/auxiliary/issue-73061.rs b/tests/rustdoc-ui/auxiliary/issue-73061.rs new file mode 100644 index 00000000000..9a2e4aaf75e --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/issue-73061.rs @@ -0,0 +1,17 @@ +//@edition:2018 + +#![feature(impl_trait_in_assoc_type)] + +pub trait Foo { + type X: std::future::Future<Output = ()>; + fn x(&self) -> Self::X; +} + +pub struct F; + +impl Foo for F { + type X = impl std::future::Future<Output = ()>; + fn x(&self) -> Self::X { + async {} + } +} diff --git a/tests/rustdoc-ui/auxiliary/module_macro_doc.rs b/tests/rustdoc-ui/auxiliary/module_macro_doc.rs new file mode 100644 index 00000000000..9d6b52b95a7 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/module_macro_doc.rs @@ -0,0 +1 @@ +//! [`long_cat`] is really long diff --git a/tests/rustdoc-ui/auxiliary/overflow.rs b/tests/rustdoc-ui/auxiliary/overflow.rs new file mode 100644 index 00000000000..ff65936bec9 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/overflow.rs @@ -0,0 +1,20 @@ +pub struct B0; +pub struct B1; +use std::ops::Shl; +use std::ops::Sub; +pub type Shleft<A, B> = <A as Shl<B>>::Output; +pub type Sub1<A> = <A as Sub<B1>>::Output; +pub struct UInt<U, B> { + pub(crate) msb: U, + pub(crate) lsb: B, +} +impl<U, B, Ur, Br> Shl<UInt<Ur, Br>> for UInt<U, B> +where + UInt<Ur, Br>: Sub<B1>, + UInt<UInt<U, B>, B0>: Shl<Sub1<UInt<Ur, Br>>>, +{ + type Output = Shleft<UInt<UInt<U, B>, B0>, Sub1<UInt<Ur, Br>>>; + fn shl(self, rhs: UInt<Ur, Br>) -> Self::Output { + unimplemented!() + } +} diff --git a/tests/rustdoc-ui/bounded-hr-lifetime.rs b/tests/rustdoc-ui/bounded-hr-lifetime.rs new file mode 100644 index 00000000000..d6c90f552a2 --- /dev/null +++ b/tests/rustdoc-ui/bounded-hr-lifetime.rs @@ -0,0 +1,9 @@ +// This test ensures that rustdoc doesn't panic on higher-ranked lifetimes +// with bounds, because an error should have already been emitted by rustc. + +pub fn hrlt<'b, 'c>() +where + for<'a: 'b + 'c> &'a (): std::fmt::Debug, + //~^ ERROR bounds cannot be used in this context +{ +} diff --git a/tests/rustdoc-ui/bounded-hr-lifetime.stderr b/tests/rustdoc-ui/bounded-hr-lifetime.stderr new file mode 100644 index 00000000000..c936e4022ef --- /dev/null +++ b/tests/rustdoc-ui/bounded-hr-lifetime.stderr @@ -0,0 +1,8 @@ +error: bounds cannot be used in this context + --> $DIR/bounded-hr-lifetime.rs:6:13 + | +LL | for<'a: 'b + 'c> &'a (): std::fmt::Debug, + | ^^ ^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/cfg-boolean-literal.rs b/tests/rustdoc-ui/cfg-boolean-literal.rs new file mode 100644 index 00000000000..74808d066c7 --- /dev/null +++ b/tests/rustdoc-ui/cfg-boolean-literal.rs @@ -0,0 +1,18 @@ +//@ check-pass + +#![feature(doc_cfg)] + +#[doc(cfg(false))] +pub fn foo() {} + +#[doc(cfg(true))] +pub fn bar() {} + +#[doc(cfg(any(true)))] +pub fn zoo() {} + +#[doc(cfg(all(true)))] +pub fn toy() {} + +#[doc(cfg(not(true)))] +pub fn nay() {} diff --git a/tests/rustdoc-ui/check-cfg.rs b/tests/rustdoc-ui/check-cfg.rs new file mode 100644 index 00000000000..6ca37db75af --- /dev/null +++ b/tests/rustdoc-ui/check-cfg.rs @@ -0,0 +1,7 @@ +//@ check-pass +//@ compile-flags: --check-cfg=cfg() + +/// uniz is nor a builtin nor pass as arguments so is unexpected +#[cfg(uniz)] +//~^ WARNING unexpected `cfg` condition name +pub struct Bar; diff --git a/tests/rustdoc-ui/check-cfg.stderr b/tests/rustdoc-ui/check-cfg.stderr new file mode 100644 index 00000000000..6f026cee41e --- /dev/null +++ b/tests/rustdoc-ui/check-cfg.stderr @@ -0,0 +1,12 @@ +warning: unexpected `cfg` condition name: `uniz` + --> $DIR/check-cfg.rs:5:7 + | +LL | #[cfg(uniz)] + | ^^^^ help: there is a config with a similar name: `unix` + | + = help: to expect this configuration use `--check-cfg=cfg(uniz)` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/check-doc-alias-attr-location.rs b/tests/rustdoc-ui/check-doc-alias-attr-location.rs new file mode 100644 index 00000000000..6de1960e2e2 --- /dev/null +++ b/tests/rustdoc-ui/check-doc-alias-attr-location.rs @@ -0,0 +1,23 @@ +pub struct Bar; +pub trait Foo { + type X; + fn foo() -> Self::X; +} + +#[doc(alias = "foo")] //~ ERROR +extern "C" {} + +#[doc(alias = "bar")] //~ ERROR +impl Bar { + #[doc(alias = "const")] + pub const A: u32 = 0; +} + +#[doc(alias = "foobar")] //~ ERROR +impl Foo for Bar { + #[doc(alias = "assoc")] //~ ERROR + type X = i32; + fn foo() -> Self::X { + 0 + } +} diff --git a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr new file mode 100644 index 00000000000..85c9516236c --- /dev/null +++ b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -0,0 +1,26 @@ +error: `#[doc(alias = "...")]` isn't allowed on foreign module + --> $DIR/check-doc-alias-attr-location.rs:7:7 + | +LL | #[doc(alias = "foo")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:10:7 + | +LL | #[doc(alias = "bar")] + | ^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on implementation block + --> $DIR/check-doc-alias-attr-location.rs:16:7 + | +LL | #[doc(alias = "foobar")] + | ^^^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block + --> $DIR/check-doc-alias-attr-location.rs:18:11 + | +LL | #[doc(alias = "assoc")] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/check-doc-alias-attr.rs b/tests/rustdoc-ui/check-doc-alias-attr.rs new file mode 100644 index 00000000000..719b98604c4 --- /dev/null +++ b/tests/rustdoc-ui/check-doc-alias-attr.rs @@ -0,0 +1,28 @@ +#![crate_type = "lib"] + +#[doc(alias = "foo")] // ok! +#[doc(alias("bar", "baz"))] // ok! +pub struct Bar; + +#[doc(alias)] //~ ERROR +#[doc(alias = 0)] //~ ERROR +#[doc(alias = "\"")] //~ ERROR +#[doc(alias = "\n")] //~ ERROR +#[doc(alias = " +")] //~^ ERROR +#[doc(alias = "\t")] //~ ERROR +#[doc(alias = " hello")] //~ ERROR +#[doc(alias = "hello ")] //~ ERROR +#[doc(alias = "")] //~ ERROR +pub struct Foo; + +#[doc(alias(0))] //~ ERROR +#[doc(alias("\""))] //~ ERROR +#[doc(alias("\n"))] //~ ERROR +#[doc(alias(" +"))] //~^ ERROR +#[doc(alias("\t"))] //~ ERROR +#[doc(alias(" hello"))] //~ ERROR +#[doc(alias("hello "))] //~ ERROR +#[doc(alias(""))] //~ ERROR +pub struct Foo2; diff --git a/tests/rustdoc-ui/check-doc-alias-attr.stderr b/tests/rustdoc-ui/check-doc-alias-attr.stderr new file mode 100644 index 00000000000..250568be333 --- /dev/null +++ b/tests/rustdoc-ui/check-doc-alias-attr.stderr @@ -0,0 +1,108 @@ +error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + --> $DIR/check-doc-alias-attr.rs:7:7 + | +LL | #[doc(alias)] + | ^^^^^ + +error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + --> $DIR/check-doc-alias-attr.rs:8:7 + | +LL | #[doc(alias = 0)] + | ^^^^^^^^^ + +error: '"' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/check-doc-alias-attr.rs:9:15 + | +LL | #[doc(alias = "\"")] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/check-doc-alias-attr.rs:10:15 + | +LL | #[doc(alias = "\n")] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/check-doc-alias-attr.rs:11:15 + | +LL | #[doc(alias = " + | _______________^ +LL | | ")] + | |_^ + +error: '\t' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/check-doc-alias-attr.rs:13:15 + | +LL | #[doc(alias = "\t")] + | ^^^^ + +error: `#[doc(alias = "...")]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:14:15 + | +LL | #[doc(alias = " hello")] + | ^^^^^^^^ + +error: `#[doc(alias = "...")]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:15:15 + | +LL | #[doc(alias = "hello ")] + | ^^^^^^^^ + +error: `#[doc(alias = "...")]` attribute cannot have empty value + --> $DIR/check-doc-alias-attr.rs:16:15 + | +LL | #[doc(alias = "")] + | ^^ + +error: `#[doc(alias("a"))]` expects string literals + --> $DIR/check-doc-alias-attr.rs:19:13 + | +LL | #[doc(alias(0))] + | ^ + +error: '"' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:20:13 + | +LL | #[doc(alias("\""))] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:21:13 + | +LL | #[doc(alias("\n"))] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:22:13 + | +LL | #[doc(alias(" + | _____________^ +LL | | "))] + | |_^ + +error: '\t' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:24:13 + | +LL | #[doc(alias("\t"))] + | ^^^^ + +error: `#[doc(alias("..."))]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:25:13 + | +LL | #[doc(alias(" hello"))] + | ^^^^^^^^ + +error: `#[doc(alias("..."))]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:26:13 + | +LL | #[doc(alias("hello "))] + | ^^^^^^^^ + +error: `#[doc(alias("..."))]` attribute cannot have empty value + --> $DIR/check-doc-alias-attr.rs:27:13 + | +LL | #[doc(alias(""))] + | ^^ + +error: aborting due to 17 previous errors + diff --git a/tests/rustdoc-ui/circular-intra-doc-link-48414.rs b/tests/rustdoc-ui/circular-intra-doc-link-48414.rs new file mode 100644 index 00000000000..23dc072c6a2 --- /dev/null +++ b/tests/rustdoc-ui/circular-intra-doc-link-48414.rs @@ -0,0 +1,14 @@ +//@ aux-build:issue-48414.rs +//@ check-pass + +// https://github.com/rust-lang/rust/issues/48414 + +// ICE when resolving paths for a trait that linked to another trait, when both were in an external +// crate + +#![crate_name = "base"] + +extern crate issue_48414; + +#[doc(inline)] +pub use issue_48414::{SomeTrait, OtherTrait}; diff --git a/tests/rustdoc-ui/const-evalutation-ice.rs b/tests/rustdoc-ui/const-evalutation-ice.rs new file mode 100644 index 00000000000..72bcbeb4c51 --- /dev/null +++ b/tests/rustdoc-ui/const-evalutation-ice.rs @@ -0,0 +1,11 @@ +// Just check we don't get an ICE for `N`. + +use std::cell::Cell; +use std::mem; + +pub struct S { + s: Cell<usize>, +} + +pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize; +//~^ ERROR overflow diff --git a/tests/rustdoc-ui/const-evalutation-ice.stderr b/tests/rustdoc-ui/const-evalutation-ice.stderr new file mode 100644 index 00000000000..51958319f5f --- /dev/null +++ b/tests/rustdoc-ui/const-evalutation-ice.stderr @@ -0,0 +1,9 @@ +error[E0080]: attempt to compute `0_usize - 1_usize`, which would overflow + --> $DIR/const-evalutation-ice.rs:10:22 + | +LL | pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `N` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/rustdoc-ui/const_arg_in_type_position.rs b/tests/rustdoc-ui/const_arg_in_type_position.rs new file mode 100644 index 00000000000..4969e8d195f --- /dev/null +++ b/tests/rustdoc-ui/const_arg_in_type_position.rs @@ -0,0 +1,6 @@ +type Array<T, const N: usize> = [T; N]; + +fn foo<const N: usize>() -> Array<N, ()> { + //~^ ERROR constant provided when a type was expected + unimplemented!() +} diff --git a/tests/rustdoc-ui/const_arg_in_type_position.stderr b/tests/rustdoc-ui/const_arg_in_type_position.stderr new file mode 100644 index 00000000000..5345f77fd39 --- /dev/null +++ b/tests/rustdoc-ui/const_arg_in_type_position.stderr @@ -0,0 +1,9 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/const_arg_in_type_position.rs:3:35 + | +LL | fn foo<const N: usize>() -> Array<N, ()> { + | ^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/rustdoc-ui/coverage/allow_missing_docs.rs b/tests/rustdoc-ui/coverage/allow_missing_docs.rs new file mode 100644 index 00000000000..43f0d731fde --- /dev/null +++ b/tests/rustdoc-ui/coverage/allow_missing_docs.rs @@ -0,0 +1,41 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +//! Make sure to have some docs on your crate root + +#[allow(missing_docs)] +pub mod mod_foo { + pub struct Bar; +} + +/// This is a struct with an `#[allow(missing_docs)]` +pub struct AllowTheMissingDocs { + #[allow(missing_docs)] + pub empty_str: String, + + /// This has + #[allow(missing_docs)] + /// but also has documentation comments + pub hello: usize, + + /// The doc id just to create a boilerplate comment + pub doc_id: Vec<u8>, +} + +/// A function that has a documentation +pub fn this_is_func() {} + +#[allow(missing_docs)] +pub struct DemoStruct { + something: usize, +} + +#[allow(missing_docs)] +pub mod bar { + #[warn(missing_docs)] + pub struct Bar { //~ WARN + pub f: u32, //~ WARN + } + + pub struct NeedsNoDocs; +} diff --git a/tests/rustdoc-ui/coverage/allow_missing_docs.stderr b/tests/rustdoc-ui/coverage/allow_missing_docs.stderr new file mode 100644 index 00000000000..3d5b512d14d --- /dev/null +++ b/tests/rustdoc-ui/coverage/allow_missing_docs.stderr @@ -0,0 +1,20 @@ +warning: missing documentation for a struct + --> $DIR/allow_missing_docs.rs:36:5 + | +LL | pub struct Bar { + | ^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/allow_missing_docs.rs:35:12 + | +LL | #[warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a struct field + --> $DIR/allow_missing_docs.rs:37:9 + | +LL | pub f: u32, + | ^^^^^^^^^^ + +warning: 2 warnings emitted + diff --git a/tests/rustdoc-ui/coverage/allow_missing_docs.stdout b/tests/rustdoc-ui/coverage/allow_missing_docs.stdout new file mode 100644 index 00000000000..17e8ee9e23d --- /dev/null +++ b/tests/rustdoc-ui/coverage/allow_missing_docs.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...i/coverage/allow_missing_docs.rs | 5 | 71.4% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 5 | 71.4% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/basic.rs b/tests/rustdoc-ui/coverage/basic.rs new file mode 100644 index 00000000000..febcc80fbbb --- /dev/null +++ b/tests/rustdoc-ui/coverage/basic.rs @@ -0,0 +1,50 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +#![feature(extern_types)] + +//! Make sure to have some docs on your crate root + +/// This struct is documented, but its fields are not. +/// +/// However, one field is private, so it shouldn't show in the total. +pub struct SomeStruct { + pub some_field: usize, + other_field: usize, +} + +impl SomeStruct { + /// Method with docs + pub fn this_fn(&self) {} + + // Method without docs + pub fn other_method(&self) {} +} + +// struct without docs +pub struct OtherStruct; + +// function with no docs +pub fn some_fn() {} + +/// Function with docs +pub fn other_fn() {} + +pub enum SomeEnum { + /// Some of these variants are documented... + VarOne, + /// ...but some of them are not. + VarTwo, + // (like this one) + VarThree, +} + +/// There's a macro here, too +#[macro_export] +macro_rules! some_macro { + () => {}; +} + +extern "C" { + pub type ExternType; +} diff --git a/tests/rustdoc-ui/coverage/basic.stdout b/tests/rustdoc-ui/coverage/basic.stdout new file mode 100644 index 00000000000..545662f0f3d --- /dev/null +++ b/tests/rustdoc-ui/coverage/basic.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...sts/rustdoc-ui/coverage/basic.rs | 7 | 50.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 7 | 50.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/doc-examples-json.rs b/tests/rustdoc-ui/coverage/doc-examples-json.rs new file mode 100644 index 00000000000..4aa4bf23771 --- /dev/null +++ b/tests/rustdoc-ui/coverage/doc-examples-json.rs @@ -0,0 +1,13 @@ +//@ check-pass +//@ compile-flags:-Z unstable-options --output-format json --show-coverage + +// This check ensures that only one doc example is counted since they're "optional" on +// certain items. + +/// ``` +/// let x = 12; +/// ``` +pub const Foo: u32 = 0; + +/// doc +pub const Bar: u32 = 0; diff --git a/tests/rustdoc-ui/coverage/doc-examples-json.stdout b/tests/rustdoc-ui/coverage/doc-examples-json.stdout new file mode 100644 index 00000000000..070fed0783e --- /dev/null +++ b/tests/rustdoc-ui/coverage/doc-examples-json.stdout @@ -0,0 +1 @@ +{"$DIR/doc-examples-json.rs":{"total":3,"with_docs":2,"total_examples":1,"with_examples":1}} diff --git a/tests/rustdoc-ui/coverage/doc-examples.rs b/tests/rustdoc-ui/coverage/doc-examples.rs new file mode 100644 index 00000000000..283d9c424aa --- /dev/null +++ b/tests/rustdoc-ui/coverage/doc-examples.rs @@ -0,0 +1,27 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +//! This test ensure that only rust code examples are counted. + +/// Doc +/// +/// ``` +/// let x = 2; +/// ``` +pub struct Foo; + +/// Doc +/// +/// ```text +/// yolo +/// ``` +pub trait Bar {} + +/// Doc +/// +/// ```ignore (just for the sake of this test) +/// let x = 2; +/// ``` +pub fn foo<T: Bar, D: ::std::fmt::Debug>(a: Foo, b: u32, c: T, d: D) -> u32 { + 0 +} diff --git a/tests/rustdoc-ui/coverage/doc-examples.stdout b/tests/rustdoc-ui/coverage/doc-examples.stdout new file mode 100644 index 00000000000..793adeb3518 --- /dev/null +++ b/tests/rustdoc-ui/coverage/doc-examples.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...tdoc-ui/coverage/doc-examples.rs | 4 | 100.0% | 1 | 33.3% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 4 | 100.0% | 1 | 33.3% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/empty.rs b/tests/rustdoc-ui/coverage/empty.rs new file mode 100644 index 00000000000..bcd3e48988b --- /dev/null +++ b/tests/rustdoc-ui/coverage/empty.rs @@ -0,0 +1,4 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +// an empty crate still has one item to document: the crate root diff --git a/tests/rustdoc-ui/coverage/empty.stdout b/tests/rustdoc-ui/coverage/empty.stdout new file mode 100644 index 00000000000..d486825287b --- /dev/null +++ b/tests/rustdoc-ui/coverage/empty.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...sts/rustdoc-ui/coverage/empty.rs | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/enum-tuple-documented.rs b/tests/rustdoc-ui/coverage/enum-tuple-documented.rs new file mode 100644 index 00000000000..4cbeb7a164d --- /dev/null +++ b/tests/rustdoc-ui/coverage/enum-tuple-documented.rs @@ -0,0 +1,37 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +// The point of this test is to ensure that the number of "documented" items +// is higher than in `enum-tuple.rs`. + +//! (remember the crate root is still a module) + +/// so check out this enum here +pub enum ThisEnum { + /// VarOne. + VarOne( + /// hello! + String, + ), + /// Var Two. + VarTwo( + /// Hello + String, + /// Bis repetita. + String, + ), +} + +/// Struct. +pub struct ThisStruct( + /// hello + u32, +); + +/// Struct. +pub struct ThisStruct2( + /// hello + u32, + /// Bis repetita. + u8, +); diff --git a/tests/rustdoc-ui/coverage/enum-tuple-documented.stdout b/tests/rustdoc-ui/coverage/enum-tuple-documented.stdout new file mode 100644 index 00000000000..82c98f43f3d --- /dev/null +++ b/tests/rustdoc-ui/coverage/enum-tuple-documented.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...overage/enum-tuple-documented.rs | 9 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 9 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/enum-tuple.rs b/tests/rustdoc-ui/coverage/enum-tuple.rs new file mode 100644 index 00000000000..5cbc52a7d03 --- /dev/null +++ b/tests/rustdoc-ui/coverage/enum-tuple.rs @@ -0,0 +1,18 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +//! (remember the crate root is still a module) + +/// so check out this enum here +pub enum ThisEnum { + /// No need to document the field if there is only one in a tuple variant! + VarOne(String), + /// But if there is more than one... still fine! + VarTwo(String, String), +} + +/// Struct. +pub struct ThisStruct(u32); + +/// Struct. +pub struct ThisStruct2(u32, u8); diff --git a/tests/rustdoc-ui/coverage/enum-tuple.stdout b/tests/rustdoc-ui/coverage/enum-tuple.stdout new file mode 100644 index 00000000000..a3377d59c07 --- /dev/null +++ b/tests/rustdoc-ui/coverage/enum-tuple.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...ustdoc-ui/coverage/enum-tuple.rs | 6 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 6 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/enums.rs b/tests/rustdoc-ui/coverage/enums.rs new file mode 100644 index 00000000000..29e41984576 --- /dev/null +++ b/tests/rustdoc-ui/coverage/enums.rs @@ -0,0 +1,22 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +//! (remember the crate root is still a module) + +/// so check out this enum here +pub enum ThisEnum { + /// this variant has some weird stuff going on + VarOne { + /// like, it has some named fields inside + field_one: usize, + // (these show up as struct fields) + field_two: usize, + }, + /// here's another variant for you + VarTwo(String), + // but not all of them need to be documented as thoroughly + VarThree, +} + +/// uninhabited enums? sure, let's throw one of those around +pub enum OtherEnum {} diff --git a/tests/rustdoc-ui/coverage/enums.stdout b/tests/rustdoc-ui/coverage/enums.stdout new file mode 100644 index 00000000000..bb224aac8c0 --- /dev/null +++ b/tests/rustdoc-ui/coverage/enums.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...sts/rustdoc-ui/coverage/enums.rs | 6 | 75.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 6 | 75.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/exotic.rs b/tests/rustdoc-ui/coverage/exotic.rs new file mode 100644 index 00000000000..9fc1498cb2a --- /dev/null +++ b/tests/rustdoc-ui/coverage/exotic.rs @@ -0,0 +1,16 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] + +//! the features only used in std also have entries in the table, so make sure those get pulled out +//! properly as well + +/// woo, check it out, we can write our own primitive docs lol +#[rustc_doc_primitive = "unit"] +mod prim_unit {} + +/// keywords? sure, pile them on +#[doc(keyword="where")] +mod where_keyword {} diff --git a/tests/rustdoc-ui/coverage/exotic.stdout b/tests/rustdoc-ui/coverage/exotic.stdout new file mode 100644 index 00000000000..bd894898cc4 --- /dev/null +++ b/tests/rustdoc-ui/coverage/exotic.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...ts/rustdoc-ui/coverage/exotic.rs | 3 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 3 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/html.rs b/tests/rustdoc-ui/coverage/html.rs new file mode 100644 index 00000000000..7fd080f0758 --- /dev/null +++ b/tests/rustdoc-ui/coverage/html.rs @@ -0,0 +1,6 @@ +//@ compile-flags:-Z unstable-options --output-format html --show-coverage + +/// Foo +pub struct Xo; + +//~? ERROR `--output-format=html` is not supported for the `--show-coverage` option diff --git a/tests/rustdoc-ui/coverage/html.stderr b/tests/rustdoc-ui/coverage/html.stderr new file mode 100644 index 00000000000..764179820c5 --- /dev/null +++ b/tests/rustdoc-ui/coverage/html.stderr @@ -0,0 +1,2 @@ +error: `--output-format=html` is not supported for the `--show-coverage` option + diff --git a/tests/rustdoc-ui/coverage/json.rs b/tests/rustdoc-ui/coverage/json.rs new file mode 100644 index 00000000000..bfa8dc70083 --- /dev/null +++ b/tests/rustdoc-ui/coverage/json.rs @@ -0,0 +1,65 @@ +//@ check-pass +//@ compile-flags:-Z unstable-options --output-format json --show-coverage + +pub mod foo { + /// Hello! + pub struct Foo; + /// Bar + pub enum Bar { A } +} + +/// X +pub struct X; + +/// Bar +/// +/// ``` +/// let x = 12; +/// ``` +pub mod bar { + /// bar + pub struct Bar; + /// X + pub enum X { + /// ``` + /// let x = "should be ignored!"; + /// ``` + Y + } +} + +/// yolo +/// +/// ```text +/// should not be counted as a code example! +/// ``` +pub enum Yolo { X } + +impl Yolo { + /// ``` + /// let x = "should be ignored!"; + /// ``` + pub const Const: u32 = 0; +} + +pub struct Xo<T: Clone> { + /// ``` + /// let x = "should be ignored!"; + /// ``` + x: T, +} + +/// ``` +/// let x = "should be ignored!"; +/// ``` +pub static StaticFoo: u32 = 0; + +/// ``` +/// let x = "should be ignored!"; +/// ``` +pub const ConstFoo: u32 = 0; + +/// ``` +/// let x = "should be ignored!"; +/// ``` +pub type TypeFoo = u32; diff --git a/tests/rustdoc-ui/coverage/json.stdout b/tests/rustdoc-ui/coverage/json.stdout new file mode 100644 index 00000000000..25fd896baf1 --- /dev/null +++ b/tests/rustdoc-ui/coverage/json.stdout @@ -0,0 +1 @@ +{"$DIR/json.rs":{"total":17,"with_docs":12,"total_examples":13,"with_examples":6}} diff --git a/tests/rustdoc-ui/coverage/private.rs b/tests/rustdoc-ui/coverage/private.rs new file mode 100644 index 00000000000..91490eff7a8 --- /dev/null +++ b/tests/rustdoc-ui/coverage/private.rs @@ -0,0 +1,21 @@ +//@ compile-flags:-Z unstable-options --show-coverage --document-private-items +//@ check-pass + +#![allow(unused)] + +//! when `--document-private-items` is passed, nothing is safe. everything must have docs or your +//! score will suffer the consequences + +mod this_mod { + fn private_fn() {} +} + +/// See, our public items have docs! +pub struct SomeStruct { + /// Look, all perfectly documented! + pub field: usize, + other: usize, +} + +/// Nothing shady going on here. Just a bunch of well-documented code. (cough) +pub fn public_fn() {} diff --git a/tests/rustdoc-ui/coverage/private.stdout b/tests/rustdoc-ui/coverage/private.stdout new file mode 100644 index 00000000000..b9981c7c50a --- /dev/null +++ b/tests/rustdoc-ui/coverage/private.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...s/rustdoc-ui/coverage/private.rs | 4 | 57.1% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 4 | 57.1% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/statics-consts.rs b/tests/rustdoc-ui/coverage/statics-consts.rs new file mode 100644 index 00000000000..85cc2384739 --- /dev/null +++ b/tests/rustdoc-ui/coverage/statics-consts.rs @@ -0,0 +1,23 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +//! gotta make sure we can count statics and consts correctly, too + +/// static like electricity, right? +pub static THIS_STATIC: usize = 0; + +/// (it's not electricity, is it) +pub const THIS_CONST: usize = 1; + +/// associated consts show up separately, but let's throw them in as well +pub trait SomeTrait { + /// just like that, yeah + const ASSOC_CONST: usize; +} + +pub struct SomeStruct; + +impl SomeStruct { + /// wait, structs can have them too, can't forget those + pub const ASSOC_CONST: usize = 100; +} diff --git a/tests/rustdoc-ui/coverage/statics-consts.stdout b/tests/rustdoc-ui/coverage/statics-consts.stdout new file mode 100644 index 00000000000..dbea3a3ea23 --- /dev/null +++ b/tests/rustdoc-ui/coverage/statics-consts.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...oc-ui/coverage/statics-consts.rs | 6 | 85.7% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 6 | 85.7% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/coverage/traits.rs b/tests/rustdoc-ui/coverage/traits.rs new file mode 100644 index 00000000000..89044369e6a --- /dev/null +++ b/tests/rustdoc-ui/coverage/traits.rs @@ -0,0 +1,38 @@ +//@ compile-flags:-Z unstable-options --show-coverage +//@ check-pass + +#![feature(trait_alias)] +#![feature(type_alias_impl_trait)] + +/// look at this trait right here +pub trait ThisTrait { + /// that's a trait all right + fn right_here(&self); + + /// even the provided functions show up as trait methods + fn aww_yeah(&self) {} + + /// gotta check those associated types, they're slippery + type SomeType; +} + +/// so what happens if we take some struct... +#[derive(Clone)] +pub struct SomeStruct; + +/// ...and slap this trait on it? +impl ThisTrait for SomeStruct { + /// nothing! trait impls are totally ignored in this calculation, sorry. + fn right_here(&self) {} + + type SomeType = String; +} + +/// but what about those aliases? i hear they're pretty exotic +pub trait MyAlias = ThisTrait + Send + Sync; + +/// woah, getting all opaque in here +pub type ThisExists = impl ThisTrait; + +/// why don't we get a little more concrete +pub fn defines() -> ThisExists { SomeStruct {} } diff --git a/tests/rustdoc-ui/coverage/traits.stdout b/tests/rustdoc-ui/coverage/traits.stdout new file mode 100644 index 00000000000..0c7857cf29c --- /dev/null +++ b/tests/rustdoc-ui/coverage/traits.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...ts/rustdoc-ui/coverage/traits.rs | 8 | 88.9% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 8 | 88.9% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/crate-reference-in-block-module.rs b/tests/rustdoc-ui/crate-reference-in-block-module.rs new file mode 100644 index 00000000000..e27c4856867 --- /dev/null +++ b/tests/rustdoc-ui/crate-reference-in-block-module.rs @@ -0,0 +1,5 @@ +//@ check-pass +fn main() { + /// [](crate) + struct X; +} diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs new file mode 100644 index 00000000000..32ba331527d --- /dev/null +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -0,0 +1,25 @@ +// This test ensures that warnings are working as expected for "custom_code_classes_in_docs" +// feature. + +#![deny(warnings)] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +/// ```{class="} +/// main; +/// ``` +//~^^^ ERROR unclosed quote string +//~| ERROR unclosed quote string +/// ```" +/// main; +/// ``` +pub fn foo() {} diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr new file mode 100644 index 00000000000..fbe3df5d9d3 --- /dev/null +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -0,0 +1,33 @@ +error: unclosed quote string `"` + --> $DIR/custom_code_classes_in_docs-warning3.rs:17:1 + | +LL | / /// ```{class="} +LL | | /// main; +LL | | /// ``` +... | +LL | | /// main; +LL | | /// ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/custom_code_classes_in_docs-warning3.rs:4:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` + +error: unclosed quote string `"` + --> $DIR/custom_code_classes_in_docs-warning3.rs:17:1 + | +LL | / /// ```{class="} +LL | | /// main; +LL | | /// ``` +... | +LL | | /// main; +LL | | /// ``` + | |_______^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/deprecated-attrs.rs b/tests/rustdoc-ui/deprecated-attrs.rs new file mode 100644 index 00000000000..dcf8a52de41 --- /dev/null +++ b/tests/rustdoc-ui/deprecated-attrs.rs @@ -0,0 +1,24 @@ +//@ compile-flags: --passes unknown-pass + +#![doc(no_default_passes)] +//~^ ERROR unknown `doc` attribute `no_default_passes` +//~| NOTE no longer functions +//~| NOTE see issue #44136 +//~| HELP you may want to use `doc(document_private_items)` +//~| NOTE `doc(no_default_passes)` is now a no-op +//~| NOTE `#[deny(invalid_doc_attributes)]` on by default +#![doc(passes = "collapse-docs unindent-comments")] +//~^ ERROR unknown `doc` attribute `passes` +//~| NOTE no longer functions +//~| NOTE see issue #44136 +//~| HELP you may want to use `doc(document_private_items)` +//~| NOTE `doc(passes)` is now a no-op +#![doc(plugins = "xxx")] +//~^ ERROR unknown `doc` attribute `plugins` +//~| NOTE see issue #44136 +//~| NOTE no longer functions +//~| NOTE `doc(plugins)` is now a no-op + +//~? WARN the `passes` flag no longer functions +//~? NOTE see issue #44136 +//~? HELP you may want to use --document-private-items diff --git a/tests/rustdoc-ui/deprecated-attrs.stderr b/tests/rustdoc-ui/deprecated-attrs.stderr new file mode 100644 index 00000000000..3e982052233 --- /dev/null +++ b/tests/rustdoc-ui/deprecated-attrs.stderr @@ -0,0 +1,37 @@ +warning: the `passes` flag no longer functions + | + = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information + = help: you may want to use --document-private-items + +error: unknown `doc` attribute `no_default_passes` + --> $DIR/deprecated-attrs.rs:3:8 + | +LL | #![doc(no_default_passes)] + | ^^^^^^^^^^^^^^^^^ no longer functions + | + = note: `doc` attribute `no_default_passes` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> + = help: you may want to use `doc(document_private_items)` + = note: `doc(no_default_passes)` is now a no-op + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: unknown `doc` attribute `passes` + --> $DIR/deprecated-attrs.rs:10:8 + | +LL | #![doc(passes = "collapse-docs unindent-comments")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no longer functions + | + = note: `doc` attribute `passes` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> + = help: you may want to use `doc(document_private_items)` + = note: `doc(passes)` is now a no-op + +error: unknown `doc` attribute `plugins` + --> $DIR/deprecated-attrs.rs:16:8 + | +LL | #![doc(plugins = "xxx")] + | ^^^^^^^^^^^^^^^ no longer functions + | + = note: `doc` attribute `plugins` no longer functions; see issue #44136 <https://github.com/rust-lang/rust/issues/44136> and CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622> + = note: `doc(plugins)` is now a no-op + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/deref-generic.rs b/tests/rustdoc-ui/deref-generic.rs new file mode 100644 index 00000000000..51d6dc3db37 --- /dev/null +++ b/tests/rustdoc-ui/deref-generic.rs @@ -0,0 +1,15 @@ +//@ check-pass +// #81395: Fix ICE when recursing into Deref target only differing in type args + +pub struct Generic<T>(T); + +impl<'a> std::ops::Deref for Generic<&'a mut ()> { + type Target = Generic<&'a ()>; + fn deref(&self) -> &Self::Target { + unimplemented!() + } +} + +impl<'a> Generic<&'a ()> { + pub fn some_method(&self) {} +} diff --git a/tests/rustdoc-ui/diagnostic-width.rs b/tests/rustdoc-ui/diagnostic-width.rs new file mode 100644 index 00000000000..e255496f02e --- /dev/null +++ b/tests/rustdoc-ui/diagnostic-width.rs @@ -0,0 +1,5 @@ +//@ compile-flags: --diagnostic-width=10 +#![deny(rustdoc::bare_urls)] + +/// This is a long line that contains a http://link.com +pub struct Foo; //~^ ERROR diff --git a/tests/rustdoc-ui/diagnostic-width.stderr b/tests/rustdoc-ui/diagnostic-width.stderr new file mode 100644 index 00000000000..94fc2343faf --- /dev/null +++ b/tests/rustdoc-ui/diagnostic-width.stderr @@ -0,0 +1,19 @@ +error: this URL is not a hyperlink + --> $DIR/diagnostic-width.rs:4:41 + | +LL | ... a http://link.com + | ^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +note: the lint level is defined here + --> $DIR/diagnostic-width.rs:2:9 + | +LL | ...ny(ru...are_urls)] + | ^^...^^^^^^^^ +help: use an automatic link instead + | +LL | /// This is a long line that contains a <http://link.com> + | + + + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs new file mode 100644 index 00000000000..1174e16dd53 --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs @@ -0,0 +1,111 @@ +//@ check-pass +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" + +//! [struct@m!()] //~ WARN: unmatched disambiguator `struct` and suffix `!()` +//! [struct@m!{}] +//! [struct@m![]] +//! [struct@f()] //~ WARN: unmatched disambiguator `struct` and suffix `()` +//! [struct@m!] //~ WARN: unmatched disambiguator `struct` and suffix `!` +//! +//! [enum@m!()] //~ WARN: unmatched disambiguator `enum` and suffix `!()` +//! [enum@m!{}] +//! [enum@m![]] +//! [enum@f()] //~ WARN: unmatched disambiguator `enum` and suffix `()` +//! [enum@m!] //~ WARN: unmatched disambiguator `enum` and suffix `!` +//! +//! [trait@m!()] //~ WARN: unmatched disambiguator `trait` and suffix `!()` +//! [trait@m!{}] +//! [trait@m![]] +//! [trait@f()] //~ WARN: unmatched disambiguator `trait` and suffix `()` +//! [trait@m!] //~ WARN: unmatched disambiguator `trait` and suffix `!` +//! +//! [module@m!()] //~ WARN: unmatched disambiguator `module` and suffix `!()` +//! [module@m!{}] +//! [module@m![]] +//! [module@f()] //~ WARN: unmatched disambiguator `module` and suffix `()` +//! [module@m!] //~ WARN: unmatched disambiguator `module` and suffix `!` +//! +//! [mod@m!()] //~ WARN: unmatched disambiguator `mod` and suffix `!()` +//! [mod@m!{}] +//! [mod@m![]] +//! [mod@f()] //~ WARN: unmatched disambiguator `mod` and suffix `()` +//! [mod@m!] //~ WARN: unmatched disambiguator `mod` and suffix `!` +//! +//! [const@m!()] //~ WARN: unmatched disambiguator `const` and suffix `!()` +//! [const@m!{}] +//! [const@m![]] +//! [const@f()] //~ WARN: incompatible link kind for `f` +//! [const@m!] //~ WARN: unmatched disambiguator `const` and suffix `!` +//! +//! [constant@m!()] //~ WARN: unmatched disambiguator `constant` and suffix `!()` +//! [constant@m!{}] +//! [constant@m![]] +//! [constant@f()] //~ WARN: incompatible link kind for `f` +//! [constant@m!] //~ WARN: unmatched disambiguator `constant` and suffix `!` +//! +//! [static@m!()] //~ WARN: unmatched disambiguator `static` and suffix `!()` +//! [static@m!{}] +//! [static@m![]] +//! [static@f()] //~ WARN: incompatible link kind for `f` +//! [static@m!] //~ WARN: unmatched disambiguator `static` and suffix `!` +//! +//! [function@m!()] //~ WARN: unmatched disambiguator `function` and suffix `!()` +//! [function@m!{}] +//! [function@m![]] +//! [function@f()] +//! [function@m!] //~ WARN: unmatched disambiguator `function` and suffix `!` +//! +//! [fn@m!()] //~ WARN: unmatched disambiguator `fn` and suffix `!()` +//! [fn@m!{}] +//! [fn@m![]] +//! [fn@f()] +//! [fn@m!] //~ WARN: unmatched disambiguator `fn` and suffix `!` +//! +//! [method@m!()] //~ WARN: unmatched disambiguator `method` and suffix `!()` +//! [method@m!{}] +//! [method@m![]] +//! [method@f()] +//! [method@m!] //~ WARN: unmatched disambiguator `method` and suffix `!` +//! +//! [derive@m!()] //~ WARN: incompatible link kind for `m` +//! [derive@m!{}] //~ WARN: incompatible link kind for `m` +//! [derive@m![]] +//! [derive@f()] //~ WARN: unmatched disambiguator `derive` and suffix `()` +//! [derive@m!] //~ WARN: incompatible link kind for `m` +//! +//! [type@m!()] //~ WARN: unmatched disambiguator `type` and suffix `!()` +//! [type@m!{}] +//! [type@m![]] +//! [type@f()] //~ WARN: unmatched disambiguator `type` and suffix `()` +//! [type@m!] //~ WARN: unmatched disambiguator `type` and suffix `!` +//! +//! [value@m!()] //~ WARN: unmatched disambiguator `value` and suffix `!()` +//! [value@m!{}] +//! [value@m![]] +//! [value@f()] +//! [value@m!] //~ WARN: unmatched disambiguator `value` and suffix `!` +//! +//! [macro@m!()] +//! [macro@m!{}] +//! [macro@m![]] +//! [macro@f()] //~ WARN: unmatched disambiguator `macro` and suffix `()` +//! [macro@m!] +//! +//! [prim@m!()] //~ WARN: unmatched disambiguator `prim` and suffix `!()` +//! [prim@m!{}] +//! [prim@m![]] +//! [prim@f()] //~ WARN: unmatched disambiguator `prim` and suffix `()` +//! [prim@m!] //~ WARN: unmatched disambiguator `prim` and suffix `!` +//! +//! [primitive@m!()] //~ WARN: unmatched disambiguator `primitive` and suffix `!()` +//! [primitive@m!{}] +//! [primitive@m![]] +//! [primitive@f()] //~ WARN: unmatched disambiguator `primitive` and suffix `()` +//! [primitive@m!] //~ WARN: unmatched disambiguator `primitive` and suffix `!` + +#[macro_export] +macro_rules! m { + () => {}; +} + +pub fn f() {} diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr new file mode 100644 index 00000000000..f4e40a48873 --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr @@ -0,0 +1,395 @@ +warning: unmatched disambiguator `struct` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:4:6 + | +LL | //! [struct@m!()] + | ^^^^^^ + | + = 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: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: unmatched disambiguator `struct` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:7:6 + | +LL | //! [struct@f()] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `struct` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:8:6 + | +LL | //! [struct@m!] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `enum` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:10:6 + | +LL | //! [enum@m!()] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `enum` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:13:6 + | +LL | //! [enum@f()] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `enum` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:14:6 + | +LL | //! [enum@m!] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `trait` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:16:6 + | +LL | //! [trait@m!()] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `trait` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:19:6 + | +LL | //! [trait@f()] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `trait` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:20:6 + | +LL | //! [trait@m!] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `module` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:22:6 + | +LL | //! [module@m!()] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `module` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:25:6 + | +LL | //! [module@f()] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `module` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:26:6 + | +LL | //! [module@m!] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `mod` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:28:6 + | +LL | //! [mod@m!()] + | ^^^ + | + = 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 + +warning: unmatched disambiguator `mod` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:31:6 + | +LL | //! [mod@f()] + | ^^^ + | + = 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 + +warning: unmatched disambiguator `mod` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:32:6 + | +LL | //! [mod@m!] + | ^^^ + | + = 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 + +warning: unmatched disambiguator `const` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:34:6 + | +LL | //! [const@m!()] + | ^^^^^ + | + = 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 + +warning: incompatible link kind for `f` + --> $DIR/disambiguator-endswith-named-suffix.rs:37:6 + | +LL | //! [const@f()] + | ^^^^^^^^^ this link resolved to a function, which is not a constant + | +help: to link to the function, add parentheses + | +LL - //! [const@f()] +LL + //! [f()] + | + +warning: unmatched disambiguator `const` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:38:6 + | +LL | //! [const@m!] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `constant` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:40:6 + | +LL | //! [constant@m!()] + | ^^^^^^^^ + | + = 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 + +warning: incompatible link kind for `f` + --> $DIR/disambiguator-endswith-named-suffix.rs:43:6 + | +LL | //! [constant@f()] + | ^^^^^^^^^^^^ this link resolved to a function, which is not a constant + | +help: to link to the function, add parentheses + | +LL - //! [constant@f()] +LL + //! [f()] + | + +warning: unmatched disambiguator `constant` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:44:6 + | +LL | //! [constant@m!] + | ^^^^^^^^ + | + = 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 + +warning: unmatched disambiguator `static` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:46:6 + | +LL | //! [static@m!()] + | ^^^^^^ + | + = 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 + +warning: incompatible link kind for `f` + --> $DIR/disambiguator-endswith-named-suffix.rs:49:6 + | +LL | //! [static@f()] + | ^^^^^^^^^^ this link resolved to a function, which is not a static + | +help: to link to the function, add parentheses + | +LL - //! [static@f()] +LL + //! [f()] + | + +warning: unmatched disambiguator `static` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:50:6 + | +LL | //! [static@m!] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `function` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:52:6 + | +LL | //! [function@m!()] + | ^^^^^^^^ + | + = 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 + +warning: unmatched disambiguator `function` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:56:6 + | +LL | //! [function@m!] + | ^^^^^^^^ + | + = 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 + +warning: unmatched disambiguator `fn` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:58:6 + | +LL | //! [fn@m!()] + | ^^ + | + = 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 + +warning: unmatched disambiguator `fn` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:62:6 + | +LL | //! [fn@m!] + | ^^ + | + = 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 + +warning: unmatched disambiguator `method` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:64:6 + | +LL | //! [method@m!()] + | ^^^^^^ + | + = 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 + +warning: unmatched disambiguator `method` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:68:6 + | +LL | //! [method@m!] + | ^^^^^^ + | + = 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 + +warning: incompatible link kind for `m` + --> $DIR/disambiguator-endswith-named-suffix.rs:70:6 + | +LL | //! [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 - //! [derive@m!()] +LL + //! [m!!()] + | + +warning: incompatible link kind for `m` + --> $DIR/disambiguator-endswith-named-suffix.rs:71:6 + | +LL | //! [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 - //! [derive@m!{}] +LL + //! [m!!{}] + | + +warning: unmatched disambiguator `derive` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:73:6 + | +LL | //! [derive@f()] + | ^^^^^^ + | + = 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 + +warning: incompatible link kind for `m` + --> $DIR/disambiguator-endswith-named-suffix.rs:74:6 + | +LL | //! [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 - //! [derive@m!] +LL + //! [m!!] + | + +warning: unmatched disambiguator `type` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:76:6 + | +LL | //! [type@m!()] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `type` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:79:6 + | +LL | //! [type@f()] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `type` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:80:6 + | +LL | //! [type@m!] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `value` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:82:6 + | +LL | //! [value@m!()] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `value` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:86:6 + | +LL | //! [value@m!] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `macro` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:91:6 + | +LL | //! [macro@f()] + | ^^^^^ + | + = 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 + +warning: unmatched disambiguator `prim` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:94:6 + | +LL | //! [prim@m!()] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `prim` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:97:6 + | +LL | //! [prim@f()] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `prim` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:98:6 + | +LL | //! [prim@m!] + | ^^^^ + | + = 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 + +warning: unmatched disambiguator `primitive` and suffix `!()` + --> $DIR/disambiguator-endswith-named-suffix.rs:100:6 + | +LL | //! [primitive@m!()] + | ^^^^^^^^^ + | + = 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 + +warning: unmatched disambiguator `primitive` and suffix `()` + --> $DIR/disambiguator-endswith-named-suffix.rs:103:6 + | +LL | //! [primitive@f()] + | ^^^^^^^^^ + | + = 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 + +warning: unmatched disambiguator `primitive` and suffix `!` + --> $DIR/disambiguator-endswith-named-suffix.rs:104:6 + | +LL | //! [primitive@m!] + | ^^^^^^^^^ + | + = 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 + +warning: 46 warnings emitted + diff --git a/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs new file mode 100644 index 00000000000..b955090e894 --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.rs @@ -0,0 +1,11 @@ +//@ check-pass + +//! [macro@m!] //~ WARN: unresolved link to `m` + +//issue#126986 + +macro_rules! m { + () => {}; +} + +fn main() {} diff --git a/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr new file mode 100644 index 00000000000..2ada7f1a4be --- /dev/null +++ b/tests/rustdoc-ui/disambiguator-macro-endswith-exclamatory.stderr @@ -0,0 +1,11 @@ +warning: unresolved link to `m` + --> $DIR/disambiguator-macro-endswith-exclamatory.rs:3:6 + | +LL | //! [macro@m!] + | ^^^^^^^^ no item named `m` in scope + | + = note: `macro_rules` named `m` exists in this crate, but it is not in scope at this link's location + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/doc-alias-assoc-const.rs b/tests/rustdoc-ui/doc-alias-assoc-const.rs new file mode 100644 index 00000000000..d95324734be --- /dev/null +++ b/tests/rustdoc-ui/doc-alias-assoc-const.rs @@ -0,0 +1,21 @@ +#![feature(trait_alias)] + +pub struct Foo; + +pub trait Bar { + const BAZ: u8; +} + +impl Bar for Foo { + #[doc(alias = "CONST_BAZ")] //~ ERROR + const BAZ: u8 = 0; +} + +impl Foo { + #[doc(alias = "CONST_FOO")] // ok! + pub const FOO: u8 = 0; + + pub fn bar() -> u8 { + Self::FOO + } +} diff --git a/tests/rustdoc-ui/doc-alias-assoc-const.stderr b/tests/rustdoc-ui/doc-alias-assoc-const.stderr new file mode 100644 index 00000000000..cd3ad4ab393 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias-assoc-const.stderr @@ -0,0 +1,8 @@ +error: `#[doc(alias = "...")]` isn't allowed on associated constant in trait implementation block + --> $DIR/doc-alias-assoc-const.rs:10:11 + | +LL | #[doc(alias = "CONST_BAZ")] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doc-alias-crate-level.rs b/tests/rustdoc-ui/doc-alias-crate-level.rs new file mode 100644 index 00000000000..70618ac01df --- /dev/null +++ b/tests/rustdoc-ui/doc-alias-crate-level.rs @@ -0,0 +1,4 @@ +#![doc(alias = "crate-level-not-working")] //~ ERROR + +#[doc(alias = "shouldn't work!")] //~ ERROR +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-alias-crate-level.stderr b/tests/rustdoc-ui/doc-alias-crate-level.stderr new file mode 100644 index 00000000000..fc8095e03ca --- /dev/null +++ b/tests/rustdoc-ui/doc-alias-crate-level.stderr @@ -0,0 +1,14 @@ +error: '\'' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/doc-alias-crate-level.rs:3:15 + | +LL | #[doc(alias = "shouldn't work!")] + | ^^^^^^^^^^^^^^^^^ + +error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute + --> $DIR/doc-alias-crate-level.rs:1:8 + | +LL | #![doc(alias = "crate-level-not-working")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/doc-alias-same-name.rs b/tests/rustdoc-ui/doc-alias-same-name.rs new file mode 100644 index 00000000000..da97c267618 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias-same-name.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +#[doc(alias = "Foo")] //~ ERROR +pub struct Foo; diff --git a/tests/rustdoc-ui/doc-alias-same-name.stderr b/tests/rustdoc-ui/doc-alias-same-name.stderr new file mode 100644 index 00000000000..a9da75c0171 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias-same-name.stderr @@ -0,0 +1,8 @@ +error: `#[doc(alias = "...")]` is the same as the item's name + --> $DIR/doc-alias-same-name.rs:3:7 + | +LL | #[doc(alias = "Foo")] + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr b/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr new file mode 100644 index 00000000000..0878f7edbf4 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr @@ -0,0 +1,30 @@ +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-check-cfg.rs:12:12 + | +LL | #![doc(cfg(foo))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-check-cfg.rs:19:11 + | +LL | #[doc(cfg(foo))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-check-cfg.rs:15:11 + | +LL | #[doc(cfg(foo))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + +warning: 3 warnings emitted + diff --git a/tests/rustdoc-ui/doc-cfg-check-cfg.rs b/tests/rustdoc-ui/doc-cfg-check-cfg.rs new file mode 100644 index 00000000000..7d37077a32d --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-check-cfg.rs @@ -0,0 +1,25 @@ +// Ensure that `doc(cfg())` respects `check-cfg` +// Currently not properly working + +//@ check-pass +//@ no-auto-check-cfg + +//@ revisions: no_check cfg_empty cfg_foo +//@[cfg_empty] compile-flags: --check-cfg cfg() +//@[cfg_foo] compile-flags: --check-cfg cfg(foo) + +#![feature(doc_cfg)] +#![doc(cfg(foo))] +//[cfg_empty]~^ WARN unexpected `cfg` condition name: `foo` + +#[doc(cfg(foo))] +//[cfg_empty]~^ WARN unexpected `cfg` condition name: `foo` +pub fn foo() {} + +#[doc(cfg(foo))] +//[cfg_empty]~^ WARN unexpected `cfg` condition name: `foo` +pub mod module { + #[allow(unexpected_cfgs)] + #[doc(cfg(bar))] + pub fn bar() {} +} diff --git a/tests/rustdoc-ui/doc-cfg-unstable.rs b/tests/rustdoc-ui/doc-cfg-unstable.rs new file mode 100644 index 00000000000..b77c3654497 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-unstable.rs @@ -0,0 +1,6 @@ +// #138113: rustdoc didn't gate unstable predicates inside `doc(cfg(..))` +#![feature(doc_cfg)] + +// `cfg_version` +#[doc(cfg(sanitize = "thread"))] //~ ERROR `cfg(sanitize)` is experimental and subject to change +pub fn cfg_sanitize() {} diff --git a/tests/rustdoc-ui/doc-cfg-unstable.stderr b/tests/rustdoc-ui/doc-cfg-unstable.stderr new file mode 100644 index 00000000000..9651c5f1a0b --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-unstable.stderr @@ -0,0 +1,13 @@ +error[E0658]: `cfg(sanitize)` is experimental and subject to change + --> $DIR/doc-cfg-unstable.rs:5:11 + | +LL | #[doc(cfg(sanitize = "thread"))] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #39699 <https://github.com/rust-lang/rust/issues/39699> for more information + = help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc-ui/doc-cfg.rs b/tests/rustdoc-ui/doc-cfg.rs new file mode 100644 index 00000000000..14943bbc341 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg.rs @@ -0,0 +1,11 @@ +#![feature(doc_cfg)] + +#[doc(cfg(), cfg(foo, bar))] +//~^ ERROR +//~^^ ERROR +#[doc(cfg(foo), cfg(bar))] +//~^ WARN unexpected `cfg` condition name: `foo` +//~^^ WARN unexpected `cfg` condition name: `bar` +#[doc(cfg())] //~ ERROR +#[doc(cfg(foo, bar))] //~ ERROR +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr new file mode 100644 index 00000000000..1233ee010de --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg.stderr @@ -0,0 +1,46 @@ +error: `cfg` predicate is not specified + --> $DIR/doc-cfg.rs:3:7 + | +LL | #[doc(cfg(), cfg(foo, bar))] + | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/doc-cfg.rs:3:23 + | +LL | #[doc(cfg(), cfg(foo, bar))] + | ^^^ + +error: `cfg` predicate is not specified + --> $DIR/doc-cfg.rs:9:7 + | +LL | #[doc(cfg())] + | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/doc-cfg.rs:10:16 + | +LL | #[doc(cfg(foo, bar))] + | ^^^ + +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg.rs:6:11 + | +LL | #[doc(cfg(foo), cfg(bar))] + | ^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `bar` + --> $DIR/doc-cfg.rs:6:21 + | +LL | #[doc(cfg(foo), cfg(bar))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(bar)` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + +error: aborting due to 4 previous errors; 2 warnings emitted + diff --git a/tests/rustdoc-ui/doc-include-suggestion.rs b/tests/rustdoc-ui/doc-include-suggestion.rs new file mode 100644 index 00000000000..aff0a24ace8 --- /dev/null +++ b/tests/rustdoc-ui/doc-include-suggestion.rs @@ -0,0 +1,6 @@ +#[doc(include = "external-cross-doc.md")] +//~^ ERROR unknown `doc` attribute `include` +//~| HELP use `doc = include_str!` instead +// FIXME(#85497): make this a deny instead so it's more clear what's happening +//~| NOTE on by default +pub struct NeedMoreDocs; diff --git a/tests/rustdoc-ui/doc-include-suggestion.stderr b/tests/rustdoc-ui/doc-include-suggestion.stderr new file mode 100644 index 00000000000..1b4b78a8f26 --- /dev/null +++ b/tests/rustdoc-ui/doc-include-suggestion.stderr @@ -0,0 +1,10 @@ +error: unknown `doc` attribute `include` + --> $DIR/doc-include-suggestion.rs:1:7 + | +LL | #[doc(include = "external-cross-doc.md")] + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` + | + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doctest-output.rs b/tests/rustdoc-ui/doctest-output.rs new file mode 100644 index 00000000000..28364c3a3ea --- /dev/null +++ b/tests/rustdoc-ui/doctest-output.rs @@ -0,0 +1,3 @@ +//@ compile-flags:-Z unstable-options --show-coverage --output-format=doctest + +//~? ERROR `--output-format=doctest` is not supported for the `--show-coverage` option diff --git a/tests/rustdoc-ui/doctest-output.stderr b/tests/rustdoc-ui/doctest-output.stderr new file mode 100644 index 00000000000..20c618dc61b --- /dev/null +++ b/tests/rustdoc-ui/doctest-output.stderr @@ -0,0 +1,2 @@ +error: `--output-format=doctest` is not supported for the `--show-coverage` option + diff --git a/tests/rustdoc-ui/doctest/auxiliary/extern_macros.rs b/tests/rustdoc-ui/doctest/auxiliary/extern_macros.rs new file mode 100644 index 00000000000..ee1fec4c5c2 --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/extern_macros.rs @@ -0,0 +1,7 @@ +#[macro_export] +macro_rules! attrs_on_struct { + ( $( #[$attr:meta] )* ) => { + $( #[$attr] )* + pub struct ExpandedStruct; + } +} diff --git a/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs b/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs new file mode 100644 index 00000000000..388b8f310ae --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/extern_macros_2024.rs @@ -0,0 +1,9 @@ +//@ edition:2024 +#![crate_name="extern_macros"] +#[macro_export] +macro_rules! attrs_on_struct { + ( $( #[$attr:meta] )* ) => { + $( #[$attr] )* + pub struct ExpandedStruct; + } +} diff --git a/tests/rustdoc-ui/doctest/auxiliary/items.rs b/tests/rustdoc-ui/doctest/auxiliary/items.rs new file mode 100644 index 00000000000..40d4eb261e5 --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/items.rs @@ -0,0 +1 @@ +fn item() {} diff --git a/tests/rustdoc-ui/doctest/auxiliary/pub_trait.rs b/tests/rustdoc-ui/doctest/auxiliary/pub_trait.rs new file mode 100644 index 00000000000..0a47fdc74d7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/pub_trait.rs @@ -0,0 +1 @@ +pub trait Trait {} diff --git a/tests/rustdoc-ui/doctest/auxiliary/relative-dir-empty-file b/tests/rustdoc-ui/doctest/auxiliary/relative-dir-empty-file new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/relative-dir-empty-file diff --git a/tests/rustdoc-ui/doctest/auxiliary/relative-dir.md b/tests/rustdoc-ui/doctest/auxiliary/relative-dir.md new file mode 100644 index 00000000000..90097ce82fb --- /dev/null +++ b/tests/rustdoc-ui/doctest/auxiliary/relative-dir.md @@ -0,0 +1,3 @@ +```rust +let x = include_bytes!("relative-dir-empty-file"); +``` diff --git a/tests/rustdoc-ui/doctest/block-doc-comment.rs b/tests/rustdoc-ui/doctest/block-doc-comment.rs new file mode 100644 index 00000000000..84bb5abb244 --- /dev/null +++ b/tests/rustdoc-ui/doctest/block-doc-comment.rs @@ -0,0 +1,17 @@ +//@ check-pass +//@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// This test ensures that no code block is detected in the doc comments. + +pub mod Wormhole { + /** # Returns + * + */ + pub fn foofoo() {} + /** + * # Returns + * + */ + pub fn barbar() {} +} diff --git a/tests/rustdoc-ui/doctest/block-doc-comment.stdout b/tests/rustdoc-ui/doctest/block-doc-comment.stdout new file mode 100644 index 00000000000..7326c0a25a0 --- /dev/null +++ b/tests/rustdoc-ui/doctest/block-doc-comment.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/cfg-test.rs b/tests/rustdoc-ui/doctest/cfg-test.rs new file mode 100644 index 00000000000..340a2eec87a --- /dev/null +++ b/tests/rustdoc-ui/doctest/cfg-test.rs @@ -0,0 +1,31 @@ +//@ check-pass +//@ compile-flags:--test --test-args --test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// Crates like core have doctests gated on `cfg(not(test))` so we need to make +// sure `cfg(test)` is not active when running `rustdoc --test`. + +/// this doctest will be ignored: +/// +/// ``` +/// assert!(false); +/// ``` +#[cfg(test)] +pub struct Foo; + +/// this doctest will be tested: +/// +/// ``` +/// assert!(true); +/// ``` +#[cfg(not(test))] +pub struct Foo; + +/// this doctest will be tested, but will not appear in documentation: +/// +/// ``` +/// assert!(true) +/// ``` +#[cfg(doctest)] +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/cfg-test.stdout b/tests/rustdoc-ui/doctest/cfg-test.stdout new file mode 100644 index 00000000000..2960ff8d3b4 --- /dev/null +++ b/tests/rustdoc-ui/doctest/cfg-test.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/cfg-test.rs - Bar (line 27) ... ok +test $DIR/cfg-test.rs - Foo (line 19) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/check-attr-test.rs b/tests/rustdoc-ui/doctest/check-attr-test.rs new file mode 100644 index 00000000000..81281db624b --- /dev/null +++ b/tests/rustdoc-ui/doctest/check-attr-test.rs @@ -0,0 +1,31 @@ +//@ compile-flags:--test + +#![deny(rustdoc::invalid_codeblock_attributes)] + +/// foo +/// +/// ```compile-fail,compilefail,comPile_fail +/// boo +/// ``` +pub fn foo() {} + +/// bar +/// +/// ```should-panic,shouldpanic,shOuld_panic +/// boo +/// ``` +pub fn bar() {} + +/// foobar +/// +/// ```no-run,norun,nO_run +/// boo +/// ``` +pub fn foobar() {} + +/// b +/// +/// ```test-harness,testharness,tesT_harness +/// boo +/// ``` +pub fn b() {} diff --git a/tests/rustdoc-ui/doctest/check-attr-test.stderr b/tests/rustdoc-ui/doctest/check-attr-test.stderr new file mode 100644 index 00000000000..257136d1633 --- /dev/null +++ b/tests/rustdoc-ui/doctest/check-attr-test.stderr @@ -0,0 +1,163 @@ +error: unknown attribute `compile-fail` + --> $DIR/check-attr-test.rs:5:1 + | +5 | / /// foo +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo +9 | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` +note: the lint level is defined here + --> $DIR/check-attr-test.rs:3:9 + | +3 | #![deny(rustdoc::invalid_codeblock_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown attribute `compilefail` + --> $DIR/check-attr-test.rs:5:1 + | +5 | / /// foo +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo +9 | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `comPile_fail` + --> $DIR/check-attr-test.rs:5:1 + | +5 | / /// foo +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo +9 | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `should-panic` + --> $DIR/check-attr-test.rs:12:1 + | +12 | / /// bar +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo +16 | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `shouldpanic` + --> $DIR/check-attr-test.rs:12:1 + | +12 | / /// bar +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo +16 | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `shOuld_panic` + --> $DIR/check-attr-test.rs:12:1 + | +12 | / /// bar +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo +16 | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `no-run` + --> $DIR/check-attr-test.rs:19:1 + | +19 | / /// foobar +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo +23 | | /// ``` + | |_______^ + | + = help: use `no_run` to compile, but not run, the code sample during testing + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `norun` + --> $DIR/check-attr-test.rs:19:1 + | +19 | / /// foobar +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo +23 | | /// ``` + | |_______^ + | + = help: use `no_run` to compile, but not run, the code sample during testing + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `nO_run` + --> $DIR/check-attr-test.rs:19:1 + | +19 | / /// foobar +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo +23 | | /// ``` + | |_______^ + | + = help: use `no_run` to compile, but not run, the code sample during testing + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `test-harness` + --> $DIR/check-attr-test.rs:26:1 + | +26 | / /// b +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo +30 | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `testharness` + --> $DIR/check-attr-test.rs:26:1 + | +26 | / /// b +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo +30 | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `tesT_harness` + --> $DIR/check-attr-test.rs:26:1 + | +26 | / /// b +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo +30 | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: aborting due to 12 previous errors + diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.rs b/tests/rustdoc-ui/doctest/check-cfg-test.rs new file mode 100644 index 00000000000..39fdb3a5853 --- /dev/null +++ b/tests/rustdoc-ui/doctest/check-cfg-test.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags: --test --nocapture --check-cfg=cfg(feature,values("test")) -Z unstable-options +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// The doctest will produce a warning because feature invalid is unexpected +/// ``` +/// #[cfg(feature = "invalid")] +/// assert!(false); +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stderr b/tests/rustdoc-ui/doctest/check-cfg-test.stderr new file mode 100644 index 00000000000..a2f173a2cb9 --- /dev/null +++ b/tests/rustdoc-ui/doctest/check-cfg-test.stderr @@ -0,0 +1,13 @@ +warning: unexpected `cfg` condition value: `invalid` + --> $DIR/check-cfg-test.rs:9:7 + | +LL | #[cfg(feature = "invalid")] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `feature` are: `test` + = help: to expect this configuration use `--check-cfg=cfg(feature, values("invalid"))` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stdout b/tests/rustdoc-ui/doctest/check-cfg-test.stdout new file mode 100644 index 00000000000..b7db49bcfa8 --- /dev/null +++ b/tests/rustdoc-ui/doctest/check-cfg-test.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/check-cfg-test.rs - Foo (line 8) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs new file mode 100644 index 00000000000..944939c8efe --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs @@ -0,0 +1,15 @@ +//@ compile-flags:--test --test-args --test-threads=1 +//@ failure-status: 101 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +//! ``` +#![doc = "#![all\ +ow(unused)]"] +//! ``` +//! +//! ``` +#![doc = r#"#![all\ +ow(unused)]"#] +//! ``` diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout new file mode 100644 index 00000000000..0baff3df144 --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.stdout @@ -0,0 +1,31 @@ + +running 2 tests +test $DIR/comment-in-attr-134221-2.rs - (line 11) ... FAILED +test $DIR/comment-in-attr-134221-2.rs - (line 7) ... ok + +failures: + +---- $DIR/comment-in-attr-134221-2.rs - (line 11) stdout ---- +error: unknown start of token: \ + --> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL + | +LL | #![all\ + | ^ + +error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `ow` + --> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL + | +LL | #![all\ + | - expected one of `(`, `::`, `=`, `[`, `]`, or `{` +LL | ow(unused)] + | ^^ unexpected token + +error: aborting due to 2 previous errors + +Couldn't compile the test. + +failures: + $DIR/comment-in-attr-134221-2.rs - (line 11) + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs new file mode 100644 index 00000000000..2fbc8a21560 --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs @@ -0,0 +1,27 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/134221>. +// It checks that even if there are comments in the attributes, the attributes +// will still be generated correctly (and therefore fail in this test). + +//@ compile-flags:--test --test-args --test-threads=1 +//@ failure-status: 101 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/*! +```rust +#![feature( + foo, // +)] +``` + +```rust +#![feature( + foo, +)] +``` + +```rust +#![ +``` +*/ diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout new file mode 100644 index 00000000000..aa1b27d1f0b --- /dev/null +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.stdout @@ -0,0 +1,50 @@ + +running 3 tests +test $DIR/comment-in-attr-134221.rs - (line 11) ... FAILED +test $DIR/comment-in-attr-134221.rs - (line 17) ... FAILED +test $DIR/comment-in-attr-134221.rs - (line 23) ... FAILED + +failures: + +---- $DIR/comment-in-attr-134221.rs - (line 11) stdout ---- +error[E0635]: unknown feature `foo` + --> $DIR/comment-in-attr-134221.rs:$LINE:$COL + | +LL | foo, // + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0635`. +Couldn't compile the test. +---- $DIR/comment-in-attr-134221.rs - (line 17) stdout ---- +error[E0635]: unknown feature `foo` + --> $DIR/comment-in-attr-134221.rs:$LINE:$COL + | +LL | foo, + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0635`. +Couldn't compile the test. +---- $DIR/comment-in-attr-134221.rs - (line 23) stdout ---- +error: this file contains an unclosed delimiter + --> $DIR/comment-in-attr-134221.rs:$LINE:$COL + | +LL | #![ + | -^ + | | + | unclosed delimiter + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/comment-in-attr-134221.rs - (line 11) + $DIR/comment-in-attr-134221.rs - (line 17) + $DIR/comment-in-attr-134221.rs - (line 23) + +test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.rs b/tests/rustdoc-ui/doctest/dead-code-2024.rs new file mode 100644 index 00000000000..079d44570bb --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-2024.rs @@ -0,0 +1,16 @@ +// This test ensures that the 2024 edition merged doctest will not use `#[allow(unused)]`. + +//@ edition: 2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +#![doc(test(attr(allow(unused_variables), deny(warnings))))] + +/// Example +/// +/// ```rust,no_run +/// trait T { fn f(); } +/// ``` +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.stdout b/tests/rustdoc-ui/doctest/dead-code-2024.stdout new file mode 100644 index 00000000000..a943a177e10 --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-2024.stdout @@ -0,0 +1,29 @@ + +running 1 test +test $DIR/dead-code-2024.rs - f (line 13) - compile ... FAILED + +failures: + +---- $DIR/dead-code-2024.rs - f (line 13) stdout ---- +error: trait `T` is never used + --> $DIR/dead-code-2024.rs:14:7 + | +LL | trait T { fn f(); } + | ^ + | +note: the lint level is defined here + --> $DIR/dead-code-2024.rs:12:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/dead-code-2024.rs - f (line 13) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/dead-code-items.rs b/tests/rustdoc-ui/doctest/dead-code-items.rs new file mode 100644 index 00000000000..015504cbced --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-items.rs @@ -0,0 +1,116 @@ +// Same test as dead-code-module but with 2 doc(test(attr())) at different levels. + +//@ edition: 2024 +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +#![doc(test(attr(deny(warnings))))] + +#[doc(test(attr(allow(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// trait OnlyWarning { fn no_deny_warnings(); } +/// ``` +static S: u32 = 5; + +#[doc(test(attr(allow(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// let unused_error = 5; +/// +/// fn dead_code_but_no_error() {} +/// ``` +const C: u32 = 5; + +#[doc(test(attr(allow(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// trait OnlyWarningAtA { fn no_deny_warnings(); } +/// ``` +struct A { + #[doc(test(attr(deny(dead_code))))] + /// Example + /// + /// ```rust,no_run + /// trait DeadCodeInField {} + /// ``` + field: u32 +} + +#[doc(test(attr(allow(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// trait OnlyWarningAtU { fn no_deny_warnings(); } +/// ``` +union U { + #[doc(test(attr(deny(dead_code))))] + /// Example + /// + /// ```rust,no_run + /// trait DeadCodeInUnionField {} + /// ``` + field: u32, + /// Example + /// + /// ```rust,no_run + /// trait NotDeadCodeInUnionField {} + /// ``` + field2: u64, +} + +#[doc(test(attr(deny(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// let not_dead_code_but_unused = 5; +/// ``` +enum Enum { + #[doc(test(attr(allow(dead_code))))] + /// Example + /// + /// ```rust,no_run + /// trait NotDeadCodeInVariant {} + /// + /// fn main() { let unused_in_variant = 5; } + /// ``` + Variant1, +} + +#[doc(test(attr(allow(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// trait OnlyWarningAtImplA { fn no_deny_warnings(); } +/// ``` +impl A { + /// Example + /// + /// ```rust,no_run + /// trait NotDeadCodeInImplMethod {} + /// ``` + fn method() {} +} + +#[doc(test(attr(deny(dead_code))))] +/// Example +/// +/// ```rust,no_run +/// trait StillDeadCodeAtMyTrait { } +/// ``` +trait MyTrait { + #[doc(test(attr(allow(dead_code))))] + /// Example + /// + /// ```rust,no_run + /// trait NotDeadCodeAtImplFn {} + /// + /// fn main() { let unused_in_impl = 5; } + /// ``` + fn my_trait_fn(); +} diff --git a/tests/rustdoc-ui/doctest/dead-code-items.stdout b/tests/rustdoc-ui/doctest/dead-code-items.stdout new file mode 100644 index 00000000000..4b9d8be94dd --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-items.stdout @@ -0,0 +1,146 @@ + +running 13 tests +test $DIR/dead-code-items.rs - A (line 32) - compile ... ok +test $DIR/dead-code-items.rs - A (line 88) - compile ... ok +test $DIR/dead-code-items.rs - A::field (line 39) - compile ... FAILED +test $DIR/dead-code-items.rs - A::method (line 94) - compile ... ok +test $DIR/dead-code-items.rs - C (line 22) - compile ... FAILED +test $DIR/dead-code-items.rs - Enum (line 70) - compile ... FAILED +test $DIR/dead-code-items.rs - Enum::Variant1 (line 77) - compile ... FAILED +test $DIR/dead-code-items.rs - MyTrait (line 103) - compile ... FAILED +test $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) - compile ... FAILED +test $DIR/dead-code-items.rs - S (line 14) - compile ... ok +test $DIR/dead-code-items.rs - U (line 48) - compile ... ok +test $DIR/dead-code-items.rs - U::field (line 55) - compile ... FAILED +test $DIR/dead-code-items.rs - U::field2 (line 61) - compile ... ok + +failures: + +---- $DIR/dead-code-items.rs - A::field (line 39) stdout ---- +error: trait `DeadCodeInField` is never used + --> $DIR/dead-code-items.rs:40:7 + | +LL | trait DeadCodeInField {} + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:38:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to 1 previous error + +Couldn't compile the test. +---- $DIR/dead-code-items.rs - C (line 22) stdout ---- +error: unused variable: `unused_error` + --> $DIR/dead-code-items.rs:23:5 + | +LL | let unused_error = 5; + | ^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_error` + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:20:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. +---- $DIR/dead-code-items.rs - Enum (line 70) stdout ---- +error: unused variable: `not_dead_code_but_unused` + --> $DIR/dead-code-items.rs:71:5 + | +LL | let not_dead_code_but_unused = 5; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_not_dead_code_but_unused` + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:68:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. +---- $DIR/dead-code-items.rs - Enum::Variant1 (line 77) stdout ---- +error: unused variable: `unused_in_variant` + --> $DIR/dead-code-items.rs:80:17 + | +LL | fn main() { let unused_in_variant = 5; } + | ^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_in_variant` + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:75:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. +---- $DIR/dead-code-items.rs - MyTrait (line 103) stdout ---- +error: trait `StillDeadCodeAtMyTrait` is never used + --> $DIR/dead-code-items.rs:104:7 + | +LL | trait StillDeadCodeAtMyTrait { } + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:102:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to 1 previous error + +Couldn't compile the test. +---- $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) stdout ---- +error: unused variable: `unused_in_impl` + --> $DIR/dead-code-items.rs:113:17 + | +LL | fn main() { let unused_in_impl = 5; } + | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused_in_impl` + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:108:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. +---- $DIR/dead-code-items.rs - U::field (line 55) stdout ---- +error: trait `DeadCodeInUnionField` is never used + --> $DIR/dead-code-items.rs:56:7 + | +LL | trait DeadCodeInUnionField {} + | ^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/dead-code-items.rs:54:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/dead-code-items.rs - A::field (line 39) + $DIR/dead-code-items.rs - C (line 22) + $DIR/dead-code-items.rs - Enum (line 70) + $DIR/dead-code-items.rs - Enum::Variant1 (line 77) + $DIR/dead-code-items.rs - MyTrait (line 103) + $DIR/dead-code-items.rs - MyTrait::my_trait_fn (line 110) + $DIR/dead-code-items.rs - U::field (line 55) + +test result: FAILED. 6 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/dead-code-module-2.rs b/tests/rustdoc-ui/doctest/dead-code-module-2.rs new file mode 100644 index 00000000000..de7b11b91ec --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-module-2.rs @@ -0,0 +1,27 @@ +// Same test as dead-code-module but with 2 doc(test(attr())) at different levels. + +//@ edition: 2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +#![doc(test(attr(allow(unused_variables))))] + +mod my_mod { + #![doc(test(attr(deny(warnings))))] + + /// Example + /// + /// ```rust,no_run + /// trait T { fn f(); } + /// ``` + pub fn f() {} +} + +/// Example +/// +/// ```rust,no_run +/// trait OnlyWarning { fn no_deny_warnings(); } +/// ``` +pub fn g() {} diff --git a/tests/rustdoc-ui/doctest/dead-code-module-2.stdout b/tests/rustdoc-ui/doctest/dead-code-module-2.stdout new file mode 100644 index 00000000000..d44068dcbf5 --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-module-2.stdout @@ -0,0 +1,35 @@ + +running 1 test +test $DIR/dead-code-module-2.rs - g (line 24) - compile ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + + +running 1 test +test $DIR/dead-code-module-2.rs - my_mod::f (line 16) - compile ... FAILED + +failures: + +---- $DIR/dead-code-module-2.rs - my_mod::f (line 16) stdout ---- +error: trait `T` is never used + --> $DIR/dead-code-module-2.rs:17:7 + | +LL | trait T { fn f(); } + | ^ + | +note: the lint level is defined here + --> $DIR/dead-code-module-2.rs:15:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/dead-code-module-2.rs - my_mod::f (line 16) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/dead-code-module.rs b/tests/rustdoc-ui/doctest/dead-code-module.rs new file mode 100644 index 00000000000..f825749a6a2 --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-module.rs @@ -0,0 +1,18 @@ +// Same test as dead-code but inside a module. + +//@ edition: 2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +mod my_mod { + #![doc(test(attr(allow(unused_variables), deny(warnings))))] + + /// Example + /// + /// ```rust,no_run + /// trait T { fn f(); } + /// ``` + pub fn f() {} +} diff --git a/tests/rustdoc-ui/doctest/dead-code-module.stdout b/tests/rustdoc-ui/doctest/dead-code-module.stdout new file mode 100644 index 00000000000..b5ccf225d25 --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code-module.stdout @@ -0,0 +1,29 @@ + +running 1 test +test $DIR/dead-code-module.rs - my_mod::f (line 14) - compile ... FAILED + +failures: + +---- $DIR/dead-code-module.rs - my_mod::f (line 14) stdout ---- +error: trait `T` is never used + --> $DIR/dead-code-module.rs:15:7 + | +LL | trait T { fn f(); } + | ^ + | +note: the lint level is defined here + --> $DIR/dead-code-module.rs:13:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/dead-code-module.rs - my_mod::f (line 14) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/dead-code.rs b/tests/rustdoc-ui/doctest/dead-code.rs new file mode 100644 index 00000000000..1ea3e1d53ac --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code.rs @@ -0,0 +1,15 @@ +// This test ensures that the doctest will not use `#[allow(unused)]`. + +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +#![doc(test(attr(allow(unused_variables), deny(warnings))))] + +/// Example +/// +/// ```rust,no_run +/// trait T { fn f(); } +/// ``` +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/dead-code.stdout b/tests/rustdoc-ui/doctest/dead-code.stdout new file mode 100644 index 00000000000..38d15d5c1bc --- /dev/null +++ b/tests/rustdoc-ui/doctest/dead-code.stdout @@ -0,0 +1,29 @@ + +running 1 test +test $DIR/dead-code.rs - f (line 12) - compile ... FAILED + +failures: + +---- $DIR/dead-code.rs - f (line 12) stdout ---- +error: trait `T` is never used + --> $DIR/dead-code.rs:13:7 + | +LL | trait T { fn f(); } + | ^ + | +note: the lint level is defined here + --> $DIR/dead-code.rs:11:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/dead-code.rs - f (line 12) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/display-output.rs b/tests/rustdoc-ui/doctest/display-output.rs new file mode 100644 index 00000000000..d5de341b696 --- /dev/null +++ b/tests/rustdoc-ui/doctest/display-output.rs @@ -0,0 +1,15 @@ +// Test that `--show-output` has an effect and `allow(unused)` can be overridden. + +//@ check-pass +//@ edition:2018 +//@ compile-flags:--test --test-args=--show-output +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #![warn(unused)] +/// let x = 12; +/// +/// fn foo(x: &dyn std::fmt::Display) {} +/// ``` +pub fn foo() {} diff --git a/tests/rustdoc-ui/doctest/display-output.stdout b/tests/rustdoc-ui/doctest/display-output.stdout new file mode 100644 index 00000000000..45e107b2c70 --- /dev/null +++ b/tests/rustdoc-ui/doctest/display-output.stdout @@ -0,0 +1,43 @@ + +running 1 test +test $DIR/display-output.rs - foo (line 9) ... ok + +successes: + +---- $DIR/display-output.rs - foo (line 9) stdout ---- +warning: unused variable: `x` + --> $DIR/display-output.rs:12:5 + | +LL | let x = 12; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | +note: the lint level is defined here + --> $DIR/display-output.rs:9:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: unused variable: `x` + --> $DIR/display-output.rs:14:8 + | +LL | fn foo(x: &dyn std::fmt::Display) {} + | ^ help: if this is intentional, prefix it with an underscore: `_x` + +warning: function `foo` is never used + --> $DIR/display-output.rs:14:4 + | +LL | fn foo(x: &dyn std::fmt::Display) {} + | ^^^ + | + = note: `#[warn(dead_code)]` implied by `#[warn(unused)]` + +warning: 3 warnings emitted + + + +successes: + $DIR/display-output.rs - foo (line 9) + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs new file mode 100644 index 00000000000..135ecca7ffd --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs @@ -0,0 +1,11 @@ +// Regression test for #97440: Multiline inner attribute triggers ICE during doctest +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +//! ```rust +//! #![deny( +//! unused_parens, +//! )] +//! ``` diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.stdout b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.stdout new file mode 100644 index 00000000000..e47edbd2a81 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/doc-comment-multi-line-attr.rs - (line 7) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs new file mode 100644 index 00000000000..16adb3c6c54 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs @@ -0,0 +1,12 @@ +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +/// ``` +/// # #![cfg_attr(not(dox), deny(missing_abi, +/// # non_ascii_idents))] +/// +/// pub struct Bar; +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.stdout b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.stdout new file mode 100644 index 00000000000..bf3521e4f91 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/doc-comment-multi-line-cfg-attr.rs - Bar (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs b/tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs new file mode 100644 index 00000000000..e916ca41ea0 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-attr-pass-module.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![crate_type = "lib"] +#![deny(invalid_doc_attributes)] +#![doc(test(no_crate_inject))] + +mod my_mod { + #![doc(test(attr(deny(warnings))))] + + pub fn foo() {} +} diff --git a/tests/rustdoc-ui/doctest/doc-test-attr-pass.rs b/tests/rustdoc-ui/doctest/doc-test-attr-pass.rs new file mode 100644 index 00000000000..edbfde90bce --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-attr-pass.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![crate_type = "lib"] +#![deny(invalid_doc_attributes)] +#![doc(test(no_crate_inject))] +#![doc(test(attr(deny(warnings))))] + +pub fn foo() {} diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.rs b/tests/rustdoc-ui/doctest/doc-test-attr.rs new file mode 100644 index 00000000000..8570252c449 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-attr.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +#![doc(test)] +//~^ ERROR `#[doc(test(...)]` takes a list of attributes +#![doc(test = "hello")] +//~^ ERROR `#[doc(test(...)]` takes a list of attributes +#![doc(test(a))] +//~^ ERROR unknown `doc(test)` attribute `a` + +pub fn foo() {} diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.stderr b/tests/rustdoc-ui/doctest/doc-test-attr.stderr new file mode 100644 index 00000000000..415251cc5e9 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-attr.stderr @@ -0,0 +1,22 @@ +error: `#[doc(test(...)]` takes a list of attributes + --> $DIR/doc-test-attr.rs:3:8 + | +LL | #![doc(test)] + | ^^^^ + | + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: `#[doc(test(...)]` takes a list of attributes + --> $DIR/doc-test-attr.rs:5:8 + | +LL | #![doc(test = "hello")] + | ^^^^^^^^^^^^^^ + +error: unknown `doc(test)` attribute `a` + --> $DIR/doc-test-attr.rs:7:13 + | +LL | #![doc(test(a))] + | ^ + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs new file mode 100644 index 00000000000..9c2d200329a --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs @@ -0,0 +1,13 @@ +//@ check-pass +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// Make sure `cfg(doctest)` is set when finding doctests but not inside +// the doctests. + +/// ``` +/// assert!(!cfg!(doctest)); +/// ``` +#[cfg(doctest)] +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.stdout b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.stdout new file mode 100644 index 00000000000..d7de1f10522 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/doc-test-doctest-feature.rs - Foo (line 9) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs new file mode 100644 index 00000000000..dd04adfe617 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs @@ -0,0 +1,15 @@ +//@ check-pass +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +#![feature(doc_cfg)] + +// Make sure `cfg(doc)` is set when finding doctests but not inside the doctests. + +/// ``` +/// #![feature(doc_cfg)] +/// assert!(!cfg!(doc)); +/// ``` +#[cfg(doc)] +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.stdout b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.stdout new file mode 100644 index 00000000000..5b07fc4c87a --- /dev/null +++ b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/doc-test-rustdoc-feature.rs - Foo (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doctest-edition.rs b/tests/rustdoc-ui/doctest/doctest-edition.rs new file mode 100644 index 00000000000..008c84f7162 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-edition.rs @@ -0,0 +1,16 @@ +//@ edition:2021 + +#![deny(rustdoc::invalid_rust_codeblocks)] +//~^ NOTE lint level is defined here + +// By default, rustdoc should use the edition of the crate. +//! ``` +//! foo'b' +//! ``` +//~^^^ ERROR could not parse +//~| NOTE prefix `foo` is unknown + +// Rustdoc should respect `edition2018` when highlighting syntax. +//! ```edition2018 +//! foo'b' +//! ``` diff --git a/tests/rustdoc-ui/doctest/doctest-edition.stderr b/tests/rustdoc-ui/doctest/doctest-edition.stderr new file mode 100644 index 00000000000..1e9ebd88c2e --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-edition.stderr @@ -0,0 +1,22 @@ +error: could not parse code block as Rust code + --> $DIR/doctest-edition.rs:7:5 + | +LL | //! ``` + | _____^ +LL | | //! foo'b' +LL | | //! ``` + | |_______^ + | + = note: error from rustc: prefix `foo` is unknown +note: the lint level is defined here + --> $DIR/doctest-edition.rs:3:9 + | +LL | #![deny(rustdoc::invalid_rust_codeblocks)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: mark blocks that do not contain Rust code as text + | +LL | //! ```text + | ++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs new file mode 100644 index 00000000000..1f80e002ef5 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs @@ -0,0 +1,10 @@ +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +/// ``` +/// #![deprecated(since = "5.2", note = "foo was rarely used. \ +/// Users should instead use bar")] +/// ``` +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.stdout b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.stdout new file mode 100644 index 00000000000..07a4f657dea --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/doctest-multiline-crate-attribute.rs - f (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs new file mode 100644 index 00000000000..db2ccefb0fb --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs @@ -0,0 +1,13 @@ +//@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass +#![allow(rustdoc::invalid_codeblock_attributes)] + +// https://github.com/rust-lang/rust/pull/124577#issuecomment-2276034737 + +// Test that invalid langstrings don't get run. + +/// ```{rust,ignore} +/// panic!(); +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout new file mode 100644 index 00000000000..7326c0a25a0 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.md b/tests/rustdoc-ui/doctest/doctest-output-include-fail.md new file mode 100644 index 00000000000..a8e61238f31 --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.md @@ -0,0 +1,7 @@ +With a code sample, that has an error: + +```rust +fn main() { + let x = 234 // no semicolon here! oh no! +} +``` diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs new file mode 100644 index 00000000000..a47bac3daef --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs @@ -0,0 +1,8 @@ +//@ edition:2024 +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +// https://github.com/rust-lang/rust/issues/130470 +#![doc = include_str!("doctest-output-include-fail.md")] diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout b/tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout new file mode 100644 index 00000000000..22d15f8743c --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout @@ -0,0 +1,24 @@ + +running 1 test +test $DIR/doctest-output-include-fail.md - (line 3) ... FAILED + +failures: + +---- $DIR/doctest-output-include-fail.md - (line 3) stdout ---- +error: expected `;`, found `}` + --> $DIR/doctest-output-include-fail.md:5:16 + | +LL | let x = 234 // no semicolon here! oh no! + | ^ help: add `;` here +LL | } + | - unexpected token + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/doctest-output-include-fail.md - (line 3) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout new file mode 100644 index 00000000000..0e2e30390ad --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout @@ -0,0 +1,8 @@ + +running 3 tests +test $DIR/doctest-output.rs - (line 12) ... ok +test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok +test $DIR/doctest-output.rs - foo::bar (line 22) ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout new file mode 100644 index 00000000000..0e2e30390ad --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout @@ -0,0 +1,8 @@ + +running 3 tests +test $DIR/doctest-output.rs - (line 12) ... ok +test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok +test $DIR/doctest-output.rs - foo::bar (line 22) ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs new file mode 100644 index 00000000000..04bd1813b4c --- /dev/null +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -0,0 +1,32 @@ +//@ revisions: edition2015 edition2024 +//@[edition2015]edition:2015 +//@[edition2015]aux-build:extern_macros.rs +//@[edition2015]compile-flags:--test --test-args=--test-threads=1 +//@[edition2024]edition:2024 +//@[edition2024]aux-build:extern_macros.rs +//@[edition2024]compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +//! ``` +//! assert_eq!(1 + 1, 2); +//! ``` + +extern crate extern_macros as macros; + +use macros::attrs_on_struct; + +pub mod foo { + + /// ``` + /// assert_eq!(1 + 1, 2); + /// ``` + pub fn bar() {} +} + +attrs_on_struct! { + /// ``` + /// assert!(true); + /// ``` +} diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.rs b/tests/rustdoc-ui/doctest/edition-2024-error-output.rs new file mode 100644 index 00000000000..82a85debcd1 --- /dev/null +++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.rs @@ -0,0 +1,14 @@ +// This is a regression test for <https://github.com/rust-lang/rust/issues/137970>. +// The output must look nice and not like a `Debug` display of a `String`. + +//@ edition: 2024 +//@ compile-flags: --test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "panicked at .+rs:" -> "panicked at $$TMP:" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ rustc-env:RUST_BACKTRACE=0 +//@ failure-status: 101 + +//! ```rust +//! assert_eq!(2 + 2, 5); +//! ``` diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout new file mode 100644 index 00000000000..273d7071237 --- /dev/null +++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout @@ -0,0 +1,24 @@ + +running 1 test +test $DIR/edition-2024-error-output.rs - (line 12) ... FAILED + +failures: + +---- $DIR/edition-2024-error-output.rs - (line 12) stdout ---- +Test executable failed (exit status: 101). + +stderr: + +thread 'main' panicked at $TMP:6:1: +assertion `left == right` failed + left: 4 + right: 5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + + +failures: + $DIR/edition-2024-error-output.rs - (line 12) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/extern-crate.rs b/tests/rustdoc-ui/doctest/extern-crate.rs new file mode 100644 index 00000000000..0415d33bb72 --- /dev/null +++ b/tests/rustdoc-ui/doctest/extern-crate.rs @@ -0,0 +1,23 @@ +//@ check-pass +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// This test ensures that crate imports are placed outside of the `main` function +// so they work all the time (even in 2015 edition). + +/// ```rust +/// #![feature(test)] +/// +/// extern crate test; +/// use test::Bencher; +/// +/// #[bench] +/// fn bench_xor_1000_ints(b: &mut Bencher) { +/// b.iter(|| { +/// (0..1000).fold(0, |old, new| old ^ new); +/// }); +/// } +/// ``` +/// +pub fn foo() {} diff --git a/tests/rustdoc-ui/doctest/extern-crate.stdout b/tests/rustdoc-ui/doctest/extern-crate.stdout new file mode 100644 index 00000000000..b103343afdd --- /dev/null +++ b/tests/rustdoc-ui/doctest/extern-crate.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/extern-crate.rs - foo (line 9) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs new file mode 100644 index 00000000000..6f7b2672b56 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs @@ -0,0 +1,12 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// ```compile_fail +/// println!("Hello"); +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.stdout b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.stdout new file mode 100644 index 00000000000..af3a90a7410 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.stdout @@ -0,0 +1,14 @@ + +running 1 test +test $DIR/failed-doctest-compile-fail.rs - Foo (line 9) - compile fail ... FAILED + +failures: + +---- $DIR/failed-doctest-compile-fail.rs - Foo (line 9) stdout ---- +Test compiled successfully, but it's marked `compile_fail`. + +failures: + $DIR/failed-doctest-compile-fail.rs - Foo (line 9) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs new file mode 100644 index 00000000000..ca5dd787467 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs @@ -0,0 +1,18 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +/// <https://github.com/rust-lang/rust/issues/91014> +/// +/// ```rust +/// struct S {}; +/// +/// fn main() { +/// assert_eq!(0, 1); +/// } +/// ``` +mod m {} diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr new file mode 100644 index 00000000000..113fb7ccb60 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr @@ -0,0 +1,8 @@ +warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function + --> $DIR/failed-doctest-extra-semicolon-on-item.rs:11:1 + | +11 | /// ```rust + | ^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout new file mode 100644 index 00000000000..1068b98cb0f --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs new file mode 100644 index 00000000000..ded674bf18a --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs @@ -0,0 +1,12 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// ```compile_fail,E0004 +/// let x: () = 5i32; +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.stdout b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.stdout new file mode 100644 index 00000000000..11355c232fe --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.stdout @@ -0,0 +1,25 @@ + +running 1 test +test $DIR/failed-doctest-missing-codes.rs - Foo (line 9) - compile fail ... FAILED + +failures: + +---- $DIR/failed-doctest-missing-codes.rs - Foo (line 9) stdout ---- +error[E0308]: mismatched types + --> $DIR/failed-doctest-missing-codes.rs:10:13 + | +LL | let x: () = 5i32; + | -- ^^^^ expected `()`, found `i32` + | | + | expected due to this + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. +Some expected error codes were not found: ["E0004"] + +failures: + $DIR/failed-doctest-missing-codes.rs - Foo (line 9) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs new file mode 100644 index 00000000000..3a08faf626f --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs @@ -0,0 +1,28 @@ +//@ only-windows +// There's a parallel generic version of this test for non-windows platforms. + +// Issue #51162: A failed doctest was not printing its stdout/stderr +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +// doctest fails at runtime +/// ``` +/// println!("stdout 1"); +/// eprintln!("stderr 1"); +/// println!("stdout 2"); +/// eprintln!("stderr 2"); +/// panic!("oh no"); +/// ``` +pub struct SomeStruct; + +// doctest fails at compile time +/// ``` +/// no +/// ``` +pub struct OtherStruct; diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout new file mode 100644 index 00000000000..7aa965d543b --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout @@ -0,0 +1,41 @@ + +running 2 tests +test $DIR/failed-doctest-output-windows.rs - OtherStruct (line 25) ... FAILED +test $DIR/failed-doctest-output-windows.rs - SomeStruct (line 15) ... FAILED + +failures: + +---- $DIR/failed-doctest-output-windows.rs - OtherStruct (line 25) stdout ---- +error[E0425]: cannot find value `no` in this scope + --> $DIR/failed-doctest-output-windows.rs:26:1 + | +LL | no + | ^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. +Couldn't compile the test. +---- $DIR/failed-doctest-output-windows.rs - SomeStruct (line 15) stdout ---- +Test executable failed (exit code: 101). + +stdout: +stdout 1 +stdout 2 + +stderr: +stderr 1 +stderr 2 + +thread 'main' panicked at $DIR/failed-doctest-output-windows.rs:7:1: +oh no +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + + +failures: + $DIR/failed-doctest-output-windows.rs - OtherStruct (line 25) + $DIR/failed-doctest-output-windows.rs - SomeStruct (line 15) + +test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.rs b/tests/rustdoc-ui/doctest/failed-doctest-output.rs new file mode 100644 index 00000000000..84c72268881 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.rs @@ -0,0 +1,28 @@ +//@ ignore-windows +// There's a parallel version of this test for Windows. + +// Issue #51162: A failed doctest was not printing its stdout/stderr +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +// doctest fails at runtime +/// ``` +/// println!("stdout 1"); +/// eprintln!("stderr 1"); +/// println!("stdout 2"); +/// eprintln!("stderr 2"); +/// panic!("oh no"); +/// ``` +pub struct SomeStruct; + +// doctest fails at compile time +/// ``` +/// no +/// ``` +pub struct OtherStruct; diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout new file mode 100644 index 00000000000..a333f341ce5 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout @@ -0,0 +1,41 @@ + +running 2 tests +test $DIR/failed-doctest-output.rs - OtherStruct (line 25) ... FAILED +test $DIR/failed-doctest-output.rs - SomeStruct (line 15) ... FAILED + +failures: + +---- $DIR/failed-doctest-output.rs - OtherStruct (line 25) stdout ---- +error[E0425]: cannot find value `no` in this scope + --> $DIR/failed-doctest-output.rs:26:1 + | +LL | no + | ^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. +Couldn't compile the test. +---- $DIR/failed-doctest-output.rs - SomeStruct (line 15) stdout ---- +Test executable failed (exit status: 101). + +stdout: +stdout 1 +stdout 2 + +stderr: +stderr 1 +stderr 2 + +thread 'main' panicked at $DIR/failed-doctest-output.rs:7:1: +oh no +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + + +failures: + $DIR/failed-doctest-output.rs - OtherStruct (line 25) + $DIR/failed-doctest-output.rs - SomeStruct (line 15) + +test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs new file mode 100644 index 00000000000..1ed67694a90 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs @@ -0,0 +1,13 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags: --test +//@ edition: 2021 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// ```should_panic +/// println!("Hello, world!"); +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout new file mode 100644 index 00000000000..9f4d60e6f4d --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.stdout @@ -0,0 +1,14 @@ + +running 1 test +test $DIR/failed-doctest-should-panic-2021.rs - Foo (line 10) ... FAILED + +failures: + +---- $DIR/failed-doctest-should-panic-2021.rs - Foo (line 10) stdout ---- +Test executable succeeded, but it's marked `should_panic`. + +failures: + $DIR/failed-doctest-should-panic-2021.rs - Foo (line 10) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs new file mode 100644 index 00000000000..793f8654661 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs @@ -0,0 +1,13 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ edition: 2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// ```should_panic +/// println!("Hello, world!"); +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout new file mode 100644 index 00000000000..2b04b77c9dc --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.stdout @@ -0,0 +1,14 @@ + +running 1 test +test $DIR/failed-doctest-should-panic.rs - Foo (line 10) - should panic ... FAILED + +failures: + +---- $DIR/failed-doctest-should-panic.rs - Foo (line 10) stdout ---- +note: test did not panic as expected at $DIR/failed-doctest-should-panic.rs:10:0 + +failures: + $DIR/failed-doctest-should-panic.rs - Foo (line 10) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout new file mode 100644 index 00000000000..ce767fb8443 --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout @@ -0,0 +1,28 @@ + +running 1 test +test $DIR/failed-doctest-test-crate.rs - m (line 14) ... FAILED + +failures: + +---- $DIR/failed-doctest-test-crate.rs - m (line 14) stdout ---- +error[E0432]: unresolved import `test` + --> $DIR/failed-doctest-test-crate.rs:15:5 + | +LL | use test::*; + | ^^^^ use of unresolved module or unlinked crate `test` + | +help: you might be missing a crate named `test`, add it to your project and import it in your code + | +LL + extern crate test; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. +Couldn't compile the test. + +failures: + $DIR/failed-doctest-test-crate.rs - m (line 14) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout new file mode 100644 index 00000000000..80642e93bbd --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout @@ -0,0 +1,25 @@ + +running 1 test +test $DIR/failed-doctest-test-crate.rs - m (line 14) ... FAILED + +failures: + +---- $DIR/failed-doctest-test-crate.rs - m (line 14) stdout ---- +error[E0432]: unresolved import `test` + --> $DIR/failed-doctest-test-crate.rs:15:5 + | +LL | use test::*; + | ^^^^ use of unresolved module or unlinked crate `test` + | + = help: you might be missing a crate named `test` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. +Couldn't compile the test. + +failures: + $DIR/failed-doctest-test-crate.rs - m (line 14) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs new file mode 100644 index 00000000000..6966d3df11c --- /dev/null +++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs @@ -0,0 +1,17 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ revisions: edition2015 edition2024 +//@[edition2015]edition:2015 +//@[edition2024]edition:2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// <https://github.com/rust-lang/rust/pull/137899#discussion_r1976743383> +/// +/// ```rust +/// use test::*; +/// ``` +pub mod m {} diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout new file mode 100644 index 00000000000..65989a8ef47 --- /dev/null +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout @@ -0,0 +1,60 @@ + +running 4 tests +test $DIR/main-alongside-macro-calls.rs - (line 19) ... ok +test $DIR/main-alongside-macro-calls.rs - (line 24) ... ok +test $DIR/main-alongside-macro-calls.rs - (line 28) ... FAILED +test $DIR/main-alongside-macro-calls.rs - (line 33) ... FAILED + +failures: + +---- $DIR/main-alongside-macro-calls.rs - (line 28) stdout ---- +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/main-alongside-macro-calls.rs:30:1 + | +LL | println!(); + | ^^^^^^^^^^ + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: macro expansion ignores `{` and any tokens following + --> $SRC_DIR/std/src/macros.rs:LL:COL + | + ::: $DIR/main-alongside-macro-calls.rs:30:1 + | +LL | println!(); + | ---------- caused by the macro expansion here + | + = note: the usage of `print!` is likely invalid in item context + +error: aborting due to 2 previous errors + +Couldn't compile the test. +---- $DIR/main-alongside-macro-calls.rs - (line 33) stdout ---- +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/main-alongside-macro-calls.rs:34:1 + | +LL | println!(); + | ^^^^^^^^^^ + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: macro expansion ignores `{` and any tokens following + --> $SRC_DIR/std/src/macros.rs:LL:COL + | + ::: $DIR/main-alongside-macro-calls.rs:34:1 + | +LL | println!(); + | ---------- caused by the macro expansion here + | + = note: the usage of `print!` is likely invalid in item context + +error: aborting due to 2 previous errors + +Couldn't compile the test. + +failures: + $DIR/main-alongside-macro-calls.rs - (line 28) + $DIR/main-alongside-macro-calls.rs - (line 33) + +test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.pass.stdout b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.pass.stdout new file mode 100644 index 00000000000..93a4bbd8736 --- /dev/null +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.pass.stdout @@ -0,0 +1,9 @@ + +running 4 tests +test $DIR/main-alongside-macro-calls.rs - (line 19) ... ok +test $DIR/main-alongside-macro-calls.rs - (line 24) ... ok +test $DIR/main-alongside-macro-calls.rs - (line 28) - compile fail ... ok +test $DIR/main-alongside-macro-calls.rs - (line 33) - compile fail ... ok + +test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.rs b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.rs new file mode 100644 index 00000000000..b455d8b0cc3 --- /dev/null +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.rs @@ -0,0 +1,44 @@ +// This test ensures that if there is are any macro calls alongside a `main` function, +// it will indeed consider the `main` function as the program entry point and *won't* +// generate its own `main` function to wrap everything even though macro calls are +// valid in statement contexts, too, and could just as well expand to statements or +// expressions (we don't perform any macro expansion to find `main`, see also +// <https://github.com/rust-lang/rust/issues/57415>). +// +// See <./main-alongside-stmts.rs> for comparison. +// +//@ compile-flags:--test --test-args --test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ revisions: pass fail +//@[pass] check-pass +//@[fail] failure-status: 101 + +// Regression test for <https://github.com/rust-lang/rust/pull/140220#issuecomment-2831872920>: + +//! ``` +//! fn main() {} +//! include!("./auxiliary/items.rs"); +//! ``` +//! +//! ``` +//! include!("./auxiliary/items.rs"); +//! fn main() {} +//! ``` + +// Regression test for <https://github.com/rust-lang/rust/issues/140412>: +// We test the "same" thing twice: Once via `compile_fail` to more closely mirror the reported +// regression and once without it to make sure that it leads to the expected rustc errors, +// namely `println!(…)` not being valid in item contexts. + +#![cfg_attr(pass, doc = " ```compile_fail")] +#![cfg_attr(fail, doc = " ```")] +//! fn main() {} +//! println!(); +//! ``` +//! +#![cfg_attr(pass, doc = " ```compile_fail")] +#![cfg_attr(fail, doc = " ```")] +//! println!(); +//! fn main() {} +//! ``` diff --git a/tests/rustdoc-ui/doctest/main-alongside-stmts.rs b/tests/rustdoc-ui/doctest/main-alongside-stmts.rs new file mode 100644 index 00000000000..5965f928cdd --- /dev/null +++ b/tests/rustdoc-ui/doctest/main-alongside-stmts.rs @@ -0,0 +1,33 @@ +// This test ensures that if there is are any statements alongside a `main` function, +// it will not consider the `main` function as the program entry point but instead +// will generate its own `main` function to wrap everything as it needs to reside in a +// module where only *items* are permitted syntactically. +// +// See <./main-alongside-macro-calls.rs> for comparison. +// +// This is a regression test for: +// * <https://github.com/rust-lang/rust/issues/140162> +// * <https://github.com/rust-lang/rust/issues/139651> +// +//@ compile-flags:--test --test-args --test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +//! ``` +//! # if cfg!(miri) { return; } +//! use std::ops::Deref; +//! +//! fn main() { +//! assert!(false); +//! } +//! ``` +//! +//! ``` +//! let x = 2; +//! assert_eq!(x, 2); +//! +//! fn main() { +//! assert!(false); +//! } +//! ``` diff --git a/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr b/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr new file mode 100644 index 00000000000..d90a289ca69 --- /dev/null +++ b/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr @@ -0,0 +1,14 @@ +warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function + --> $DIR/main-alongside-stmts.rs:17:1 + | +17 | //! ``` + | ^^^^^^^ + +warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function + --> $DIR/main-alongside-stmts.rs:26:1 + | +26 | //! ``` + | ^^^^^^^ + +warning: 2 warnings emitted + diff --git a/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout b/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout new file mode 100644 index 00000000000..9b9a3fe8a68 --- /dev/null +++ b/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/main-alongside-stmts.rs - (line 17) ... ok +test $DIR/main-alongside-stmts.rs - (line 26) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs new file mode 100644 index 00000000000..7dac64e6de4 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs @@ -0,0 +1,15 @@ +//@ edition: 2024 +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +/// ```ignore (test) +/// let x = 12; +/// ``` +pub fn ignored() {} + +/// ```no_run +/// panic!("blob"); +/// ``` +pub fn no_run() {} diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout new file mode 100644 index 00000000000..a32da0aeb96 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/merged-ignore-no_run.rs - ignored (line 7) ... ignored +test $DIR/merged-ignore-no_run.rs - no_run (line 12) - compile ... ok + +test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/nested-main.rs b/tests/rustdoc-ui/doctest/nested-main.rs new file mode 100644 index 00000000000..d1b3bd6da40 --- /dev/null +++ b/tests/rustdoc-ui/doctest/nested-main.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// Regression test for <https://github.com/rust-lang/rust/issues/131893>. +// It ensures that if a function called `main` is nested, it will not consider +// it as the `main` function. + +/// ``` +/// fn dox() { +/// fn main() {} +/// } +/// ``` +pub fn foo() {} + +// This one ensures that having a nested `main` doesn't prevent the +// actual `main` function to be detected. +/// ``` +/// fn main() { +/// fn main() {} +/// } +/// ``` +pub fn foo2() {} diff --git a/tests/rustdoc-ui/doctest/nested-main.stdout b/tests/rustdoc-ui/doctest/nested-main.stdout new file mode 100644 index 00000000000..af9a8f5e1d7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/nested-main.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/nested-main.rs - foo (line 10) ... ok +test $DIR/nested-main.rs - foo2 (line 19) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/no-run-flag-error.rs b/tests/rustdoc-ui/doctest/no-run-flag-error.rs new file mode 100644 index 00000000000..3f9016b23db --- /dev/null +++ b/tests/rustdoc-ui/doctest/no-run-flag-error.rs @@ -0,0 +1,7 @@ +// test the behavior of the --no-run flag without the --test flag + +//@ compile-flags:-Z unstable-options --no-run --test-args=--test-threads=1 + +pub fn f() {} + +//~? ERROR the `--test` flag must be passed to enable `--no-run` diff --git a/tests/rustdoc-ui/doctest/no-run-flag-error.stderr b/tests/rustdoc-ui/doctest/no-run-flag-error.stderr new file mode 100644 index 00000000000..d032646c365 --- /dev/null +++ b/tests/rustdoc-ui/doctest/no-run-flag-error.stderr @@ -0,0 +1,2 @@ +error: the `--test` flag must be passed to enable `--no-run` + diff --git a/tests/rustdoc-ui/doctest/no-run-flag.rs b/tests/rustdoc-ui/doctest/no-run-flag.rs new file mode 100644 index 00000000000..8f1381e0760 --- /dev/null +++ b/tests/rustdoc-ui/doctest/no-run-flag.rs @@ -0,0 +1,38 @@ +// test the behavior of the --no-run flag + +//@ check-pass +//@ compile-flags:-Z unstable-options --test --no-run --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// let a = true; +/// ``` +/// ```should_panic +/// panic!() +/// ``` +/// ```ignore (incomplete-code) +/// fn foo() { +/// ``` +/// ```no_run +/// loop { +/// println!("Hello, world"); +/// } +/// ``` +/// fails to compile +/// ```compile_fail +/// let x = 5; +/// x += 2; // shouldn't compile! +/// ``` +/// Ok the test does not run +/// ``` +/// panic!() +/// ``` +/// Ok the test does not run +/// ```should_panic +/// loop { +/// println!("Hello, world"); +/// panic!() +/// } +/// ``` +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/no-run-flag.stdout b/tests/rustdoc-ui/doctest/no-run-flag.stdout new file mode 100644 index 00000000000..02f28aaf60d --- /dev/null +++ b/tests/rustdoc-ui/doctest/no-run-flag.stdout @@ -0,0 +1,12 @@ + +running 7 tests +test $DIR/no-run-flag.rs - f (line 11) - compile ... ok +test $DIR/no-run-flag.rs - f (line 14) ... ignored +test $DIR/no-run-flag.rs - f (line 17) - compile ... ok +test $DIR/no-run-flag.rs - f (line 23) - compile fail ... ok +test $DIR/no-run-flag.rs - f (line 28) - compile ... ok +test $DIR/no-run-flag.rs - f (line 32) - compile ... ok +test $DIR/no-run-flag.rs - f (line 8) - compile ... ok + +test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/nocapture-fail.rs b/tests/rustdoc-ui/doctest/nocapture-fail.rs new file mode 100644 index 00000000000..8c64a49f650 --- /dev/null +++ b/tests/rustdoc-ui/doctest/nocapture-fail.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags:--test -Zunstable-options --nocapture +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ```compile_fail +/// fn foo() { +/// Input: 123 +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/nocapture-fail.stderr b/tests/rustdoc-ui/doctest/nocapture-fail.stderr new file mode 100644 index 00000000000..c6a5785a24f --- /dev/null +++ b/tests/rustdoc-ui/doctest/nocapture-fail.stderr @@ -0,0 +1,18 @@ +error: struct literal body without path + --> $DIR/nocapture-fail.rs:8:10 + | +LL | fn foo() { + | __________^ +LL | | Input: 123 +LL | | } + | |_^ + | +help: you might have forgotten to add the struct literal inside the block + | +LL ~ fn foo() { SomeStruct { +LL | Input: 123 +LL ~ } } + | + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doctest/nocapture-fail.stdout b/tests/rustdoc-ui/doctest/nocapture-fail.stdout new file mode 100644 index 00000000000..754f77db53c --- /dev/null +++ b/tests/rustdoc-ui/doctest/nocapture-fail.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/nocapture-fail.rs - Foo (line 7) - compile fail ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/nocapture.rs b/tests/rustdoc-ui/doctest/nocapture.rs new file mode 100644 index 00000000000..c4360341864 --- /dev/null +++ b/tests/rustdoc-ui/doctest/nocapture.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ compile-flags:--test -Zunstable-options --nocapture +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// println!("hello!"); +/// eprintln!("stderr"); +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/nocapture.stderr b/tests/rustdoc-ui/doctest/nocapture.stderr new file mode 100644 index 00000000000..af6415db3c7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/nocapture.stderr @@ -0,0 +1 @@ +stderr diff --git a/tests/rustdoc-ui/doctest/nocapture.stdout b/tests/rustdoc-ui/doctest/nocapture.stdout new file mode 100644 index 00000000000..4880e75da70 --- /dev/null +++ b/tests/rustdoc-ui/doctest/nocapture.stdout @@ -0,0 +1,7 @@ + +running 1 test +hello! +test $DIR/nocapture.rs - Foo (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs new file mode 100644 index 00000000000..f2540574f15 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs @@ -0,0 +1,34 @@ +//@ check-fail +//@ edition:2018 +//@ failure-status: 101 +//@ aux-build:pub_trait.rs +//@ compile-flags: --test --test-args --test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +#![doc(test(attr(deny(non_local_definitions))))] +#![doc(test(attr(allow(dead_code))))] + +/// This will produce a warning: +/// ```rust,no_run +/// # extern crate pub_trait; +/// # use pub_trait::Trait; +/// +/// struct Local; +/// +/// fn foo() { +/// impl Trait for &Local {} +/// } +/// ``` +/// +/// But this shouldn't produce a warning: +/// ```rust,no_run +/// # extern crate pub_trait; +/// # use pub_trait::Trait; +/// +/// struct Local; +/// impl Trait for &Local {} +/// +/// # fn main() {} +/// ``` +pub fn doctest() {} diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.stdout b/tests/rustdoc-ui/doctest/non-local-defs-impl.stdout new file mode 100644 index 00000000000..c1f750017e7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.stdout @@ -0,0 +1,35 @@ + +running 2 tests +test $DIR/non-local-defs-impl.rs - doctest (line 13) - compile ... FAILED +test $DIR/non-local-defs-impl.rs - doctest (line 25) - compile ... ok + +failures: + +---- $DIR/non-local-defs-impl.rs - doctest (line 13) stdout ---- +error: non-local `impl` definition, `impl` blocks should be written at the same level as their item + --> $DIR/non-local-defs-impl.rs:20:5 + | +LL | fn foo() { + | -------- move the `impl` block outside of this function `foo` and up 3 bodies +LL | impl Trait for &Local {} + | ^^^^^-----^^^^^^----- + | | | + | | `Local` is not local + | `Trait` is not local + | + = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` +note: the lint level is defined here + --> $DIR/non-local-defs-impl.rs:11:9 + | +LL | #![deny(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/non-local-defs-impl.rs - doctest (line 13) + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs new file mode 100644 index 00000000000..ce65ad2cf72 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +//! ``` +//! #[macro_export] +//! macro_rules! a_macro { () => {} } +//! ``` diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr new file mode 100644 index 00000000000..e39dc4d5ee0 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr @@ -0,0 +1,12 @@ +warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module + --> $DIR/non_local_defs.rs:9:1 + | +LL | macro_rules! a_macro { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }` + = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute + = note: `#[warn(non_local_definitions)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stdout b/tests/rustdoc-ui/doctest/non_local_defs.stdout new file mode 100644 index 00000000000..bee195fcdd7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/non_local_defs.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/non_local_defs.rs - (line 7) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/per-target-ignores.rs b/tests/rustdoc-ui/doctest/per-target-ignores.rs new file mode 100644 index 00000000000..3dea7099b4b --- /dev/null +++ b/tests/rustdoc-ui/doctest/per-target-ignores.rs @@ -0,0 +1,14 @@ +//@ only-aarch64 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +///```ignore-x86_64 +/// assert!(cfg!(not(target_arch = "x86_64"))); +///``` +pub fn foo() -> u8 { + 4 +} + +fn main() {} diff --git a/tests/rustdoc-ui/doctest/per-target-ignores.stdout b/tests/rustdoc-ui/doctest/per-target-ignores.stdout new file mode 100644 index 00000000000..fe7282144dd --- /dev/null +++ b/tests/rustdoc-ui/doctest/per-target-ignores.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/per-target-ignores.rs - foo (line 7) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/private-doc-test.rs b/tests/rustdoc-ui/doctest/private-doc-test.rs new file mode 100644 index 00000000000..911cbdbb89d --- /dev/null +++ b/tests/rustdoc-ui/doctest/private-doc-test.rs @@ -0,0 +1,12 @@ +//@ check-pass + +#![deny(rustdoc::private_doc_tests)] + +mod foo { + /// private doc test + /// + /// ```ignore (used for testing ignored doc tests) + /// assert!(false); + /// ``` + fn bar() {} +} diff --git a/tests/rustdoc-ui/doctest/private-item-doc-test.rs b/tests/rustdoc-ui/doctest/private-item-doc-test.rs new file mode 100644 index 00000000000..1a3d6cc636d --- /dev/null +++ b/tests/rustdoc-ui/doctest/private-item-doc-test.rs @@ -0,0 +1,11 @@ +#![deny(rustdoc::private_doc_tests)] + +mod foo { + /// private doc test + /// + /// ``` + /// assert!(false); + /// ``` + //~^^^^^ ERROR documentation test in private item + fn bar() {} +} diff --git a/tests/rustdoc-ui/doctest/private-item-doc-test.stderr b/tests/rustdoc-ui/doctest/private-item-doc-test.stderr new file mode 100644 index 00000000000..5177057c728 --- /dev/null +++ b/tests/rustdoc-ui/doctest/private-item-doc-test.stderr @@ -0,0 +1,18 @@ +error: documentation test in private item + --> $DIR/private-item-doc-test.rs:4:5 + | +LL | / /// private doc test +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); +LL | | /// ``` + | |___________^ + | +note: the lint level is defined here + --> $DIR/private-item-doc-test.rs:1:9 + | +LL | #![deny(rustdoc::private_doc_tests)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doctest/private-public-item-doc-test.rs b/tests/rustdoc-ui/doctest/private-public-item-doc-test.rs new file mode 100644 index 00000000000..7cc62b38cc2 --- /dev/null +++ b/tests/rustdoc-ui/doctest/private-public-item-doc-test.rs @@ -0,0 +1,11 @@ +#![deny(rustdoc::private_doc_tests)] + +mod foo { + /// private doc test + /// + /// ``` + /// assert!(false); + /// ``` + //~^^^^^ ERROR documentation test in private item + pub fn bar() {} +} diff --git a/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr b/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr new file mode 100644 index 00000000000..38b8dd652d3 --- /dev/null +++ b/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr @@ -0,0 +1,18 @@ +error: documentation test in private item + --> $DIR/private-public-item-doc-test.rs:4:5 + | +LL | / /// private doc test +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); +LL | | /// ``` + | |___________^ + | +note: the lint level is defined here + --> $DIR/private-public-item-doc-test.rs:1:9 + | +LL | #![deny(rustdoc::private_doc_tests)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doctest/public-reexported-item-doc-test.rs b/tests/rustdoc-ui/doctest/public-reexported-item-doc-test.rs new file mode 100644 index 00000000000..e786c03470b --- /dev/null +++ b/tests/rustdoc-ui/doctest/public-reexported-item-doc-test.rs @@ -0,0 +1,16 @@ +//@ check-pass + +#![deny(rustdoc::private_doc_tests)] + +pub fn foo() {} + +mod private { + /// re-exported doc test + /// + /// ``` + /// assert!(true); + /// ``` + pub fn bar() {} +} + +pub use private::bar; diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout new file mode 100644 index 00000000000..ff26e7e3231 --- /dev/null +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout @@ -0,0 +1,22 @@ + +running 1 test +test $DIR/relative-path-include-bytes-132203.rs - (line 18) ... FAILED + +failures: + +---- $DIR/relative-path-include-bytes-132203.rs - (line 18) stdout ---- +error: couldn't read `$DIR/relative-dir-empty-file`: $FILE_NOT_FOUND_MSG (os error 2) + --> $DIR/relative-path-include-bytes-132203.rs:19:9 + | +LL | let x = include_bytes!("relative-dir-empty-file"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/relative-path-include-bytes-132203.rs - (line 18) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2024.stdout b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2024.stdout new file mode 100644 index 00000000000..e4c65703081 --- /dev/null +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2024.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/auxiliary/relative-dir.md - (line 1) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs new file mode 100644 index 00000000000..ceacd69a5fd --- /dev/null +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs @@ -0,0 +1,18 @@ +//@ revisions: edition2015 edition2024 +//@[edition2015]edition:2015 +//@[edition2015]check-fail +//@[edition2015]failure-status: 101 +//@[edition2015]compile-flags:--test --test-args=--test-threads=1 +//@[edition2024]edition:2024 +//@[edition2024]check-pass +//@[edition2024]compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests.rustdoc-ui.doctest." -> "$$DIR/" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "`: .* \(os error 2\)" -> "`: $$FILE_NOT_FOUND_MSG (os error 2)" + +// https://github.com/rust-lang/rust/issues/132203 +// This version, because it's edition2024, passes thanks to the new +// relative path. The edition2015 version fails, because paths are +// resolved relative to the rs file instead of relative to the md file. + +#![doc=include_str!("auxiliary/relative-dir.md")] diff --git a/tests/rustdoc-ui/doctest/run-directory.correct.stdout b/tests/rustdoc-ui/doctest/run-directory.correct.stdout new file mode 100644 index 00000000000..e9b2754794a --- /dev/null +++ b/tests/rustdoc-ui/doctest/run-directory.correct.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/run-directory.rs - foo (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/run-directory.incorrect.stdout b/tests/rustdoc-ui/doctest/run-directory.incorrect.stdout new file mode 100644 index 00000000000..97a5dbc5c0c --- /dev/null +++ b/tests/rustdoc-ui/doctest/run-directory.incorrect.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/run-directory.rs - foo (line 19) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/run-directory.rs b/tests/rustdoc-ui/doctest/run-directory.rs new file mode 100644 index 00000000000..090bd19c4d9 --- /dev/null +++ b/tests/rustdoc-ui/doctest/run-directory.rs @@ -0,0 +1,23 @@ +// this test asserts that the cwd of doctest invocations is set correctly. + +//@ revisions: correct incorrect +//@ check-pass +//@ [correct]compile-flags:--test --test-run-directory={{src-base}} +//@ [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// assert_eq!( +/// std::fs::read_to_string("doctest/run-directory.rs").unwrap(), +/// include_str!("run-directory.rs"), +/// ); +/// ``` +#[cfg(correct)] +pub fn foo() {} + +/// ``` +/// assert!(std::fs::read_to_string("doctest/run-directory.rs").is_err()); +/// ``` +#[cfg(incorrect)] +pub fn foo() {} diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs new file mode 100644 index 00000000000..88e2e0cf019 --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs @@ -0,0 +1,16 @@ +// This test checks that the test behave when `--doctest-build-arg` is passed multiple times. + +//@ check-pass +//@ compile-flags: --test -Zunstable-options --doctest-build-arg=--cfg=testcase_must_be_present +//@ compile-flags: --doctest-build-arg=--cfg=another +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #[cfg(testcase_must_be_present)] +/// #[cfg(another)] +/// fn must_be_present() {} +/// +/// fn main() { must_be_present() } +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout new file mode 100644 index 00000000000..f6b8ad6afab --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/rustflags-multiple-args.rs - Bar (line 9) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/rustflags.rs b/tests/rustdoc-ui/doctest/rustflags.rs new file mode 100644 index 00000000000..f030158cdaa --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags: --test -Zunstable-options --doctest-build-arg=--cfg=testcase_must_be_present +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #[cfg(testcase_must_be_present)] +/// fn must_be_present() {} +/// +/// fn main() { must_be_present() } +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/rustflags.stdout b/tests/rustdoc-ui/doctest/rustflags.stdout new file mode 100644 index 00000000000..b9da6637745 --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/rustflags.rs - Bar (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs new file mode 100644 index 00000000000..c53a8b48749 --- /dev/null +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs @@ -0,0 +1,17 @@ +// This test checks that it will output warnings for usage of `standalone` or `standalone_crate`. + +//@ edition: 2024 +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +#![deny(warnings)] + +//! ```standalone +//! bla +//! ``` +//! +//! ```standalone-crate +//! bla +//! ``` diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr new file mode 100644 index 00000000000..bfc1e919404 --- /dev/null +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr @@ -0,0 +1,38 @@ +error: unknown attribute `standalone` + --> $DIR/standalone-warning-2024.rs:11:1 + | +11 | / //! ```standalone +12 | | //! bla +13 | | //! ``` +14 | | //! +15 | | //! ```standalone-crate +16 | | //! bla +17 | | //! ``` + | |_______^ + | + = help: use `standalone_crate` to compile this code block separately + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` +note: the lint level is defined here + --> $DIR/standalone-warning-2024.rs:9:9 + | +9 | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` + +error: unknown attribute `standalone-crate` + --> $DIR/standalone-warning-2024.rs:11:1 + | +11 | / //! ```standalone +12 | | //! bla +13 | | //! ``` +14 | | //! +15 | | //! ```standalone-crate +16 | | //! bla +17 | | //! ``` + | |_______^ + | + = help: use `standalone_crate` to compile this code block separately + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/doctest/standalone-warning.rs b/tests/rustdoc-ui/doctest/standalone-warning.rs new file mode 100644 index 00000000000..ce081c7641c --- /dev/null +++ b/tests/rustdoc-ui/doctest/standalone-warning.rs @@ -0,0 +1,10 @@ +// This test checks that it will not output warning for usage of `standalone` or `standalone_crate`. +//@ check-pass + +//! ```standalone +//! bla +//! ``` +//! +//! ```standalone-crate +//! bla +//! ``` diff --git a/tests/rustdoc-ui/doctest/stdout-and-stderr.rs b/tests/rustdoc-ui/doctest/stdout-and-stderr.rs new file mode 100644 index 00000000000..9b0c69d8839 --- /dev/null +++ b/tests/rustdoc-ui/doctest/stdout-and-stderr.rs @@ -0,0 +1,26 @@ +// This test ensures that the output is correctly generated when the +// doctest fails. It checks when there is stderr and stdout, no stdout +// and no stderr/stdout. +// +// This is a regression test for <https://github.com/rust-lang/rust/issues/140289>. + +//@ edition: 2024 +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "panicked at .+rs:" -> "panicked at $$TMP:" +//@ failure-status: 101 +//@ rustc-env:RUST_BACKTRACE=0 + +//! ``` +//! println!("######## from a DOC TEST ########"); +//! assert_eq!("doc", "test"); +//! ``` +//! +//! ``` +//! assert_eq!("doc", "test"); +//! ``` +//! +//! ``` +//! std::process::exit(1); +//! ``` diff --git a/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout b/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout new file mode 100644 index 00000000000..b2febe1344f --- /dev/null +++ b/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout @@ -0,0 +1,46 @@ + +running 3 tests +test $DIR/stdout-and-stderr.rs - (line 15) ... FAILED +test $DIR/stdout-and-stderr.rs - (line 20) ... FAILED +test $DIR/stdout-and-stderr.rs - (line 24) ... FAILED + +failures: + +---- $DIR/stdout-and-stderr.rs - (line 15) stdout ---- +Test executable failed (exit status: 101). + +stdout: +######## from a DOC TEST ######## + +stderr: + +thread 'main' panicked at $TMP:7:1: +assertion `left == right` failed + left: "doc" + right: "test" +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +---- $DIR/stdout-and-stderr.rs - (line 20) stdout ---- +Test executable failed (exit status: 101). + +stderr: + +thread 'main' panicked at $TMP:15:1: +assertion `left == right` failed + left: "doc" + right: "test" +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +---- $DIR/stdout-and-stderr.rs - (line 24) stdout ---- +Test executable failed (exit status: 1). + + +failures: + $DIR/stdout-and-stderr.rs - (line 15) + $DIR/stdout-and-stderr.rs - (line 20) + $DIR/stdout-and-stderr.rs - (line 24) + +test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/test-compile-fail1.rs b/tests/rustdoc-ui/doctest/test-compile-fail1.rs new file mode 100644 index 00000000000..278f01f4c83 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-compile-fail1.rs @@ -0,0 +1,8 @@ +//@ compile-flags:--test + +/// ``` +/// assert!(true) +/// ``` +pub fn f() {} + +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/test-compile-fail1.stderr b/tests/rustdoc-ui/doctest/test-compile-fail1.stderr new file mode 100644 index 00000000000..02f4d8d754f --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-compile-fail1.stderr @@ -0,0 +1,14 @@ +error[E0428]: the name `f` is defined multiple times + --> $DIR/test-compile-fail1.rs:8:1 + | +6 | pub fn f() {} + | ---------- previous definition of the value `f` here +7 | +8 | pub fn f() {} + | ^^^^^^^^^^ `f` redefined here + | + = note: `f` must be defined only once in the value namespace of this module + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0428`. diff --git a/tests/rustdoc-ui/doctest/test-compile-fail2.rs b/tests/rustdoc-ui/doctest/test-compile-fail2.rs new file mode 100644 index 00000000000..7432cc9f826 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-compile-fail2.rs @@ -0,0 +1,3 @@ +//@ compile-flags:--test + +fail diff --git a/tests/rustdoc-ui/doctest/test-compile-fail2.stderr b/tests/rustdoc-ui/doctest/test-compile-fail2.stderr new file mode 100644 index 00000000000..f0ad40eb6ca --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-compile-fail2.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `::`, found `<eof>` + --> $DIR/test-compile-fail2.rs:3:1 + | +3 | fail + | ^^^^ expected one of `!` or `::` + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doctest/test-compile-fail3.rs b/tests/rustdoc-ui/doctest/test-compile-fail3.rs new file mode 100644 index 00000000000..a2486d9dc6f --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-compile-fail3.rs @@ -0,0 +1,3 @@ +//@ compile-flags:--test + +"fail diff --git a/tests/rustdoc-ui/doctest/test-compile-fail3.stderr b/tests/rustdoc-ui/doctest/test-compile-fail3.stderr new file mode 100644 index 00000000000..09d78b2f346 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-compile-fail3.stderr @@ -0,0 +1,9 @@ +error[E0765]: unterminated double quote string + --> $DIR/test-compile-fail3.rs:3:1 + | +3 | "fail + | ^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0765`. diff --git a/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stderr b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stderr new file mode 100644 index 00000000000..0dc7c2a2eea --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-main-alongside-exprs.stderr @@ -0,0 +1,8 @@ +warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function + --> $DIR/test-main-alongside-exprs.rs:15:1 + | +15 | //! ``` + | ^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/doctest/test-no_std.rs b/tests/rustdoc-ui/doctest/test-no_std.rs new file mode 100644 index 00000000000..9abfa4a3728 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-no_std.rs @@ -0,0 +1,13 @@ +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ check-pass + +#![no_std] + +extern crate alloc; + +/// ``` +/// assert!(true) +/// ``` +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/test-no_std.stdout b/tests/rustdoc-ui/doctest/test-no_std.stdout new file mode 100644 index 00000000000..8d5a30804c1 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-no_std.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/test-no_std.rs - f (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/test-type.rs b/tests/rustdoc-ui/doctest/test-type.rs new file mode 100644 index 00000000000..28c862fb69b --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-type.rs @@ -0,0 +1,26 @@ +//@ compile-flags: --test --test-args=--test-threads=1 +//@ check-pass +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// let a = true; +/// ``` +/// ```should_panic +/// panic!() +/// ``` +/// ```ignore (incomplete-code) +/// fn foo() { +/// ``` +/// ```no_run +/// loop { +/// println!("Hello, world"); +/// } +/// ``` +/// fails to compile +/// ```compile_fail +/// let x = 5; +/// x += 2; // shouldn't compile! +/// ``` + +pub fn f() {} diff --git a/tests/rustdoc-ui/doctest/test-type.stdout b/tests/rustdoc-ui/doctest/test-type.stdout new file mode 100644 index 00000000000..a66fd240d34 --- /dev/null +++ b/tests/rustdoc-ui/doctest/test-type.stdout @@ -0,0 +1,10 @@ + +running 5 tests +test $DIR/test-type.rs - f (line 12) ... ignored +test $DIR/test-type.rs - f (line 15) - compile ... ok +test $DIR/test-type.rs - f (line 21) - compile fail ... ok +test $DIR/test-type.rs - f (line 6) ... ok +test $DIR/test-type.rs - f (line 9) ... ok + +test result: ok. 4 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs new file mode 100644 index 00000000000..d90e152aada --- /dev/null +++ b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs @@ -0,0 +1,11 @@ +//@ compile-flags: --test +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 +//@ rustc-env: RUST_BACKTRACE=0 + +/// ```rust +/// let x = 7; +/// "unterminated +/// ``` +pub fn foo() {} diff --git a/tests/rustdoc-ui/doctest/unparseable-doc-test.stdout b/tests/rustdoc-ui/doctest/unparseable-doc-test.stdout new file mode 100644 index 00000000000..0574dc8b282 --- /dev/null +++ b/tests/rustdoc-ui/doctest/unparseable-doc-test.stdout @@ -0,0 +1,23 @@ + +running 1 test +test $DIR/unparseable-doc-test.rs - foo (line 7) ... FAILED + +failures: + +---- $DIR/unparseable-doc-test.rs - foo (line 7) stdout ---- +error[E0765]: unterminated double quote string + --> $DIR/unparseable-doc-test.rs:9:1 + | +LL | "unterminated + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0765`. +Couldn't compile the test. + +failures: + $DIR/unparseable-doc-test.rs - foo (line 7) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/warn-main-not-called.rs b/tests/rustdoc-ui/doctest/warn-main-not-called.rs new file mode 100644 index 00000000000..25d92e9cee9 --- /dev/null +++ b/tests/rustdoc-ui/doctest/warn-main-not-called.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ compile-flags:--test --test-args --test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// In case there is a `main` function in the doctest alongside expressions, +// the whole doctest will be wrapped into a function and the `main` function +// won't be called. + +//! ``` +//! macro_rules! bla { +//! ($($x:tt)*) => {} +//! } +//! +//! let x = 12; +//! bla!(fn main ()); +//! ``` +//! +//! ``` +//! let x = 12; +//! fn main() {} +//! ``` diff --git a/tests/rustdoc-ui/doctest/warn-main-not-called.stderr b/tests/rustdoc-ui/doctest/warn-main-not-called.stderr new file mode 100644 index 00000000000..3a079f47555 --- /dev/null +++ b/tests/rustdoc-ui/doctest/warn-main-not-called.stderr @@ -0,0 +1,14 @@ +warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function + --> $DIR/warn-main-not-called.rs:10:1 + | +10 | //! ``` + | ^^^^^^^ + +warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function + --> $DIR/warn-main-not-called.rs:19:1 + | +19 | //! ``` + | ^^^^^^^ + +warning: 2 warnings emitted + diff --git a/tests/rustdoc-ui/doctest/warn-main-not-called.stdout b/tests/rustdoc-ui/doctest/warn-main-not-called.stdout new file mode 100644 index 00000000000..07cdddc7b94 --- /dev/null +++ b/tests/rustdoc-ui/doctest/warn-main-not-called.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/warn-main-not-called.rs - (line 10) ... ok +test $DIR/warn-main-not-called.rs - (line 19) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs new file mode 100644 index 00000000000..3b4fb3f3443 --- /dev/null +++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs @@ -0,0 +1,21 @@ +//@ edition: 2024 +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ failure-status: 101 + +/// ``` +/// /* plop +/// ``` +pub fn one() {} + +/// ``` +/// } mod __doctest_1 { fn main() { +/// ``` +pub fn two() {} + +/// ```should_panic +/// panic!() +/// ``` +pub fn three() {} diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout b/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout new file mode 100644 index 00000000000..62e1fb10b9f --- /dev/null +++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.stdout @@ -0,0 +1,41 @@ + +running 1 test +test $DIR/wrong-ast-2024.rs - three (line 18) - should panic ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + + +running 2 tests +test $DIR/wrong-ast-2024.rs - one (line 8) ... FAILED +test $DIR/wrong-ast-2024.rs - two (line 13) ... FAILED + +failures: + +---- $DIR/wrong-ast-2024.rs - one (line 8) stdout ---- +error[E0758]: unterminated block comment + --> $DIR/wrong-ast-2024.rs:$LINE:$COL + | +LL | /* plop + | ^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0758`. +Couldn't compile the test. +---- $DIR/wrong-ast-2024.rs - two (line 13) stdout ---- +error: unexpected closing delimiter: `}` + --> $DIR/wrong-ast-2024.rs:$LINE:$COL + | +LL | } mod __doctest_1 { fn main() { + | ^ unexpected closing delimiter + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/wrong-ast-2024.rs - one (line 8) + $DIR/wrong-ast-2024.rs - two (line 13) + +test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/wrong-ast.rs b/tests/rustdoc-ui/doctest/wrong-ast.rs new file mode 100644 index 00000000000..be8f5417586 --- /dev/null +++ b/tests/rustdoc-ui/doctest/wrong-ast.rs @@ -0,0 +1,19 @@ +//@ compile-flags:--test --test-args=--test-threads=1 +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// ``` +/// /* plop +/// ``` +pub fn one() {} + +/// ``` +/// } mod __doctest_1 { fn main() { +/// ``` +pub fn two() {} + +/// ```should_panic +/// panic!() +/// ``` +pub fn three() {} diff --git a/tests/rustdoc-ui/doctest/wrong-ast.stdout b/tests/rustdoc-ui/doctest/wrong-ast.stdout new file mode 100644 index 00000000000..15494706c16 --- /dev/null +++ b/tests/rustdoc-ui/doctest/wrong-ast.stdout @@ -0,0 +1,36 @@ + +running 3 tests +test $DIR/wrong-ast.rs - one (line 6) ... FAILED +test $DIR/wrong-ast.rs - three (line 16) ... ok +test $DIR/wrong-ast.rs - two (line 11) ... FAILED + +failures: + +---- $DIR/wrong-ast.rs - one (line 6) stdout ---- +error[E0758]: unterminated block comment + --> $DIR/wrong-ast.rs:7:1 + | +LL | /* plop + | ^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0758`. +Couldn't compile the test. +---- $DIR/wrong-ast.rs - two (line 11) stdout ---- +error: unexpected closing delimiter: `}` + --> $DIR/wrong-ast.rs:12:1 + | +LL | } mod __doctest_1 { fn main() { + | ^ unexpected closing delimiter + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + $DIR/wrong-ast.rs - one (line 6) + $DIR/wrong-ast.rs - two (line 11) + +test result: FAILED. 1 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/error-in-impl-trait/README.md b/tests/rustdoc-ui/error-in-impl-trait/README.md new file mode 100644 index 00000000000..0b42ff1771e --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/README.md @@ -0,0 +1,7 @@ +Each of these needs to be in a separate file, +because the `span_delayed_bug` ICE in rustdoc won't be triggered +if even a single other error was emitted. + +However, conceptually they are all testing basically the same thing. +See https://github.com/rust-lang/rust/pull/73566#issuecomment-653689128 +for more details. diff --git a/tests/rustdoc-ui/error-in-impl-trait/async.rs b/tests/rustdoc-ui/error-in-impl-trait/async.rs new file mode 100644 index 00000000000..b7e740163cd --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/async.rs @@ -0,0 +1,7 @@ +//@ edition:2018 +//@ check-pass + +/// Should compile fine +pub async fn a() -> u32 { + error::_in::async_fn() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/closure.rs b/tests/rustdoc-ui/error-in-impl-trait/closure.rs new file mode 100644 index 00000000000..74aae098e57 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/closure.rs @@ -0,0 +1,5 @@ +//@ check-pass +// manually desugared version of an `async fn` (but with a closure instead of a coroutine) +pub fn a() -> impl Fn() -> u32 { + || content::doesnt::matter() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/const-generics.rs b/tests/rustdoc-ui/error-in-impl-trait/const-generics.rs new file mode 100644 index 00000000000..948014bb858 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/const-generics.rs @@ -0,0 +1,23 @@ +//@ check-pass +//@ edition:2018 +trait ValidTrait {} + +/// This has docs +pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> { + loop {} +} + +pub trait Trait<const N: usize> {} +impl Trait<1> for u8 {} +impl Trait<2> for u8 {} +impl<const N: usize> Trait<N> for [u8; N] {} + +/// This also has docs +pub fn test<const N: usize>() -> impl Trait<N> where u8: Trait<N> { + loop {} +} + +/// Document all the functions +pub async fn a_sink<const N: usize>(v: [u8; N]) -> impl Trait<N> { + loop {} +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/generic-argument.rs b/tests/rustdoc-ui/error-in-impl-trait/generic-argument.rs new file mode 100644 index 00000000000..735d0f5db38 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/generic-argument.rs @@ -0,0 +1,7 @@ +//@ check-pass +trait ValidTrait {} + +/// This has docs +pub fn f() -> impl ValidTrait { + Vec::<DoesNotExist>::new() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs b/tests/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs new file mode 100644 index 00000000000..fef2520ddbe --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs @@ -0,0 +1,6 @@ +//@ check-pass +pub trait ValidTrait {} +/// This returns impl trait +pub fn g() -> impl ValidTrait { + (|| error::_in::impl_trait::alias::nested::closure())() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/impl-keyword.rs b/tests/rustdoc-ui/error-in-impl-trait/impl-keyword.rs new file mode 100644 index 00000000000..0cb5c33ef0d --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/impl-keyword.rs @@ -0,0 +1,6 @@ +//@ check-pass +pub trait ValidTrait {} +/// This returns impl trait +pub fn g() -> impl ValidTrait { + error::_in::impl_trait() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs new file mode 100644 index 00000000000..7151ebd599f --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs @@ -0,0 +1,8 @@ +pub fn f() -> impl Sized { + pub enum E { + //~^ ERROR: recursive type + V(E), + } + + unimplemented!() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr new file mode 100644 index 00000000000..69e2eebcdd8 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `f::E` has infinite size + --> $DIR/infinite-recursive-type-2.rs:2:5 + | +LL | pub enum E { + | ^^^^^^^^^^ +LL | +LL | V(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | V(Box<E>), + | ++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs new file mode 100644 index 00000000000..032da8f53f0 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs @@ -0,0 +1,14 @@ +//@ normalize-stderr: "`.*`" -> "`DEF_ID`" +//@ normalize-stdout: "`.*`" -> "`DEF_ID`" +//@ edition:2018 + +pub async fn f() -> impl std::fmt::Debug { + #[derive(Debug)] + enum E { //~ ERROR + This(E), + Unit, + } + E::Unit +} + +fn main() {} diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.stderr b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.stderr new file mode 100644 index 00000000000..c169ca670a6 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.stderr @@ -0,0 +1,16 @@ +error[E0072]: recursive type `DEF_ID` has infinite size + --> $DIR/infinite-recursive-type-impl-trait-return.rs:7:5 + | +LL | enum E { + | ^^^^^^ +LL | This(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `DEF_ID`) to break the cycle + | +LL | This(Box<E>), + | ++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `DEF_ID`. diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs new file mode 100644 index 00000000000..1f855051729 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs @@ -0,0 +1,8 @@ +fn f() -> impl Sized { + enum E { + //~^ ERROR: recursive type + V(E), + } + + unimplemented!() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr new file mode 100644 index 00000000000..bd5de384cde --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `f::E` has infinite size + --> $DIR/infinite-recursive-type.rs:2:5 + | +LL | enum E { + | ^^^^^^ +LL | +LL | V(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | V(Box<E>), + | ++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs b/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs new file mode 100644 index 00000000000..6c53c2912e1 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/realistic-async.rs @@ -0,0 +1,28 @@ +//@ edition:2018 +//@ check-pass + +mod windows { + pub trait WinFoo { + fn foo(&self) {} + } + + impl WinFoo for () {} +} + +#[cfg(any(windows, doc))] +use windows::*; + +mod unix { + pub trait UnixFoo { + fn foo(&self) {} + } + + impl UnixFoo for () {} +} + +#[cfg(any(unix, doc))] +use unix::*; + +async fn bar() { + ().foo() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs b/tests/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs new file mode 100644 index 00000000000..b3fd59a7275 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs @@ -0,0 +1,10 @@ +//@ check-pass +#![feature(type_alias_impl_trait)] + +pub trait ValidTrait {} +type ImplTrait = impl ValidTrait; + +/// This returns impl trait, but using a type alias +pub fn h() -> ImplTrait { + (|| error::_in::impl_trait::alias::nested::closure())() +} diff --git a/tests/rustdoc-ui/error-in-impl-trait/trait-alias.rs b/tests/rustdoc-ui/error-in-impl-trait/trait-alias.rs new file mode 100644 index 00000000000..9e715e0d324 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/trait-alias.rs @@ -0,0 +1,10 @@ +//@ check-pass +#![feature(type_alias_impl_trait)] + +pub trait ValidTrait {} +type ImplTrait = impl ValidTrait; + +/// This returns impl trait, but using a type alias +pub fn h() -> ImplTrait { + error::_in::impl_trait::alias() +} diff --git a/tests/rustdoc-ui/extract-doctests-result.rs b/tests/rustdoc-ui/extract-doctests-result.rs new file mode 100644 index 00000000000..88affb6d333 --- /dev/null +++ b/tests/rustdoc-ui/extract-doctests-result.rs @@ -0,0 +1,11 @@ +// Test to ensure that it generates expected output for `--output-format=doctest` command-line +// flag. + +//@ compile-flags:-Z unstable-options --output-format=doctest +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ check-pass + +//! ``` +//! let x = 12; +//! Ok(()) +//! ``` diff --git a/tests/rustdoc-ui/extract-doctests-result.stdout b/tests/rustdoc-ui/extract-doctests-result.stdout new file mode 100644 index 00000000000..44e6d33c662 --- /dev/null +++ b/tests/rustdoc-ui/extract-doctests-result.stdout @@ -0,0 +1 @@ +{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests-result.rs","line":8,"doctest_attributes":{"original":"","should_panic":false,"no_run":false,"ignore":"None","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nOk(())","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nOk(())","wrapper":{"before":"fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> {\n","after":"\n} _inner().unwrap() }","returns_result":true}},"name":"$DIR/extract-doctests-result.rs - (line 8)"}]} \ No newline at end of file diff --git a/tests/rustdoc-ui/extract-doctests.rs b/tests/rustdoc-ui/extract-doctests.rs new file mode 100644 index 00000000000..06bd35969d0 --- /dev/null +++ b/tests/rustdoc-ui/extract-doctests.rs @@ -0,0 +1,15 @@ +// Test to ensure that it generates expected output for `--output-format=doctest` command-line +// flag. + +//@ compile-flags:-Z unstable-options --output-format=doctest +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ check-pass + +//! ```ignore (checking attributes) +//! let x = 12; +//! let y = 14; +//! ``` +//! +//! ```edition2018,compile_fail +//! let +//! ``` diff --git a/tests/rustdoc-ui/extract-doctests.stdout b/tests/rustdoc-ui/extract-doctests.stdout new file mode 100644 index 00000000000..796ecd82f1c --- /dev/null +++ b/tests/rustdoc-ui/extract-doctests.stdout @@ -0,0 +1 @@ +{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nlet y = 14;","wrapper":{"before":"fn main() {\n","after":"\n}","returns_result":false}},"name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":null,"name":"$DIR/extract-doctests.rs - (line 13)"}]} \ No newline at end of file diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs new file mode 100644 index 00000000000..17812018b9b --- /dev/null +++ b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs @@ -0,0 +1,7 @@ +#![doc(cfg_hide(test))] +//~^ ERROR `#[doc(cfg_hide)]` is experimental + +#[cfg(not(test))] +pub fn public_fn() {} +#[cfg(test)] +pub fn internal_use_only() {} diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr new file mode 100644 index 00000000000..55135986ffe --- /dev/null +++ b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr @@ -0,0 +1,13 @@ +error[E0658]: `#[doc(cfg_hide)]` is experimental + --> $DIR/feature-gate-doc_cfg_hide.rs:1:1 + | +LL | #![doc(cfg_hide(test))] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 <https://github.com/rust-lang/rust/issues/43781> for more information + = help: add `#![feature(doc_cfg_hide)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt-unstable.rs b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt-unstable.rs new file mode 100644 index 00000000000..0ea2edb6f5a --- /dev/null +++ b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt-unstable.rs @@ -0,0 +1,6 @@ +// This test purpose is to check that the "--generate-link-to-definition" +// option can only be used on nightly. + +//@ compile-flags: --generate-link-to-definition + +pub fn f() {} diff --git a/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt-unstable.stderr b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt-unstable.stderr new file mode 100644 index 00000000000..a8ddf91bcbf --- /dev/null +++ b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt-unstable.stderr @@ -0,0 +1,2 @@ +error: the `-Z unstable-options` flag must also be passed to enable the flag `generate-link-to-definition` + diff --git a/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt.rs b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt.rs new file mode 100644 index 00000000000..9d6ec0caf9f --- /dev/null +++ b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt.rs @@ -0,0 +1,9 @@ +// This test purpose is to check that the "--generate-link-to-definition" +// option can only be used with HTML generation. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition --output-format json +//@ check-pass + +pub fn f() {} + +//~? WARN `--generate-link-to-definition` option can only be used with HTML output format diff --git a/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt.stderr b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt.stderr new file mode 100644 index 00000000000..62b0e3ce408 --- /dev/null +++ b/tests/rustdoc-ui/generate-link-to-definition/generate-link-to-definition-opt.stderr @@ -0,0 +1,4 @@ +warning: `--generate-link-to-definition` option can only be used with HTML output format + | + = note: `--generate-link-to-definition` option will be ignored + diff --git a/tests/rustdoc-ui/hashtag-doctest.rs b/tests/rustdoc-ui/hashtag-doctest.rs new file mode 100644 index 00000000000..5f745611530 --- /dev/null +++ b/tests/rustdoc-ui/hashtag-doctest.rs @@ -0,0 +1,17 @@ +// This test ensures that `##` are not emitting a warning when generating +// docs with the 2024 edition (or any edition). +// Regression test for <https://github.com/rust-lang/rust/issues/136899>. + +//@ check-pass +//@revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 + +#![deny(warnings)] + +//! Test +//! +//! ``` +//! ##[allow(dead_code)] +//! println!("hello world"); +//! ``` diff --git a/tests/rustdoc-ui/hidden-trait-method-34423.rs b/tests/rustdoc-ui/hidden-trait-method-34423.rs new file mode 100644 index 00000000000..8f3572e35bc --- /dev/null +++ b/tests/rustdoc-ui/hidden-trait-method-34423.rs @@ -0,0 +1,13 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/34423 + +pub struct Foo; + +pub trait Bar { + #[doc(hidden)] + fn bar() {} +} + +impl Bar for Foo { + fn bar() {} +} diff --git a/tests/rustdoc-ui/ice-assoc-const-for-primitive-31808.rs b/tests/rustdoc-ui/ice-assoc-const-for-primitive-31808.rs new file mode 100644 index 00000000000..2c1c666b22c --- /dev/null +++ b/tests/rustdoc-ui/ice-assoc-const-for-primitive-31808.rs @@ -0,0 +1,16 @@ +//@ check-pass + +// Test that associated item impls on primitive types don't crash rustdoc + +// https://github.com/rust-lang/rust/issues/31808 +#![crate_name="issue_31808"] + +pub trait Foo { + const BAR: usize; + type BAZ; +} + +impl Foo for () { + const BAR: usize = 0; + type BAZ = usize; +} diff --git a/tests/rustdoc-ui/ice-assoc-type-loop-102154.rs b/tests/rustdoc-ui/ice-assoc-type-loop-102154.rs new file mode 100644 index 00000000000..68e22ce6ea1 --- /dev/null +++ b/tests/rustdoc-ui/ice-assoc-type-loop-102154.rs @@ -0,0 +1,16 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/102154 + +trait A<Y, N> { + type B; +} +type MaybeBox<T> = <T as A<T, Box<T>>>::B; +struct P { + t: MaybeBox<P> +} +impl<Y, N> A<Y, N> for P { + type B = N; +} +fn main() { + let t: MaybeBox<P>; +} diff --git a/tests/rustdoc-ui/ice-blanket-impl-119792.rs b/tests/rustdoc-ui/ice-blanket-impl-119792.rs new file mode 100644 index 00000000000..90f0ea8469b --- /dev/null +++ b/tests/rustdoc-ui/ice-blanket-impl-119792.rs @@ -0,0 +1,19 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/119792 + +struct Wrapper<T>(T); + +trait Div<Rhs> {} +trait Mul<Rhs> { + type Output; +} + +impl<T> Mul<T> for Wrapper<T> { + type Output = (); +} + +impl<T> Div<Self> for Wrapper<T> {} + +pub trait NumOps<Rhs> {} + +impl<T, Rhs> NumOps<Rhs> for T where T: Mul<Rhs, Output = ()> + Div<Rhs> {} diff --git a/tests/rustdoc-ui/ice-blanket-impl-52873.rs b/tests/rustdoc-ui/ice-blanket-impl-52873.rs new file mode 100644 index 00000000000..b150d41ce2a --- /dev/null +++ b/tests/rustdoc-ui/ice-blanket-impl-52873.rs @@ -0,0 +1,175 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/52873 +#![crate_name="foo"] + +// Regression test for #52873. We used to ICE due to unexpected +// overflows when checking for "blanket impl inclusion". + +use std::marker::PhantomData; +use std::cmp::Ordering; +use std::ops::{Add, Mul}; + +pub type True = B1; +pub type False = B0; +pub type U0 = UTerm; +pub type U1 = UInt<UTerm, B1>; + +pub trait NonZero {} + +pub trait Bit { +} + +pub trait Unsigned { +} + +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] +pub struct B0; + +impl B0 { + #[inline] + pub fn new() -> B0 { + B0 + } +} + +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] +pub struct B1; + +impl B1 { + #[inline] + pub fn new() -> B1 { + B1 + } +} + +impl Bit for B0 { +} + +impl Bit for B1 { +} + +impl NonZero for B1 {} + +pub trait PrivatePow<Y, N> { + type Output; +} +pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output; + +pub type Add1<A> = <A as Add<::B1>>::Output; +pub type Prod<A, B> = <A as Mul<B>>::Output; +pub type Square<A> = <A as Mul>::Output; +pub type Sum<A, B> = <A as Add<B>>::Output; + +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] +pub struct UTerm; + +impl UTerm { + #[inline] + pub fn new() -> UTerm { + UTerm + } +} + +impl Unsigned for UTerm { +} + +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] +pub struct UInt<U, B> { + _marker: PhantomData<(U, B)>, +} + +impl<U: Unsigned, B: Bit> UInt<U, B> { + #[inline] + pub fn new() -> UInt<U, B> { + UInt { + _marker: PhantomData, + } + } +} + +impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> { +} + +impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {} + +impl Add<B0> for UTerm { + type Output = UTerm; + fn add(self, _: B0) -> Self::Output { + UTerm + } +} + +impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> { + type Output = UInt<U, B>; + fn add(self, _: B0) -> Self::Output { + UInt::new() + } +} + +impl<U: Unsigned> Add<U> for UTerm { + type Output = U; + fn add(self, _: U) -> Self::Output { + unimplemented!() + } +} + +impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> { + type Output = UTerm; + fn mul(self, _: B0) -> Self::Output { + UTerm + } +} + +impl<U: Unsigned, B: Bit> Mul<B1> for UInt<U, B> { + type Output = UInt<U, B>; + fn mul(self, _: B1) -> Self::Output { + UInt::new() + } +} + +impl<U: Unsigned> Mul<U> for UTerm { + type Output = UTerm; + fn mul(self, _: U) -> Self::Output { + UTerm + } +} + +impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B0> +where + Ul: Mul<UInt<Ur, B>>, +{ + type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>; + fn mul(self, _: UInt<Ur, B>) -> Self::Output { + unimplemented!() + } +} + +pub trait Pow<Exp> { + type Output; +} + +impl<X: Unsigned, N: Unsigned> Pow<N> for X +where + X: PrivatePow<U1, N>, +{ + type Output = PrivatePowOut<X, U1, N>; +} + +impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X { + type Output = Y; +} + +impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X +where + X: Mul<Y>, +{ + type Output = Prod<X, Y>; +} + +impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B0>> for X +where + X: Mul, + Square<X>: PrivatePow<Y, UInt<U, B>>, +{ + type Output = PrivatePowOut<Square<X>, Y, UInt<U, B>>; +} diff --git a/tests/rustdoc-ui/ice-blanket-impl-56701.rs b/tests/rustdoc-ui/ice-blanket-impl-56701.rs new file mode 100644 index 00000000000..13b0fc9032a --- /dev/null +++ b/tests/rustdoc-ui/ice-blanket-impl-56701.rs @@ -0,0 +1,35 @@ +//@ check-pass +// This shouldn't cause a stack overflow when rustdoc is run +// https://github.com/rust-lang/rust/issues/56701 + +use std::ops::Deref; +use std::ops::DerefMut; + +pub trait SimpleTrait { + type SimpleT; +} + +impl<Inner: SimpleTrait, Outer: Deref<Target = Inner>> SimpleTrait for Outer { + type SimpleT = Inner::SimpleT; +} + +pub trait AnotherTrait { + type AnotherT; +} + +impl<T, Simple: SimpleTrait<SimpleT = Vec<T>>> AnotherTrait for Simple { + type AnotherT = T; +} + +pub struct Unrelated<Inner, UnrelatedT: DerefMut<Target = Vec<Inner>>>(UnrelatedT); + +impl<Inner, UnrelatedT: DerefMut<Target = Vec<Inner>>> Deref for Unrelated<Inner, UnrelatedT> { + type Target = Vec<Inner>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + + +pub fn main() { } diff --git a/tests/rustdoc-ui/ice-blanket-impl-selection-55001.rs b/tests/rustdoc-ui/ice-blanket-impl-selection-55001.rs new file mode 100644 index 00000000000..89d3904af4e --- /dev/null +++ b/tests/rustdoc-ui/ice-blanket-impl-selection-55001.rs @@ -0,0 +1,35 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/55001 +#![crate_name="foo"] + +// Regression test for issue #55001. Previously, we would incorrectly +// cache certain trait selection results when checking for blanket impls, +// resulting in an ICE when we tried to confirm the cached ParamCandidate +// against an obligation. + +pub struct DefaultAllocator; +pub struct Standard; +pub struct Inner; + +pub trait Rand {} + +pub trait Distribution<T> {} +pub trait Allocator<N> {} + +impl<T> Rand for T where Standard: Distribution<T> {} + +impl<A> Distribution<Point<A>> for Standard +where +DefaultAllocator: Allocator<A>, +Standard: Distribution<A> {} + +impl Distribution<Inner> for Standard {} + + +pub struct Point<N> +where DefaultAllocator: Allocator<N> +{ + field: N +} + +fn main() {} diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs new file mode 100644 index 00000000000..2e384fa1be6 --- /dev/null +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -0,0 +1,16 @@ +//@ compile-flags: -Ztreat-err-as-bug +//@ rustc-env:RUSTC_ICE=0 +//@ failure-status: 101 + +//@ normalize-stderr: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" +//@ normalize-stderr: "thread.*panicked at compiler.*" -> "" +//@ normalize-stderr: " +\d{1,}: .*\n" -> "" +//@ normalize-stderr: " + at .*\n" -> "" +//@ normalize-stderr: ".*note: Some details are omitted.*\n" -> "" + +fn wrong() +//~^ ERROR expected one of + +//~? RAW aborting due to +//~? RAW we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr new file mode 100644 index 00000000000..b6eb8a1792d --- /dev/null +++ b/tests/rustdoc-ui/ice-bug-report-url.stderr @@ -0,0 +1,21 @@ +error: internal compiler error: expected one of `->`, `where`, or `{`, found `<eof>` + --> $DIR/ice-bug-report-url.rs:12:10 + | +LL | fn wrong() + | ^ expected one of `->`, `where`, or `{` + + + +aborting due to `-Z treat-err-as-bug=1` +stack backtrace: + +error: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md + +note: please make sure that you have updated to the latest nightly + +note: rustc {version} running on {platform} + +query stack during panic: +end of query stack diff --git a/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs b/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs new file mode 100644 index 00000000000..1434bef49e0 --- /dev/null +++ b/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs @@ -0,0 +1,15 @@ +// Regression test for ICE https://github.com/rust-lang/rust/issues/73061 + +//@ check-pass +//@ aux-build:issue-73061.rs + +extern crate issue_73061; + +pub struct Z; + +impl issue_73061::Foo for Z { + type X = <issue_73061::F as issue_73061::Foo>::X; + fn x(&self) -> Self::X { + issue_73061::F.x() + } +} diff --git a/tests/rustdoc-ui/ice-method-where-clause-circular-100620.rs b/tests/rustdoc-ui/ice-method-where-clause-circular-100620.rs new file mode 100644 index 00000000000..e12b214410b --- /dev/null +++ b/tests/rustdoc-ui/ice-method-where-clause-circular-100620.rs @@ -0,0 +1,22 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/100620 + +pub trait Bar<S> {} + +pub trait Qux<T> {} + +pub trait Foo<T, S> { + fn bar() + where + T: Bar<S>, + { + } +} + +pub struct Concrete; + +impl<S> Foo<(), S> for Concrete {} + +impl<T, S> Bar<S> for T where S: Qux<T> {} + +impl<T, S> Qux<T> for S where T: Bar<S> {} diff --git a/tests/rustdoc-ui/ice-unresolved-import-100241.rs b/tests/rustdoc-ui/ice-unresolved-import-100241.rs new file mode 100644 index 00000000000..eef4b8355bf --- /dev/null +++ b/tests/rustdoc-ui/ice-unresolved-import-100241.rs @@ -0,0 +1,14 @@ +//! See [`S`]. + +// Check that this isn't an ICE +//@ should-fail + +// https://github.com/rust-lang/rust/issues/100241 + +mod foo { + pub use inner::S; + //~^ ERROR unresolved imports `inner`, `foo::S` +} + +use foo::*; +use foo::S; diff --git a/tests/rustdoc-ui/ice-unresolved-import-100241.stderr b/tests/rustdoc-ui/ice-unresolved-import-100241.stderr new file mode 100644 index 00000000000..a82847d381c --- /dev/null +++ b/tests/rustdoc-ui/ice-unresolved-import-100241.stderr @@ -0,0 +1,14 @@ +error[E0432]: unresolved import `inner` + --> $DIR/ice-unresolved-import-100241.rs:9:13 + | +LL | pub use inner::S; + | ^^^^^ use of unresolved module or unlinked crate `inner` + | +help: you might be missing a crate named `inner`, add it to your project and import it in your code + | +LL + extern crate inner; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/rustdoc-ui/ignore-block-help.rs b/tests/rustdoc-ui/ignore-block-help.rs new file mode 100644 index 00000000000..bc46cdb0e00 --- /dev/null +++ b/tests/rustdoc-ui/ignore-block-help.rs @@ -0,0 +1,10 @@ +//@ check-pass + +/// ```ignore (to-prevent-tidy-error) +/// let heart = 'â¤ï¸'; +/// ``` +//~^^^ WARNING could not parse code block +//~| NOTE on by default +//~| NOTE character literal may only contain one codepoint +//~| HELP `ignore` code blocks require valid Rust code +pub struct X; diff --git a/tests/rustdoc-ui/ignore-block-help.stderr b/tests/rustdoc-ui/ignore-block-help.stderr new file mode 100644 index 00000000000..a30ea51dd8a --- /dev/null +++ b/tests/rustdoc-ui/ignore-block-help.stderr @@ -0,0 +1,19 @@ +warning: could not parse code block as Rust code + --> $DIR/ignore-block-help.rs:3:5 + | +LL | /// ```ignore (to-prevent-tidy-error) + | _____^ +LL | | /// let heart = 'â¤ï¸'; +LL | | /// ``` + | |_______^ + | +help: `ignore` code blocks require valid Rust code for syntax highlighting; mark blocks that do not contain Rust code as text: ```text + --> $DIR/ignore-block-help.rs:3:5 + | +LL | /// ```ignore (to-prevent-tidy-error) + | ^^^ + = note: error from rustc: character literal may only contain one codepoint + = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/impl-fn-nesting.rs b/tests/rustdoc-ui/impl-fn-nesting.rs new file mode 100644 index 00000000000..a927f6bd799 --- /dev/null +++ b/tests/rustdoc-ui/impl-fn-nesting.rs @@ -0,0 +1,49 @@ +// Ensure that rustdoc gives errors for trait impls inside function bodies that don't resolve. +// See https://github.com/rust-lang/rust/pull/73566 +pub struct ValidType; +pub trait ValidTrait {} +pub trait NeedsBody { + type Item; + fn f(); +} + +/// This function has docs +pub fn f<B: UnknownBound>(a: UnknownType, b: B) { +//~^ ERROR cannot find trait `UnknownBound` in this scope +//~| ERROR cannot find type `UnknownType` in this scope + impl UnknownTrait for ValidType {} //~ ERROR cannot find trait `UnknownTrait` + impl<T: UnknownBound> UnknownTrait for T {} + //~^ ERROR cannot find trait `UnknownBound` in this scope + //~| ERROR cannot find trait `UnknownTrait` in this scope + impl ValidTrait for UnknownType {} + //~^ ERROR cannot find type `UnknownType` in this scope + impl ValidTrait for ValidType where ValidTrait: UnknownBound {} + //~^ ERROR cannot find trait `UnknownBound` in this scope + + /// This impl has documentation + impl NeedsBody for ValidType { + type Item = UnknownType; + //~^ ERROR cannot find type `UnknownType` in this scope + + /// This function has documentation + fn f() { + <UnknownTypeShouldBeIgnored>::a(); + content::shouldnt::matter(); + unknown_macro!(); + //~^ ERROR cannot find macro `unknown_macro` in this scope + + /// This is documentation for a macro + macro_rules! can_define_macros_here_too { + () => { + this::content::should::also::be::ignored() + } + } + can_define_macros_here_too!(); + + /// This also is documented. + pub fn doubly_nested(c: UnknownType) { + //~^ ERROR cannot find type `UnknownType` in this scope + } + } + } +} diff --git a/tests/rustdoc-ui/impl-fn-nesting.stderr b/tests/rustdoc-ui/impl-fn-nesting.stderr new file mode 100644 index 00000000000..75e6b4ed217 --- /dev/null +++ b/tests/rustdoc-ui/impl-fn-nesting.stderr @@ -0,0 +1,64 @@ +error: cannot find macro `unknown_macro` in this scope + --> $DIR/impl-fn-nesting.rs:32:13 + | +LL | unknown_macro!(); + | ^^^^^^^^^^^^^ + +error[E0405]: cannot find trait `UnknownBound` in this scope + --> $DIR/impl-fn-nesting.rs:11:13 + | +LL | pub fn f<B: UnknownBound>(a: UnknownType, b: B) { + | ^^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `UnknownType` in this scope + --> $DIR/impl-fn-nesting.rs:11:30 + | +LL | pub fn f<B: UnknownBound>(a: UnknownType, b: B) { + | ^^^^^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `UnknownTrait` in this scope + --> $DIR/impl-fn-nesting.rs:14:10 + | +LL | impl UnknownTrait for ValidType {} + | ^^^^^^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `UnknownTrait` in this scope + --> $DIR/impl-fn-nesting.rs:15:27 + | +LL | impl<T: UnknownBound> UnknownTrait for T {} + | ^^^^^^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `UnknownBound` in this scope + --> $DIR/impl-fn-nesting.rs:15:13 + | +LL | impl<T: UnknownBound> UnknownTrait for T {} + | ^^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `UnknownType` in this scope + --> $DIR/impl-fn-nesting.rs:18:25 + | +LL | impl ValidTrait for UnknownType {} + | ^^^^^^^^^^^ not found in this scope + +error[E0405]: cannot find trait `UnknownBound` in this scope + --> $DIR/impl-fn-nesting.rs:20:53 + | +LL | impl ValidTrait for ValidType where ValidTrait: UnknownBound {} + | ^^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `UnknownType` in this scope + --> $DIR/impl-fn-nesting.rs:25:21 + | +LL | type Item = UnknownType; + | ^^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `UnknownType` in this scope + --> $DIR/impl-fn-nesting.rs:44:37 + | +LL | pub fn doubly_nested(c: UnknownType) { + | ^^^^^^^^^^^ not found in this scope + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0405, E0412. +For more information about an error, try `rustc --explain E0405`. diff --git a/tests/rustdoc-ui/include-str-bare-urls.rs b/tests/rustdoc-ui/include-str-bare-urls.rs new file mode 100644 index 00000000000..f80e28e8ca7 --- /dev/null +++ b/tests/rustdoc-ui/include-str-bare-urls.rs @@ -0,0 +1,17 @@ +// https://github.com/rust-lang/rust/issues/118549 +// +// HEADS UP! +// +// Normally, a line with errors on it will also have a comment +// marking it up as something that needs to generate an error. +// +// The test harness doesn't gather hot comments from the `.md` file. +// Rustdoc will generate an error for the line, and the `.stderr` +// snapshot includes this error, but Compiletest doesn't see it. +// +// If the stderr file changes, make sure the warning points at the URL! + +#![deny(rustdoc::bare_urls)] +#![doc=include_str!("auxiliary/include-str-bare-urls.md")] + +//~? ERROR this URL is not a hyperlink diff --git a/tests/rustdoc-ui/include-str-bare-urls.stderr b/tests/rustdoc-ui/include-str-bare-urls.stderr new file mode 100644 index 00000000000..53da2411874 --- /dev/null +++ b/tests/rustdoc-ui/include-str-bare-urls.stderr @@ -0,0 +1,19 @@ +error: this URL is not a hyperlink + --> $DIR/auxiliary/include-str-bare-urls.md:1:11 + | +LL | HEADS UP! https://example.com MUST SHOW UP IN THE STDERR FILE! + | ^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +note: the lint level is defined here + --> $DIR/include-str-bare-urls.rs:14:9 + | +LL | #![deny(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | HEADS UP! <https://example.com> MUST SHOW UP IN THE STDERR FILE! + | + + + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/infinite-recursive-type.rs b/tests/rustdoc-ui/infinite-recursive-type.rs new file mode 100644 index 00000000000..32793fc4f76 --- /dev/null +++ b/tests/rustdoc-ui/infinite-recursive-type.rs @@ -0,0 +1,4 @@ +enum E { +//~^ ERROR recursive type `E` has infinite size + V(E), +} diff --git a/tests/rustdoc-ui/infinite-recursive-type.stderr b/tests/rustdoc-ui/infinite-recursive-type.stderr new file mode 100644 index 00000000000..cc914de6d1e --- /dev/null +++ b/tests/rustdoc-ui/infinite-recursive-type.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `E` has infinite size + --> $DIR/infinite-recursive-type.rs:1:1 + | +LL | enum E { + | ^^^^^^ +LL | +LL | V(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | V(Box<E>), + | ++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/tests/rustdoc-ui/inherent-assoc-consts-36031.rs b/tests/rustdoc-ui/inherent-assoc-consts-36031.rs new file mode 100644 index 00000000000..e487d130671 --- /dev/null +++ b/tests/rustdoc-ui/inherent-assoc-consts-36031.rs @@ -0,0 +1,12 @@ +//@ aux-build:issue-36031.rs +//@ check-pass +//@ build-aux-docs +//@ ignore-cross-compile + +// https://github.com/rust-lang/rust/issues/36031 + +#![crate_name = "foo"] + +extern crate issue_36031; + +pub use issue_36031::Foo; diff --git a/tests/rustdoc-ui/intra-doc/.gitattributes b/tests/rustdoc-ui/intra-doc/.gitattributes new file mode 100644 index 00000000000..0ac2e3c27f4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/.gitattributes @@ -0,0 +1 @@ +warning-crlf.rs -text 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 00000000000..51922caeb25 --- /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 00000000000..a38df98433d --- /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 1 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 00000000000..0290b858204 --- /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 primitive 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 00000000000..47853e0b589 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ambiguity.stderr @@ -0,0 +1,101 @@ +error: `true` is both a module and a primitive 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 primitive type, prefix with `prim@` + | +LL | /// [prim@true] + | +++++ + +error: `ambiguous` is both a function and a struct + --> $DIR/ambiguity.rs:27:7 + | +LL | /// [`ambiguous`] is ambiguous. + | ^^^^^^^^^ ambiguous link + | +help: to link to the function, add parentheses + | +LL | /// [`ambiguous()`] is ambiguous. + | ++ +help: to link to the struct, prefix with `struct@` + | +LL | /// [`struct@ambiguous`] is ambiguous. + | +++++++ + +error: `ambiguous` is both a function and a struct + --> $DIR/ambiguity.rs:29:6 + | +LL | /// [ambiguous] is ambiguous. + | ^^^^^^^^^ ambiguous link + | +help: to link to the function, add parentheses + | +LL | /// [ambiguous()] is ambiguous. + | ++ +help: to link to the struct, prefix with `struct@` + | +LL | /// [struct@ambiguous] is ambiguous. + | +++++++ + +error: `multi_conflict` is a function, a struct, and a macro + --> $DIR/ambiguity.rs:31:7 + | +LL | /// [`multi_conflict`] is a three-way conflict. + | ^^^^^^^^^^^^^^ ambiguous link + | +help: to link to the function, add parentheses + | +LL | /// [`multi_conflict()`] is a three-way conflict. + | ++ +help: to link to the struct, prefix with `struct@` + | +LL | /// [`struct@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 constant and a module + --> $DIR/ambiguity.rs:33:16 + | +LL | /// Ambiguous [type_and_value]. + | ^^^^^^^^^^^^^^ ambiguous link + | +help: to link to the constant, prefix with `const@` + | +LL | /// Ambiguous [const@type_and_value]. + | ++++++ +help: to link to the module, prefix with `mod@` + | +LL | /// Ambiguous [mod@type_and_value]. + | ++++ + +error: `foo::bar` is both a function and an enum + --> $DIR/ambiguity.rs:35:43 + | +LL | /// Ambiguous non-implied shortcut link [`foo::bar`]. + | ^^^^^^^^ ambiguous link + | +help: to link to the function, add parentheses + | +LL | /// Ambiguous non-implied shortcut link [`foo::bar()`]. + | ++ +help: to link to the enum, prefix with `enum@` + | +LL | /// Ambiguous non-implied shortcut link [`enum@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 00000000000..34e11c7c7b7 --- /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 00000000000..0d226b27753 --- /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 00000000000..00373fe21de --- /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-item-not-in-scope.rs b/tests/rustdoc-ui/intra-doc/assoc-item-not-in-scope.rs new file mode 100644 index 00000000000..0976515f4a4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/assoc-item-not-in-scope.rs @@ -0,0 +1,22 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +#[derive(Debug)] +/// Link to [`S::fmt`] +//~^ ERROR unresolved link +pub struct S; + +pub mod inner { + use std::fmt::Debug; + use super::S; + + /// Link to [`S::fmt`] + pub fn f() {} +} + +pub mod ambiguous { + use std::fmt::{Display, Debug}; + use super::S; + + /// Link to [`S::fmt`] + pub fn f() {} +} diff --git a/tests/rustdoc-ui/intra-doc/assoc-item-not-in-scope.stderr b/tests/rustdoc-ui/intra-doc/assoc-item-not-in-scope.stderr new file mode 100644 index 00000000000..7ce677e863b --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/assoc-item-not-in-scope.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `S::fmt` + --> $DIR/assoc-item-not-in-scope.rs:4:15 + | +LL | /// Link to [`S::fmt`] + | ^^^^^^ the struct `S` has no field or associated item named `fmt` + | +note: the lint level is defined here + --> $DIR/assoc-item-not-in-scope.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + 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 00000000000..cb656edb5b3 --- /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 00000000000..cfb24fc2c66 --- /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 00000000000..7a11a165723 --- /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 00000000000..d11c69f812a --- /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 00000000000..d11c69f812a --- /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 00000000000..d11c69f812a --- /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 00000000000..d11c69f812a --- /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/in-proc-item-comment.rs b/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs new file mode 100644 index 00000000000..5d3d3c196e1 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/in-proc-item-comment.rs @@ -0,0 +1,20 @@ +//@ force-host +//@ no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +mod view {} + +/// [`view`] +#[proc_macro] +pub fn f(_: TokenStream) -> TokenStream { + todo!() +} + +/// [`f()`] +#[proc_macro] +pub fn g(_: TokenStream) -> TokenStream { + todo!() +} diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-doc.rs b/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-doc.rs new file mode 100644 index 00000000000..15bf51e6f8e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-doc.rs @@ -0,0 +1 @@ +//! Inner doc comment 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 00000000000..31a8310d472 --- /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/issue-103463-aux.rs b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs new file mode 100644 index 00000000000..2b8fdec1f12 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/auxiliary/issue-103463-aux.rs @@ -0,0 +1,4 @@ +pub trait Trait { + /// [`u8::clone`] + fn method(); +} 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 00000000000..0a3dc57f102 --- /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 00000000000..80f0797e83f --- /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/bad-link-to-proc-macro.rs b/tests/rustdoc-ui/intra-doc/bad-link-to-proc-macro.rs new file mode 100644 index 00000000000..b449465768e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/bad-link-to-proc-macro.rs @@ -0,0 +1,21 @@ +//@ compile-flags: --crate-type=proc-macro --document-private-items +#![deny(rustdoc::broken_intra_doc_links)] + +//! Link to [`m`]. +//~^ ERROR `m` is both a module and a macro + +// test a further edge case related to https://github.com/rust-lang/rust/issues/91274 + +// we need to make sure that when there is actually an ambiguity +// in a proc-macro crate, we print out a sensible error. +// because proc macro crates can't normally export modules, +// this can only happen in --document-private-items mode. + +extern crate proc_macro; + +mod m {} + +#[proc_macro] +pub fn m(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} diff --git a/tests/rustdoc-ui/intra-doc/bad-link-to-proc-macro.stderr b/tests/rustdoc-ui/intra-doc/bad-link-to-proc-macro.stderr new file mode 100644 index 00000000000..09a5d26eded --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/bad-link-to-proc-macro.stderr @@ -0,0 +1,22 @@ +error: `m` is both a module and a macro + --> $DIR/bad-link-to-proc-macro.rs:4:15 + | +LL | //! Link to [`m`]. + | ^ ambiguous link + | +note: the lint level is defined here + --> $DIR/bad-link-to-proc-macro.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the module, prefix with `mod@` + | +LL | //! Link to [`mod@m`]. + | ++++ +help: to link to the macro, add an exclamation mark + | +LL | //! Link to [`m!`]. + | + + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.rs b/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.rs new file mode 100644 index 00000000000..b88a52fb80f --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.rs @@ -0,0 +1,16 @@ +// Test that we don't ICE with broken links that don't show up in the docs. + +//@ check-pass +//@ edition: 2021 + +/// [1] +//~^ WARN unresolved link to `1` +//~| WARN unresolved link to `1` +pub use {std, core}; + +/// [2] +pub use {}; + +/// [3] +//~^ WARN unresolved link to `3` +pub extern crate alloc; diff --git a/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr b/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr new file mode 100644 index 00000000000..b25849f25b4 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/broken-link-in-unused-doc-string.stderr @@ -0,0 +1,28 @@ +warning: unresolved link to `3` + --> $DIR/broken-link-in-unused-doc-string.rs:14:6 + | +LL | /// [3] + | ^ no item named `3` 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 `1` + --> $DIR/broken-link-in-unused-doc-string.rs:6:6 + | +LL | /// [1] + | ^ no item named `1` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `1` + --> $DIR/broken-link-in-unused-doc-string.rs:6:6 + | +LL | /// [1] + | ^ no item named `1` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: 3 warnings emitted + 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 00000000000..233396fbdda --- /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 00000000000..ceecfa6816c --- /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 00000000000..5dc61017960 --- /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 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/deny-intra-link-resolution-failure.rs b/tests/rustdoc-ui/intra-doc/deny-intra-link-resolution-failure.rs new file mode 100644 index 00000000000..09da124b162 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deny-intra-link-resolution-failure.rs @@ -0,0 +1,4 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// [v2] //~ ERROR +pub fn foo() {} diff --git a/tests/rustdoc-ui/intra-doc/deny-intra-link-resolution-failure.stderr b/tests/rustdoc-ui/intra-doc/deny-intra-link-resolution-failure.stderr new file mode 100644 index 00000000000..ace20a5fe97 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deny-intra-link-resolution-failure.stderr @@ -0,0 +1,15 @@ +error: unresolved link to `v2` + --> $DIR/deny-intra-link-resolution-failure.rs:3:6 + | +LL | /// [v2] + | ^^ no item named `v2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/deny-intra-link-resolution-failure.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 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 00000000000..f63a9e87497 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.rs @@ -0,0 +1,97 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined +pub enum S { + A, +} +fn S() {} + +#[macro_export] +macro_rules! m { + () => {}; +} + +static s: usize = 0; +const c: usize = 0; + +trait T {} + +struct X { + y: usize, +} + +/// 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@` + +/// Link to [method@X::y] +//~^ ERROR incompatible link kind for `X::y` +//~| NOTE this link resolved +//~| HELP prefix with `field@` + +/// Link to [field@S::A] +//~^ ERROR unresolved link to `S::A` +//~| NOTE this link resolves +//~| HELP prefix with `variant@` +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 00000000000..3bba27e593c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr @@ -0,0 +1,186 @@ +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:22: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 [struct@S] +LL + /// Link to [enum@S] + | + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:27: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 [mod@S] +LL + /// Link to [enum@S] + | + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:32: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 [union@S] +LL + /// Link to [enum@S] + | + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:37: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 [trait@S] +LL + /// Link to [enum@S] + | + +error: incompatible link kind for `T` + --> $DIR/disambiguator-mismatch.rs:42: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 [struct@T] +LL + /// Link to [trait@T] + | + +error: incompatible link kind for `m` + --> $DIR/disambiguator-mismatch.rs:47: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:52:14 + | +LL | /// Link to [m()] + | ^^^ this link resolves to the macro `m`, which is not a function + | +help: to link to the macro, add an exclamation mark + | +LL | /// Link to [m!()] + | + + +error: incompatible link kind for `s` + --> $DIR/disambiguator-mismatch.rs:58: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 [const@s] +LL + /// Link to [static@s] + | + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:63: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 [static@c] +LL + /// Link to [const@c] + | + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:68: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 [fn@c] +LL + /// Link to [const@c] + | + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:73: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:78: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:83:14 + | +LL | /// Link to [fn@std] + | ^^^^^^ this link resolves to the crate `std`, which is not a function + | +help: to link to the crate, prefix with `mod@` + | +LL - /// Link to [fn@std] +LL + /// Link to [mod@std] + | + +error: incompatible link kind for `X::y` + --> $DIR/disambiguator-mismatch.rs:88:14 + | +LL | /// Link to [method@X::y] + | ^^^^^^^^^^^ this link resolved to a field, which is not a function + | +help: to link to the field, prefix with `field@` + | +LL - /// Link to [method@X::y] +LL + /// Link to [field@X::y] + | + +error: unresolved link to `S::A` + --> $DIR/disambiguator-mismatch.rs:93:14 + | +LL | /// Link to [field@S::A] + | ^^^^^^^^^^ this link resolves to the variant `A`, which is not a field + | +help: to link to the variant, prefix with `variant@` + | +LL - /// Link to [field@S::A] +LL + /// Link to [variant@S::A] + | + +error: aborting due to 15 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 00000000000..ceb74c25af2 --- /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 00000000000..6addb010e07 --- /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 00000000000..3faff8a3cca --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -0,0 +1,7 @@ +//@ normalize-stderr: "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/empty-associated-items.rs b/tests/rustdoc-ui/intra-doc/empty-associated-items.rs new file mode 100644 index 00000000000..ea94cb349ad --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/empty-associated-items.rs @@ -0,0 +1,8 @@ +// This test ensures that an empty associated item will not crash rustdoc. +// This is a regression test for <https://github.com/rust-lang/rust/issues/140026>. + +#[deny(rustdoc::broken_intra_doc_links)] + +/// [`String::`] +//~^ ERROR +pub struct Foo; diff --git a/tests/rustdoc-ui/intra-doc/empty-associated-items.stderr b/tests/rustdoc-ui/intra-doc/empty-associated-items.stderr new file mode 100644 index 00000000000..b0527916ab5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/empty-associated-items.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `String::` + --> $DIR/empty-associated-items.rs:6:7 + | +LL | /// [`String::`] + | ^^^^^^^^ the struct `String` has no field or associated item named `` + | +note: the lint level is defined here + --> $DIR/empty-associated-items.rs:4:8 + | +LL | #[deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/errors.rs b/tests/rustdoc-ui/intra-doc/errors.rs new file mode 100644 index 00000000000..e885a3b35f6 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/errors.rs @@ -0,0 +1,121 @@ +#![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 primitive type `u8` has no associated item named `not_found` + +/// [std::primitive::u8::not_found] +//~^ ERROR unresolved link +//~| NOTE the primitive 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 a function +#[macro_export] +macro_rules! m { + () => {}; +} + +///[`TestEnum::Variant1::field_name`] +//~^ ERROR unresolved link +//~| NOTE variant `Variant1` has no such field +pub enum TestEnum { + Variant1 {}, + Variant2 { field_name: u64 }, +} + +///[`TestEnumNoFields::Variant1::field_name`] +//~^ ERROR unresolved link +//~| NOTE `Variant1` is a variant, not a module or type, and cannot have associated items +pub enum TestEnumNoFields { + Variant1 (), + Variant2 {}, +} diff --git a/tests/rustdoc-ui/intra-doc/errors.stderr b/tests/rustdoc-ui/intra-doc/errors.stderr new file mode 100644 index 00000000000..07d328f99a3 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/errors.stderr @@ -0,0 +1,169 @@ +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 primitive 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 primitive 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 a macro + | +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 `TestEnum::Variant1::field_name` + --> $DIR/errors.rs:107:6 + | +LL | ///[`TestEnum::Variant1::field_name`] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variant `Variant1` has no such field + +error: unresolved link to `TestEnumNoFields::Variant1::field_name` + --> $DIR/errors.rs:115:6 + | +LL | ///[`TestEnumNoFields::Variant1::field_name`] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Variant1` is a variant, not a module or type, and cannot have associated items + +error: unresolved link to `m` + --> $DIR/errors.rs:98:6 + | +LL | /// [m()] + | ^^^ this link resolves to the macro `m`, which is not a function + | +help: to link to the macro, add an exclamation mark + | +LL | /// [m!()] + | + + +error: aborting due to 22 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 00000000000..df32f556e73 --- /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 00000000000..3cfac942ca8 --- /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 00000000000..1245bc15bb0 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr @@ -0,0 +1,25 @@ +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: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = 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: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = 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 00000000000..1ba865b53c2 --- /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, prefix with `field@` +//~|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 00000000000..7321c87b790 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/field-ice.stderr @@ -0,0 +1,19 @@ +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, prefix with `field@` + | +LL - /// [`Foo::bar()`] +LL + /// [`field@Foo::bar`] + | + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs new file mode 100644 index 00000000000..9d8edbf6b5d --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs @@ -0,0 +1,15 @@ +// This test ensures that ambiguities (not) resolved at a later stage still emit an error. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +#[doc(hidden)] +pub struct Thing {} + +#[allow(non_snake_case)] +#[doc(hidden)] +pub fn Thing() {} + +/// Do stuff with [`Thing`]. +//~^ ERROR all items matching `Thing` are private or doc(hidden) +pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr new file mode 100644 index 00000000000..1a49c90a172 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr @@ -0,0 +1,14 @@ +error: all items matching `Thing` are private or doc(hidden) + --> $DIR/filter-out-private-2.rs:13:21 + | +LL | /// Do stuff with [`Thing`]. + | ^^^^^ unresolved link + | +note: the lint level is defined here + --> $DIR/filter-out-private-2.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private.rs b/tests/rustdoc-ui/intra-doc/filter-out-private.rs new file mode 100644 index 00000000000..f481b51dad0 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private.rs @@ -0,0 +1,13 @@ +// This test ensures that ambiguities resolved at a later stage still emit an error. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Thing {} + +#[allow(non_snake_case)] +pub fn Thing() {} + +/// Do stuff with [`Thing`]. +//~^ ERROR `Thing` is both a function and a struct +pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private.stderr new file mode 100644 index 00000000000..1d1830b1f1c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private.stderr @@ -0,0 +1,22 @@ +error: `Thing` is both a function and a struct + --> $DIR/filter-out-private.rs:11:21 + | +LL | /// Do stuff with [`Thing`]. + | ^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/filter-out-private.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the function, add parentheses + | +LL | /// Do stuff with [`Thing()`]. + | ++ +help: to link to the struct, prefix with `struct@` + | +LL | /// Do stuff with [`struct@Thing`]. + | +++++++ + +error: aborting due to 1 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 00000000000..4064475355f --- /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 00000000000..02379cd6cdf --- /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 00000000000..b5470c859fd --- /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 00000000000..7c81044dbf8 --- /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/ice-extern-trait-local-impl-104145.rs b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs new file mode 100644 index 00000000000..0e403b21c8a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ice-extern-trait-local-impl-104145.rs @@ -0,0 +1,17 @@ +// https://github.com/rust-lang/rust/issues/104145 +//@ check-pass + +// Doc links in `Trait`'s methods are resolved because it has a local impl. + +//@ aux-build:issue-103463-aux.rs + +extern crate issue_103463_aux; +use issue_103463_aux::Trait; + +pub struct LocalType; + +impl Trait for LocalType { + fn method() {} +} + +fn main() {} diff --git a/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs new file mode 100644 index 00000000000..10894282e55 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/ice-priv-use-103463.rs @@ -0,0 +1,11 @@ +// https://github.com/rust-lang/rust/issues/103463 +//@ check-pass + +// The `Trait` is not pulled into the crate resulting in doc links in its methods being resolved. + +//@ aux-build:issue-103463-aux.rs + +extern crate issue_103463_aux; +use issue_103463_aux::Trait; + +fn main() {} diff --git a/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs b/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs new file mode 100644 index 00000000000..bcfb790e55f --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs @@ -0,0 +1,11 @@ +// Test for issue #108501. +// Module parent scope doesn't hijack import's parent scope for the import's doc links. + +//@ check-pass +//@ aux-build: inner-crate-doc.rs +//@ compile-flags: --extern inner_crate_doc +//@ edition: 2018 + +/// Import doc comment [inner_crate_doc] +#[doc(inline)] +pub use inner_crate_doc; diff --git a/tests/rustdoc-ui/intra-doc/import-inline-merge.rs b/tests/rustdoc-ui/intra-doc/import-inline-merge.rs new file mode 100644 index 00000000000..9307ec23b1e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/import-inline-merge.rs @@ -0,0 +1,16 @@ +// Import for `A` is inlined and doc comments on the import and `A` itself are merged. +// After the merge they still have correct parent scopes to resolve both `[A]` and `[B]`. + +//@ check-pass + +#![allow(rustdoc::private_intra_doc_links)] + +mod m { + /// [B] + pub struct A {} + + pub struct B {} +} + +/// [A] +pub use m::A; 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 00000000000..3088bcd4653 --- /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 00000000000..2818b6b4bba --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr @@ -0,0 +1,19 @@ +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 - //! [static@u8::MIN] +LL + //! [const@u8::MIN] + | + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs new file mode 100644 index 00000000000..23dd8a140bf --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs @@ -0,0 +1,22 @@ +// This test ensures that this warning doesn't show up: +// warning: `PartialEq` is both a trait and a derive macro +// --> tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs:1:7 +// | +// 1 | //! [`PartialEq`] +// | ^^^^^^^^^ ambiguous link +// | +// = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default +// help: to link to the trait, prefix with `trait@` +// | +// 1 | //! [`trait@PartialEq`] +// | ++++++ +// help: to link to the derive macro, prefix with `derive@` +// | +// 1 | //! [`derive@PartialEq`] +// | +++++++ + +//@ check-pass + +#![deny(rustdoc::broken_intra_doc_links)] + +//! [`PartialEq`] diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-2.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-2.rs new file mode 100644 index 00000000000..cbe60f746b6 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-2.rs @@ -0,0 +1,17 @@ +// This is ensuring that the UI output for associated items is as expected. + +#![deny(rustdoc::broken_intra_doc_links)] + +/// [`Trait::IDENT`] +//~^ ERROR both an associated constant and an associated type +pub trait Trait { + type IDENT; + const IDENT: usize; +} + +/// [`Trait2::IDENT`] +//~^ ERROR both an associated function and an associated type +pub trait Trait2 { + type IDENT; + fn IDENT() {} +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-2.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-2.stderr new file mode 100644 index 00000000000..952392548da --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-2.stderr @@ -0,0 +1,37 @@ +error: `Trait::IDENT` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items-2.rs:5:7 + | +LL | /// [`Trait::IDENT`] + | ^^^^^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-2.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@Trait::IDENT`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Trait::IDENT`] + | +++++ + +error: `Trait2::IDENT` is both an associated function and an associated type + --> $DIR/issue-108653-associated-items-2.rs:12:7 + | +LL | /// [`Trait2::IDENT`] + | ^^^^^^^^^^^^^ ambiguous link + | +help: to link to the associated function, add parentheses + | +LL | /// [`Trait2::IDENT()`] + | ++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Trait2::IDENT`] + | +++++ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-3.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-3.rs new file mode 100644 index 00000000000..7ffd0a40e7c --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-3.rs @@ -0,0 +1,16 @@ +// This is ensuring that the UI output for associated items works when it's being documented +// from another item. + +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(nonstandard_style)] + +pub trait Trait { + type Trait; + const Trait: usize; +} + +/// [`Trait`] +//~^ ERROR both a constant and a trait +/// [`Trait::Trait`] +//~^ ERROR both an associated constant and an associated type +pub const Trait: usize = 0; diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-3.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-3.stderr new file mode 100644 index 00000000000..6401dacb57a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-3.stderr @@ -0,0 +1,37 @@ +error: `Trait` is both a constant and a trait + --> $DIR/issue-108653-associated-items-3.rs:12:7 + | +LL | /// [`Trait`] + | ^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-3.rs:4:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the constant, prefix with `const@` + | +LL | /// [`const@Trait`] + | ++++++ +help: to link to the trait, prefix with `trait@` + | +LL | /// [`trait@Trait`] + | ++++++ + +error: `Trait::Trait` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items-3.rs:14:7 + | +LL | /// [`Trait::Trait`] + | ^^^^^^^^^^^^ ambiguous link + | +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@Trait::Trait`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Trait::Trait`] + | +++++ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-4.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-4.rs new file mode 100644 index 00000000000..537d61364bb --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-4.rs @@ -0,0 +1,21 @@ +// This is ensuring that the UI output for associated items works when it's being documented +// from another item. + +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(nonstandard_style)] + +pub trait Trait { + type Trait; +} + +/// [`Struct::Trait`] +//~^ ERROR both an associated constant and an associated type +pub struct Struct; + +impl Trait for Struct { + type Trait = Struct; +} + +impl Struct { + pub const Trait: usize = 0; +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-4.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-4.stderr new file mode 100644 index 00000000000..9d16219be2f --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-4.stderr @@ -0,0 +1,22 @@ +error: `Struct::Trait` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items-4.rs:11:7 + | +LL | /// [`Struct::Trait`] + | ^^^^^^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-4.rs:4:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@Struct::Trait`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Struct::Trait`] + | +++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-5.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-5.rs new file mode 100644 index 00000000000..bc28bc54421 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-5.rs @@ -0,0 +1,8 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(nonstandard_style)] + +/// [`u32::MAX`] +//~^ ERROR both an associated constant and a trait +pub mod u32 { + pub trait MAX {} +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-5.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-5.stderr new file mode 100644 index 00000000000..f7dabed2979 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-5.stderr @@ -0,0 +1,22 @@ +error: `u32::MAX` is both an associated constant and a trait + --> $DIR/issue-108653-associated-items-5.rs:4:7 + | +LL | /// [`u32::MAX`] + | ^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-5.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@u32::MAX`] + | ++++++ +help: to link to the trait, prefix with `trait@` + | +LL | /// [`trait@u32::MAX`] + | ++++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-6.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-6.rs new file mode 100644 index 00000000000..8fde74d0ddb --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-6.rs @@ -0,0 +1,8 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(nonstandard_style)] + +/// [`u32::MAX`] +//~^ ERROR both an associated constant and a primitive type +pub mod u32 { + pub use std::primitive::u32 as MAX; +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-6.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-6.stderr new file mode 100644 index 00000000000..baf23e94f45 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-6.stderr @@ -0,0 +1,22 @@ +error: `u32::MAX` is both an associated constant and a primitive type + --> $DIR/issue-108653-associated-items-6.rs:4:7 + | +LL | /// [`u32::MAX`] + | ^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-6.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@u32::MAX`] + | ++++++ +help: to link to the primitive type, prefix with `prim@` + | +LL | /// [`prim@u32::MAX`] + | +++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-7.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-7.rs new file mode 100644 index 00000000000..6e99f4365a7 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-7.rs @@ -0,0 +1,12 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(nonstandard_style)] + +pub trait Trait { + type MAX; +} + +/// [`u32::MAX`] +//~^ ERROR both an associated constant and an associated type +impl Trait for u32 { + type MAX = u32; +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-7.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-7.stderr new file mode 100644 index 00000000000..54235275476 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-7.stderr @@ -0,0 +1,22 @@ +error: `u32::MAX` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items-7.rs:8:7 + | +LL | /// [`u32::MAX`] + | ^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-7.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@u32::MAX`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@u32::MAX`] + | +++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-8.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-8.rs new file mode 100644 index 00000000000..2f8ee1566bd --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-8.rs @@ -0,0 +1,12 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(nonstandard_style)] + +/// [`u32::MAX`] +//~^ ERROR both an associated constant and an associated type +pub trait T { + type MAX; +} + +impl T for u32 { + type MAX = (); +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-8.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-8.stderr new file mode 100644 index 00000000000..a2641c25170 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-8.stderr @@ -0,0 +1,22 @@ +error: `u32::MAX` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items-8.rs:4:7 + | +LL | /// [`u32::MAX`] + | ^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items-8.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@u32::MAX`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@u32::MAX`] + | +++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-9.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-9.rs new file mode 100644 index 00000000000..e4c8bcec2d3 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-9.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![deny(warnings)] + +//! [usize::Item] + +pub trait Foo { type Item; } +pub trait Bar { type Item; } + +impl Foo for usize { type Item = u32; } +impl Bar for usize { type Item = i32; } diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items.rs new file mode 100644 index 00000000000..0a393e26d6a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items.rs @@ -0,0 +1,35 @@ +// This is ensuring that the UI output for associated items is as expected. + +#![deny(rustdoc::broken_intra_doc_links)] + +pub enum Enum { + IDENT, +} + +/// [`Self::IDENT`] +//~^ ERROR both an associated function and an associated type +pub trait Trait { + type IDENT; + fn IDENT(); +} + +/// [`Self::IDENT`] +//~^ ERROR both an associated function and a variant +impl Trait for Enum { + type IDENT = usize; + fn IDENT() {} +} + +/// [`Self::IDENT2`] +//~^ ERROR both an associated constant and an associated type +pub trait Trait2 { + type IDENT2; + const IDENT2: usize; +} + +/// [`Self::IDENT2`] +//~^ ERROR both an associated constant and an associated type +impl Trait2 for Enum { + type IDENT2 = usize; + const IDENT2: usize = 0; +} diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items.stderr b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items.stderr new file mode 100644 index 00000000000..9cd855b69ff --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items.stderr @@ -0,0 +1,67 @@ +error: `Self::IDENT` is both an associated function and an associated type + --> $DIR/issue-108653-associated-items.rs:9:7 + | +LL | /// [`Self::IDENT`] + | ^^^^^^^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/issue-108653-associated-items.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated function, add parentheses + | +LL | /// [`Self::IDENT()`] + | ++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Self::IDENT`] + | +++++ + +error: `Self::IDENT2` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items.rs:23:7 + | +LL | /// [`Self::IDENT2`] + | ^^^^^^^^^^^^ ambiguous link + | +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@Self::IDENT2`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Self::IDENT2`] + | +++++ + +error: `Self::IDENT` is both an associated function and a variant + --> $DIR/issue-108653-associated-items.rs:16:7 + | +LL | /// [`Self::IDENT`] + | ^^^^^^^^^^^ ambiguous link + | +help: to link to the associated function, add parentheses + | +LL | /// [`Self::IDENT()`] + | ++ +help: to link to the variant, prefix with `variant@` + | +LL | /// [`variant@Self::IDENT`] + | ++++++++ + +error: `Self::IDENT2` is both an associated constant and an associated type + --> $DIR/issue-108653-associated-items.rs:30:7 + | +LL | /// [`Self::IDENT2`] + | ^^^^^^^^^^^^ ambiguous link + | +help: to link to the associated constant, prefix with `const@` + | +LL | /// [`const@Self::IDENT2`] + | ++++++ +help: to link to the associated type, prefix with `type@` + | +LL | /// [`type@Self::IDENT2`] + | +++++ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs new file mode 100644 index 00000000000..ef9c56f7592 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs @@ -0,0 +1,6 @@ +// this test used to ICE +#![deny(rustdoc::broken_intra_doc_links)] +//! [Clone ()]. //~ ERROR unresolved +//! [Clone !]. //~ ERROR incompatible +//! [`Clone ()`]. //~ ERROR unresolved +//! [`Clone !`]. //~ ERROR incompatible diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr new file mode 100644 index 00000000000..a347044bfe9 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr @@ -0,0 +1,55 @@ +error: unresolved link to `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:3:6 + | +LL | //! [Clone ()]. + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +note: the lint level is defined here + --> $DIR/issue-110495-suffix-with-space.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the trait, prefix with `trait@` + | +LL - //! [Clone ()]. +LL + //! [trait@Clone ]. + | + +error: incompatible link kind for `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:4:6 + | +LL | //! [Clone !]. + | ^^^^^^^ this link resolved to a derive macro, which is not a macro + | +help: to link to the derive macro, prefix with `derive@` + | +LL - //! [Clone !]. +LL + //! [derive@Clone ]. + | + +error: unresolved link to `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:5:7 + | +LL | //! [`Clone ()`]. + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - //! [`Clone ()`]. +LL + //! [`trait@Clone `]. + | + +error: incompatible link kind for `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:6:7 + | +LL | //! [`Clone !`]. + | ^^^^^^^ this link resolved to a derive macro, which is not a macro + | +help: to link to the derive macro, prefix with `derive@` + | +LL - //! [`Clone !`]. +LL + //! [`derive@Clone `]. + | + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs new file mode 100644 index 00000000000..4e74278dc7b --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.rs @@ -0,0 +1,10 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/111189>. +// This test ensures that it doesn't crash. + +#![deny(warnings)] + +/// #[rustfmt::skip] +//~^ ERROR unresolved link to `rustfmt::skip` +/// #[clippy::whatever] +//~^ ERROR unresolved link to `clippy::whatever` +pub fn foo() {} diff --git a/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr new file mode 100644 index 00000000000..edd3dfa7d7e --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-111189-resolution-ice.stderr @@ -0,0 +1,21 @@ +error: unresolved link to `rustfmt::skip` + --> $DIR/issue-111189-resolution-ice.rs:6:7 + | +LL | /// #[rustfmt::skip] + | ^^^^^^^^^^^^^ no item named `rustfmt` in scope + | +note: the lint level is defined here + --> $DIR/issue-111189-resolution-ice.rs:4:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` + +error: unresolved link to `clippy::whatever` + --> $DIR/issue-111189-resolution-ice.rs:8:7 + | +LL | /// #[clippy::whatever] + | ^^^^^^^^^^^^^^^^ no item named `clippy` in scope + +error: aborting due to 2 previous errors + 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 00000000000..0c9457c69da --- /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 00000000000..6ad8084b09c --- /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 00000000000..a82a936fe03 --- /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 00000000000..161625ed28c --- /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 00000000000..08349fef88d --- /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 00000000000..587cbad6848 --- /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] +// //~ 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 00000000000..6e08a923963 --- /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 | // + | ^ 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 primitive 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 primitive 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 primitive 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 primitive 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 00000000000..567524438ca --- /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 00000000000..e87ce095cd4 --- /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 primitive type +//~| NOTE ambiguous link +//~| HELP to link to the module +//~| HELP to link to the primitive type + +/// [type@char] +//~^ ERROR both a module and a primitive type +//~| NOTE ambiguous link +//~| HELP to link to the module +//~| HELP to link to the primitive 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 primitive 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 00000000000..c50f6bb9b87 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/prim-conflict.stderr @@ -0,0 +1,63 @@ +error: `char` is both a module and a primitive 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 primitive type, prefix with `prim@` + | +LL | /// [prim@char] + | +++++ + +error: `char` is both a module and a primitive type + --> $DIR/prim-conflict.rs:10:6 + | +LL | /// [type@char] + | ^^^^^^^^^ ambiguous link + | +help: to link to the module, prefix with `mod@` + | +LL - /// [type@char] +LL + /// [mod@char] + | +help: to link to the primitive type, prefix with `prim@` + | +LL - /// [type@char] +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 - /// [struct@char] +LL + /// [mod@char] + | + +error: incompatible link kind for `char` + --> $DIR/prim-conflict.rs:26:10 + | +LL | //! [struct@char] + | ^^^^^^^^^^^ this link resolved to a primitive type, which is not a struct + | +help: to link to the primitive type, prefix with `prim@` + | +LL - //! [struct@char] +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 00000000000..0ec11d86175 --- /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 00000000000..4d5bd70bff6 --- /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 00000000000..6661e9021f8 --- /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 00000000000..45b51e12edc --- /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 00000000000..b1ab0a462aa --- /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/proc-macro-doc.rs b/tests/rustdoc-ui/intra-doc/proc-macro-doc.rs new file mode 100644 index 00000000000..5d6819273b7 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/proc-macro-doc.rs @@ -0,0 +1,27 @@ +//@ check-pass +//@ force-host +//@ no-prefer-dynamic +//@ compile-flags: --crate-type proc-macro + +#![deny(rustdoc::broken_intra_doc_links)] + +extern crate proc_macro; +use proc_macro::*; + +/// [`Unpin`] +#[proc_macro_derive(F)] +pub fn derive_(t: proc_macro::TokenStream) -> proc_macro::TokenStream { + t +} + +/// [`Vec`] +#[proc_macro_attribute] +pub fn attr(t: proc_macro::TokenStream, _: proc_macro::TokenStream) -> proc_macro::TokenStream { + t +} + +/// [`std::fs::File`] +#[proc_macro] +pub fn func(t: proc_macro::TokenStream) -> proc_macro::TokenStream { + t +} diff --git a/tests/rustdoc-ui/intra-doc/pub-export-lint.rs b/tests/rustdoc-ui/intra-doc/pub-export-lint.rs new file mode 100644 index 00000000000..f2e66b77bf3 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/pub-export-lint.rs @@ -0,0 +1,5 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// [aloha] +//~^ ERROR unresolved link to `aloha` +pub use std::task::RawWakerVTable; diff --git a/tests/rustdoc-ui/intra-doc/pub-export-lint.stderr b/tests/rustdoc-ui/intra-doc/pub-export-lint.stderr new file mode 100644 index 00000000000..b037b7933ca --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/pub-export-lint.stderr @@ -0,0 +1,15 @@ +error: unresolved link to `aloha` + --> $DIR/pub-export-lint.rs:3:6 + | +LL | /// [aloha] + | ^^^^^ no item named `aloha` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/pub-export-lint.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/pub-proc-item.rs b/tests/rustdoc-ui/intra-doc/pub-proc-item.rs new file mode 100644 index 00000000000..413efb40b0d --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/pub-proc-item.rs @@ -0,0 +1,8 @@ +//@ aux-build:in-proc-item-comment.rs +//@ check-pass + +// issue#132743 + +extern crate in_proc_item_comment; + +pub use in_proc_item_comment::{f, g}; diff --git a/tests/rustdoc-ui/intra-doc/reachable-non-exported.rs b/tests/rustdoc-ui/intra-doc/reachable-non-exported.rs new file mode 100644 index 00000000000..5eabf3a09ad --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/reachable-non-exported.rs @@ -0,0 +1,13 @@ +// The structure is reachable, but not exported, so rustdoc +// doesn't attempt to request doc link resolutions on it. + +//@ check-pass + +mod private { + /// [core::str::FromStr] + pub struct ReachableButNotExported; +} + +pub fn foo() -> private::ReachableButNotExported { + private::ReachableButNotExported +} diff --git a/tests/rustdoc-ui/intra-doc/reference-link-reports-error-once.rs b/tests/rustdoc-ui/intra-doc/reference-link-reports-error-once.rs new file mode 100644 index 00000000000..71bd2c522ff --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/reference-link-reports-error-once.rs @@ -0,0 +1,20 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// Links to [a] [link][a] +/// And also a [third link][a] +/// And also a [reference link][b] +/// +/// Other links to the same target should still emit error: [ref] //~ERROR unresolved link to `ref` +/// Duplicate [ref] //~ERROR unresolved link to `ref` +/// +/// Other links to other targets should still emit error: [ref2] //~ERROR unresolved link to `ref2` +/// Duplicate [ref2] //~ERROR unresolved link to `ref2` +/// +/// [a]: ref +//~^ ERROR unresolved link to `ref` +/// [b]: ref2 +//~^ ERROR unresolved link to + +/// [ref][] +//~^ ERROR unresolved link +pub fn f() {} diff --git a/tests/rustdoc-ui/intra-doc/reference-link-reports-error-once.stderr b/tests/rustdoc-ui/intra-doc/reference-link-reports-error-once.stderr new file mode 100644 index 00000000000..2ab67090f66 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/reference-link-reports-error-once.stderr @@ -0,0 +1,63 @@ +error: unresolved link to `ref` + --> $DIR/reference-link-reports-error-once.rs:13:10 + | +LL | /// [a]: ref + | ^^^ no item named `ref` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/reference-link-reports-error-once.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `ref2` + --> $DIR/reference-link-reports-error-once.rs:15:10 + | +LL | /// [b]: ref2 + | ^^^^ no item named `ref2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `ref` + --> $DIR/reference-link-reports-error-once.rs:7:62 + | +LL | /// Other links to the same target should still emit error: [ref] + | ^^^ no item named `ref` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `ref` + --> $DIR/reference-link-reports-error-once.rs:8:16 + | +LL | /// Duplicate [ref] + | ^^^ no item named `ref` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `ref2` + --> $DIR/reference-link-reports-error-once.rs:10:60 + | +LL | /// Other links to other targets should still emit error: [ref2] + | ^^^^ no item named `ref2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `ref2` + --> $DIR/reference-link-reports-error-once.rs:11:16 + | +LL | /// Duplicate [ref2] + | ^^^^ no item named `ref2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `ref` + --> $DIR/reference-link-reports-error-once.rs:18:6 + | +LL | /// [ref][] + | ^^^ no item named `ref` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to 7 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/reference-links.rs b/tests/rustdoc-ui/intra-doc/reference-links.rs new file mode 100644 index 00000000000..e81e034465d --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/reference-links.rs @@ -0,0 +1,6 @@ +// Test that errors point to the reference, not to the title text. +#![deny(rustdoc::broken_intra_doc_links)] +//! Links to [a] [link][a] +//! +//! [a]: std::process::Comman +//~^ ERROR unresolved diff --git a/tests/rustdoc-ui/intra-doc/reference-links.stderr b/tests/rustdoc-ui/intra-doc/reference-links.stderr new file mode 100644 index 00000000000..2a30359238a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/reference-links.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `std::process::Comman` + --> $DIR/reference-links.rs:5:10 + | +LL | //! [a]: std::process::Comman + | ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process` + | +note: the lint level is defined here + --> $DIR/reference-links.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + 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 00000000000..041ec293259 --- /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 00000000000..765f26c4845 --- /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 1 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 00000000000..beec9e2833c --- /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 00000000000..508d0683d5d --- /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 00000000000..86b31cb14d8 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -0,0 +1,14 @@ +//@ normalize-stderr: "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 00000000000..741a7f51a77 --- /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 `` + --> $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: 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: 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 00000000000..c71e5bee12e --- /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 00000000000..dcdd230c25a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved_crate` + --> $DIR/unresolved-import-recovery.rs:3:5 + | +LL | use unresolved_crate::module::Name; + | ^^^^^^^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved_crate` + | +help: you might be missing a crate named `unresolved_crate`, add it to your project and import it in your code + | +LL + extern crate unresolved_crate; + | + +error: aborting due to 1 previous error + +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 00000000000..f1f30c2a93d --- /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 00000000000..f9f135a922b --- /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 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/value-ctor.rs b/tests/rustdoc-ui/intra-doc/value-ctor.rs new file mode 100644 index 00000000000..6f57b7c6f10 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/value-ctor.rs @@ -0,0 +1,35 @@ +// https://github.com/rust-lang/rust/issues/130591 +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +/// [value@Foo::X] //~ERROR broken +pub enum Foo { + X, +} + +/// [tst][value@MyStruct] //~ERROR broken +pub struct MyStruct; + +pub enum MyEnum { + Internals, +} + +pub use MyEnum::*; + +/// In this context, [a][type@Internals] is a struct, +/// while [b][value@Internals] fails. //~ERROR broken +/// Also, [c][struct@Internals] is a struct, +/// while [d][variant@Internals] fails. //~ERROR broken +pub struct Internals { + foo: (), +} + +pub mod inside { + pub struct Internals2; +} + +use inside::*; + +/// In this context, [a][type@Internals2] is an enum, +/// while [b][value@Internals2] fails. //~ERROR broken +pub enum Internals2 {} diff --git a/tests/rustdoc-ui/intra-doc/value-ctor.stderr b/tests/rustdoc-ui/intra-doc/value-ctor.stderr new file mode 100644 index 00000000000..cfc2bb67396 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/value-ctor.stderr @@ -0,0 +1,67 @@ +error: unresolved link to `Foo::X` + --> $DIR/value-ctor.rs:5:6 + | +LL | /// [value@Foo::X] + | ^^^^^^^^^^^^ this link resolves to the variant `X`, which is not in the value namespace + | +note: the lint level is defined here + --> $DIR/value-ctor.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the variant, prefix with `variant@` + | +LL - /// [value@Foo::X] +LL + /// [variant@Foo::X] + | + +error: unresolved link to `MyStruct` + --> $DIR/value-ctor.rs:10:11 + | +LL | /// [tst][value@MyStruct] + | ^^^^^^^^^^^^^^ this link resolves to the struct `MyStruct`, which is not in the value namespace + | +help: to link to the struct, prefix with `struct@` + | +LL - /// [tst][value@MyStruct] +LL + /// [tst][struct@MyStruct] + | + +error: unresolved link to `Internals` + --> $DIR/value-ctor.rs:20:15 + | +LL | /// while [b][value@Internals] fails. + | ^^^^^^^^^^^^^^^ this link resolves to the struct `Internals`, which is not in the value namespace + | +help: to link to the struct, prefix with `struct@` + | +LL - /// while [b][value@Internals] fails. +LL + /// while [b][struct@Internals] fails. + | + +error: incompatible link kind for `Internals` + --> $DIR/value-ctor.rs:22:15 + | +LL | /// while [d][variant@Internals] fails. + | ^^^^^^^^^^^^^^^^^ this link resolved to a struct, which is not a variant + | +help: to link to the struct, prefix with `struct@` + | +LL - /// while [d][variant@Internals] fails. +LL + /// while [d][struct@Internals] fails. + | + +error: unresolved link to `Internals2` + --> $DIR/value-ctor.rs:34:15 + | +LL | /// while [b][value@Internals2] fails. + | ^^^^^^^^^^^^^^^^ this link resolves to the enum `Internals2`, which is not in the value namespace + | +help: to link to the enum, prefix with `enum@` + | +LL - /// while [b][value@Internals2] fails. +LL + /// while [b][enum@Internals2] fails. + | + +error: aborting due to 5 previous errors + 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 00000000000..9d3a4673c9d --- /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 00000000000..c309a55f44d --- /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 00000000000..ed51b2fa41b --- /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] + pub fn f() {} + } +} +f!("Foo\nbar [BarF] bar\nbaz"); //~ WARNING `BarF` + +/** # 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 00000000000..9b3f6f822d7 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/warning.stderr @@ -0,0 +1,152 @@ +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:20 + | +LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] + | ^^^^ no item named `BarD` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarF` + --> $DIR/warning.rs:54:15 + | +LL | f!("Foo\nbar [BarF] bar\nbaz"); + | ^^^^ 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:23 + | +LL | #[doc = "single line [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:71:41 + | +LL | #[doc = "single line with \"escaping\" [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: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 + diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.rs b/tests/rustdoc-ui/intra-doc/weird-syntax.rs new file mode 100644 index 00000000000..d2a922b2b62 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.rs @@ -0,0 +1,165 @@ +// Many examples are from +// https://github.com/rust-lang/rust/issues/110111#issuecomment-1517800781 +#![deny(rustdoc::broken_intra_doc_links)] + +//! This test case is closely linked to [raphlinus/pulldown-cmark#441], getting offsets of +//! link components. In particular, pulldown-cmark doesn't provide the offsets of the contents +//! of a link. +//! +//! To work around this, rustdoc parses parts of a link definition itself. This is basically a +//! test suite for that link syntax parser. +//! +//! [raphlinus/pulldown-cmark#441]: https://github.com/raphlinus/pulldown-cmark/issues/441 + +use std::clone::Clone; + +// Basic version // + +/// [`struct@Clone`] //~ERROR link +pub struct LinkToCloneWithBackquotes; + +/// [```struct@Clone```] //~ERROR link +pub struct LinkToCloneWithMultipleBackquotes; + +/// [ ` struct@Clone ` ] //~ERROR link +pub struct LinkToCloneWithSpacesAndBackquotes; + +/// [ `Clone ()` ] //~ERROR link +pub struct LinkToCloneWithSpacesBackquotesAndParens; + +/// [`Clone ()` ] //~ERROR link +pub struct LinkToCloneWithSpacesEndBackquotesAndParens; + +/// [ `Clone ()`] //~ERROR link +pub struct LinkToCloneWithSpacesStartBackquotesAndParens; + +/// [```Clone ()```] //~ERROR link +pub struct LinkToCloneWithMultipleBackquotesAndParens; + +/// [```Clone \(\)```] // not URL-shaped enough +pub struct LinkToCloneWithMultipleBackquotesAndEscapedParens; + +/// [ ``` Clone () ``` ] //~ERROR link +pub struct LinkToCloneWithSpacesMultipleBackquotesAndParens; + +/// [ x \] ] // not URL-shaped enough +pub struct LinkWithEscapedCloseBrace; + +/// [ x \[ ] // not URL-shaped enough +pub struct LinkWithEscapedOpenBrace; + +/// [ x \( ] // not URL-shaped enough +pub struct LinkWithEscapedCloseParen; + +/// [ x \) ] // not URL-shaped enough +pub struct LinkWithEscapedOpenParen; + +/// [ Clone \(\) ] // not URL-shaped enough +pub struct LinkWithEscapedParens; + +// [][] version // + +/// [x][ struct@Clone] //~ERROR link +pub struct XLinkToCloneWithStartSpace; + +/// [x][struct@Clone ] //~ERROR link +pub struct XLinkToCloneWithEndSpace; + +/// [x][Clone\(\)] not URL-shaped enough +pub struct XLinkToCloneWithEscapedParens; + +/// [x][`Clone`] not URL-shaped enough +pub struct XLinkToCloneWithBackquotes; + +/// [x][Clone()] //~ERROR link +pub struct XLinkToCloneWithUnescapedParens; + +/// [x][Clone ()] //~ERROR link +pub struct XLinkToCloneWithUnescapedParensAndDoubleSpace; + +/// [x][Clone [] //~ERROR unresolved link to `x` +pub struct XLinkToCloneWithUnmatchedOpenParenAndDoubleSpace; + +/// [x][Clone \[] // not URL-shaped enough +pub struct XLinkToCloneWithUnmatchedEscapedOpenParenAndDoubleSpace; + +/// [x][Clone \]] // not URL-shaped enough +pub struct XLinkToCloneWithUnmatchedEscapedCloseParenAndDoubleSpace; + +// []() version // + +/// [w]( struct@Clone) //~ERROR link +pub struct WLinkToCloneWithStartSpace; + +/// [w](struct@Clone ) //~ERROR link +pub struct WLinkToCloneWithEndSpace; + +/// [w](Clone\(\)) //~ERROR link +pub struct WLinkToCloneWithEscapedParens; + +/// [w](`Clone`) not URL-shaped enough +pub struct WLinkToCloneWithBackquotes; + +/// [w](Clone()) //~ERROR link +pub struct WLinkToCloneWithUnescapedParens; + +/// [w](Clone ()) not URL-shaped enough +pub struct WLinkToCloneWithUnescapedParensAndDoubleSpace; + +/// [w](Clone () //~ERROR unresolved link to `w` +pub struct WLinkToCloneWithUnmatchedOpenParenAndDoubleSpace; + +/// [w](Clone \() //~ERROR unresolved link to `w` +pub struct WLinkToCloneWithUnmatchedEscapedOpenParenAndDoubleSpace; + +/// [w](Clone \)) //~ERROR unresolved link to `w` +pub struct WLinkToCloneWithUnmatchedEscapedCloseParenAndDoubleSpace; + +// References + +/// The [cln][] link here is going to be unresolved, because `Clone()` gets +//~^ ERROR link +/// rejected in Markdown for not being URL-shaped enough. +/// [cln]: Clone() +//~^ ERROR link +pub struct LinkToCloneWithParensInReference; + +/// The [cln][] link here is going to produce a good inline suggestion +/// +/// [cln]: struct@Clone +//~^ ERROR link +pub struct LinkToCloneWithWrongPrefix; + +/// The [cln][] link here will produce a good inline suggestion +/// +/// [cln]: Clone\(\) +//~^ ERROR link +pub struct LinkToCloneWithEscapedParensInReference; + +/// The [cln][] link here will produce a good inline suggestion +/// +/// [cln]: struct\@Clone +//~^ ERROR link +pub struct LinkToCloneWithEscapedAtsInReference; + + +/// This link reference definition isn't used, but since it is still parsed, +/// it should still produce a warning. +/// +/// [cln]: struct\@Clone +//~^ ERROR link +pub struct UnusedLinkToCloneReferenceDefinition; + +/// <https://github.com/rust-lang/rust/issues/133150> +/// +/// - [`SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER`]: the +//~^ ERROR link +/// `(__unsafe_unretained)` NSWindow associated with the window, if you want +/// to wrap an existing window. +/// - [`SDL_PROP_WINDOW_CREATE_COCOA_VIEW_POINTER`]: the `(__unsafe_unretained)` +/// NSView associated with the window, defaults to `[window contentView]` +pub fn a() {} +#[allow(nonstandard_style)] +pub struct SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER; +#[allow(nonstandard_style)] +pub struct SDL_PROP_WINDOW_CREATE_COCOA_VIEW_POINTER; diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr new file mode 100644 index 00000000000..ad813f0f9b6 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr @@ -0,0 +1,303 @@ +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:18:7 + | +LL | /// [`struct@Clone`] + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +note: the lint level is defined here + --> $DIR/weird-syntax.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the trait, prefix with `trait@` + | +LL - /// [`struct@Clone`] +LL + /// [`trait@Clone`] + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:21:9 + | +LL | /// [```struct@Clone```] + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [```struct@Clone```] +LL + /// [```trait@Clone```] + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:24:11 + | +LL | /// [ ` struct@Clone ` ] + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [ ` struct@Clone ` ] +LL + /// [ ` trait@Clone ` ] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:27:9 + | +LL | /// [ `Clone ()` ] + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [ `Clone ()` ] +LL + /// [ `trait@Clone ` ] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:30:7 + | +LL | /// [`Clone ()` ] + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [`Clone ()` ] +LL + /// [`trait@Clone ` ] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:33:9 + | +LL | /// [ `Clone ()`] + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [ `Clone ()`] +LL + /// [ `trait@Clone `] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:36:9 + | +LL | /// [```Clone ()```] + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [```Clone ()```] +LL + /// [```trait@Clone ```] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:42:13 + | +LL | /// [ ``` Clone () ``` ] + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [ ``` Clone () ``` ] +LL + /// [ ``` trait@Clone ``` ] + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:62:10 + | +LL | /// [x][ struct@Clone] + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [x][ struct@Clone] +LL + /// [x][ trait@Clone] + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:65:9 + | +LL | /// [x][struct@Clone ] + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [x][struct@Clone ] +LL + /// [x][trait@Clone ] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:74:9 + | +LL | /// [x][Clone()] + | ^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [x][Clone()] +LL + /// [x][trait@Clone] + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:77:9 + | +LL | /// [x][Clone ()] + | ^^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [x][Clone ()] +LL + /// [x][trait@Clone ] + | + +error: unresolved link to `x` + --> $DIR/weird-syntax.rs:80:6 + | +LL | /// [x][Clone [] + | ^ no item named `x` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:91:10 + | +LL | /// [w]( struct@Clone) + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [w]( struct@Clone) +LL + /// [w]( trait@Clone) + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:94:9 + | +LL | /// [w](struct@Clone ) + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [w](struct@Clone ) +LL + /// [w](trait@Clone ) + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:97:9 + | +LL | /// [w](Clone\(\)) + | ^^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [w](Clone\(\)) +LL + /// [w](trait@Clone) + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:103:9 + | +LL | /// [w](Clone()) + | ^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [w](Clone()) +LL + /// [w](trait@Clone) + | + +error: unresolved link to `w` + --> $DIR/weird-syntax.rs:109:6 + | +LL | /// [w](Clone () + | ^ no item named `w` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `w` + --> $DIR/weird-syntax.rs:112:6 + | +LL | /// [w](Clone \() + | ^ no item named `w` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `w` + --> $DIR/weird-syntax.rs:115:6 + | +LL | /// [w](Clone \)) + | ^ no item named `w` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `cln` + --> $DIR/weird-syntax.rs:120:10 + | +LL | /// The [cln][] link here is going to be unresolved, because `Clone()` gets + | ^^^ no item named `cln` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `cln` + --> $DIR/weird-syntax.rs:123:6 + | +LL | /// [cln]: Clone() + | ^^^ no item named `cln` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:129:12 + | +LL | /// [cln]: struct@Clone + | ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [cln]: struct@Clone +LL + /// [cln]: trait@Clone + | + +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:135:12 + | +LL | /// [cln]: Clone\(\) + | ^^^^^^^^^ this link resolves to the trait `Clone`, which is not a function + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [cln]: Clone\(\) +LL + /// [cln]: trait@Clone + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:141:12 + | +LL | /// [cln]: struct\@Clone + | ^^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [cln]: struct\@Clone +LL + /// [cln]: trait@struct + | + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:149:12 + | +LL | /// [cln]: struct\@Clone + | ^^^^^^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL - /// [cln]: struct\@Clone +LL + /// [cln]: trait@struct + | + +error: unresolved link to `the` + --> $DIR/weird-syntax.rs:155:56 + | +LL | /// - [`SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER`]: the + | ^^^ no item named `the` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to 27 previous errors + diff --git a/tests/rustdoc-ui/invalid-cfg.rs b/tests/rustdoc-ui/invalid-cfg.rs new file mode 100644 index 00000000000..d237b8605c0 --- /dev/null +++ b/tests/rustdoc-ui/invalid-cfg.rs @@ -0,0 +1,4 @@ +#![feature(doc_cfg)] +#[doc(cfg = "x")] //~ ERROR not followed by parentheses +#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +struct S {} diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr new file mode 100644 index 00000000000..dae238b052b --- /dev/null +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -0,0 +1,14 @@ +error: `cfg` is not followed by parentheses + --> $DIR/invalid-cfg.rs:2:7 + | +LL | #[doc(cfg = "x")] + | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/invalid-cfg.rs:3:14 + | +LL | #[doc(cfg(x, y))] + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/invalid-keyword.rs b/tests/rustdoc-ui/invalid-keyword.rs new file mode 100644 index 00000000000..2d70471c85e --- /dev/null +++ b/tests/rustdoc-ui/invalid-keyword.rs @@ -0,0 +1,4 @@ +#![feature(rustdoc_internals)] + +#[doc(keyword = "foo df")] //~ ERROR +mod foo {} diff --git a/tests/rustdoc-ui/invalid-keyword.stderr b/tests/rustdoc-ui/invalid-keyword.stderr new file mode 100644 index 00000000000..c1e41d3b0b3 --- /dev/null +++ b/tests/rustdoc-ui/invalid-keyword.stderr @@ -0,0 +1,10 @@ +error: nonexistent keyword `foo df` used in `#[doc(keyword = "...")]` + --> $DIR/invalid-keyword.rs:3:17 + | +LL | #[doc(keyword = "foo df")] + | ^^^^^^^^ + | + = help: only existing keywords are allowed in core/std + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/invalid-redundant-explicit-link.rs b/tests/rustdoc-ui/invalid-redundant-explicit-link.rs new file mode 100644 index 00000000000..99ac1d82aaf --- /dev/null +++ b/tests/rustdoc-ui/invalid-redundant-explicit-link.rs @@ -0,0 +1,8 @@ +//@ check-pass + +// Regression test for <https://github.com/rust-lang/rust/issues/123158>. It +// should not emit any warning. + +//! [**`SomeTrait`**](SomeTrait): + +pub trait SomeTrait {} diff --git a/tests/rustdoc-ui/invalid-syntax.rs b/tests/rustdoc-ui/invalid-syntax.rs new file mode 100644 index 00000000000..3b60239df8d --- /dev/null +++ b/tests/rustdoc-ui/invalid-syntax.rs @@ -0,0 +1,107 @@ +//@ check-pass + +/// ``` +/// \__________pkt->size___________/ \_result->size_/ \__pkt->size__/ +/// ``` +pub fn foo() {} +//~^^^^ WARNING could not parse code block as Rust code + +/// ``` +/// | +/// LL | use foobar::Baz; +/// | ^^^^^^ did you mean `baz::foobar`? +/// ``` +pub fn bar() {} +//~^^^^^^ WARNING could not parse code block as Rust code + +/// ``` +/// valid +/// ``` +/// +/// ``` +/// \_ +/// ``` +/// +/// ```text +/// "invalid +/// ``` +pub fn valid_and_invalid() {} +//~^^^^^^^^ WARNING could not parse code block as Rust code + +/// This is a normal doc comment, but... +/// +/// There's a code block with bad syntax in it: +/// +/// ```rust +/// \_ +/// ``` +/// +/// Good thing we tested it! +pub fn baz() {} +//~^^^^^^ WARNING could not parse code block as Rust code + +/// Indented block start +/// +/// code with bad syntax +/// \_ +/// +/// Indented block end +pub fn quux() {} +//~^^^^^ WARN could not parse code block as Rust code + +/// Unclosed fence +/// +/// ``` +/// slkdjf +pub fn xyzzy() {} + +/// Indented code that contains a fence +/// +/// ``` +pub fn blah() {} +//~^^ WARNING could not parse code block as Rust code + +/// ```edition2018 +/// \_ +/// ``` +pub fn blargh() {} +//~^^^^ WARNING could not parse code block as Rust code + +#[doc = "```"] +/// \_ +#[doc = "```"] +pub fn crazy_attrs() {} +//~^^^^ WARNING could not parse code block + +/// ```rust +/// ``` +pub fn empty_rust() {} +//~^^^ WARNING Rust code block is empty + +/// ``` +/// +/// +/// ``` +pub fn empty_rust_with_whitespace() {} +//~^^^^^ WARNING Rust code block is empty + +/// ``` +/// let x = 1; +/// ``` +/// +/// \____/ +/// +pub fn indent_after_fenced() {} +//~^^^ WARNING could not parse code block as Rust code + +/// ``` +/// "invalid +/// ``` +pub fn invalid() {} +//~^^^^ WARNING could not parse code block as Rust code + +/// ``` +/// fn wook_at_my_beautifuw_bwaces_plz() {); +/// ``` +pub fn uwu() {} +//~^^^^ WARNING could not parse code block as Rust code diff --git a/tests/rustdoc-ui/invalid-syntax.stderr b/tests/rustdoc-ui/invalid-syntax.stderr new file mode 100644 index 00000000000..c6e1f6fd413 --- /dev/null +++ b/tests/rustdoc-ui/invalid-syntax.stderr @@ -0,0 +1,168 @@ +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:3:5 + | +LL | /// ``` + | _____^ +LL | | /// \__________pkt->size___________/ \_result->size_/ \__pkt->size__/ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: \ + = note: error from rustc: unknown start of token: \ + = note: error from rustc: unknown start of token: \ + = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:9:5 + | +LL | /// ``` + | _____^ +LL | | /// | +LL | | /// LL | use foobar::Baz; +LL | | /// | ^^^^^^ did you mean `baz::foobar`? +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: ` + = note: error from rustc: unknown start of token: ` +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:21:5 + | +LL | /// ``` + | _____^ +LL | | /// \_ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: \ +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:35:5 + | +LL | /// ```rust + | _____^ +LL | | /// \_ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: \ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:45:9 + | +LL | /// code with bad syntax + | _________^ +LL | | /// \_ + | |__________^ + | + = note: error from rustc: unknown start of token: \ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:60:9 + | +LL | /// ``` + | ^^^ + | + = note: error from rustc: unknown start of token: ` + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:64:5 + | +LL | /// ```edition2018 + | _____^ +LL | | /// \_ +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unknown start of token: \ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:70:9 + | +LL | #[doc = "```"] + | _________^ +LL | | /// \_ +LL | | #[doc = "```"] + | |_____________^ + | + = help: mark blocks that do not contain Rust code as text: ```text + = note: error from rustc: unknown start of token: \ + +warning: Rust code block is empty + --> $DIR/invalid-syntax.rs:76:5 + | +LL | /// ```rust + | _____^ +LL | | /// ``` + | |_______^ + +warning: Rust code block is empty + --> $DIR/invalid-syntax.rs:81:5 + | +LL | /// ``` + | _____^ +LL | | /// +LL | | /// +LL | | /// ``` + | |_______^ + | +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:92:9 + | +LL | /// \____/ + | _________^ +LL | | /// + | |_^ + | + = note: error from rustc: unknown start of token: \ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:97:5 + | +LL | /// ``` + | _____^ +LL | | /// "invalid +LL | | /// ``` + | |_______^ + | + = note: error from rustc: unterminated double quote string +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:103:5 + | +LL | /// ``` + | _____^ +LL | | /// fn wook_at_my_beautifuw_bwaces_plz() {); +LL | | /// ``` + | |_______^ + | + = note: error from rustc: mismatched closing delimiter: `)` +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: 13 warnings emitted + diff --git a/tests/rustdoc-ui/invalid-theme-name.rs b/tests/rustdoc-ui/invalid-theme-name.rs new file mode 100644 index 00000000000..22b5e616a3d --- /dev/null +++ b/tests/rustdoc-ui/invalid-theme-name.rs @@ -0,0 +1,4 @@ +//@ compile-flags:--theme {{src-base}}/invalid-theme-name.rs + +//~? ERROR invalid argument: "$DIR/invalid-theme-name.rs" +//~? HELP must have a .css extension diff --git a/tests/rustdoc-ui/invalid-theme-name.stderr b/tests/rustdoc-ui/invalid-theme-name.stderr new file mode 100644 index 00000000000..80204442dbe --- /dev/null +++ b/tests/rustdoc-ui/invalid-theme-name.stderr @@ -0,0 +1,4 @@ +error: invalid argument: "$DIR/invalid-theme-name.rs" + | + = help: arguments to --theme must have a .css extension + diff --git a/tests/rustdoc-ui/invalid_associated_const.rs b/tests/rustdoc-ui/invalid_associated_const.rs new file mode 100644 index 00000000000..f93834268f6 --- /dev/null +++ b/tests/rustdoc-ui/invalid_associated_const.rs @@ -0,0 +1,11 @@ +#![feature(associated_const_equality)] + +trait T { + type A: S<C<X = 0i32> = 34>; + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here +} + +trait S { + const C: i32; +} diff --git a/tests/rustdoc-ui/invalid_associated_const.stderr b/tests/rustdoc-ui/invalid_associated_const.stderr new file mode 100644 index 00000000000..66f8ffe6d72 --- /dev/null +++ b/tests/rustdoc-ui/invalid_associated_const.stderr @@ -0,0 +1,28 @@ +error[E0229]: associated item constraints are not allowed here + --> $DIR/invalid_associated_const.rs:4:17 + | +LL | type A: S<C<X = 0i32> = 34>; + | ^^^^^^^^ associated item constraint not allowed here + | +help: consider removing this associated item binding + | +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | + +error[E0229]: associated item constraints are not allowed here + --> $DIR/invalid_associated_const.rs:4:17 + | +LL | type A: S<C<X = 0i32> = 34>; + | ^^^^^^^^ associated item constraint not allowed here + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider removing this associated item binding + | +LL - type A: S<C<X = 0i32> = 34>; +LL + type A: S<C = 34>; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs new file mode 100644 index 00000000000..427c84679ba --- /dev/null +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs @@ -0,0 +1,11 @@ +trait X { + type Y<'a>; +} +fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} +//~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments +//~| ERROR associated type takes 0 generic arguments but 1 generic argument +//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments +//~| ERROR associated type takes 0 generic arguments but 1 generic argument +//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments +//~| ERROR associated type takes 0 generic arguments but 1 generic argument +//~| ERROR trait `X` is not dyn compatible diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr new file mode 100644 index 00000000000..2c25589a553 --- /dev/null +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr @@ -0,0 +1,114 @@ +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn f<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {} + | +++ + +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^--- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: associated type defined here, with 0 generic parameters + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ + +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | fn f<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {} + | +++ + +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^--- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: associated type defined here, with 0 generic parameters + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | fn f<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {} + | +++ + +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^--- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: associated type defined here, with 0 generic parameters + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0038]: the trait `X` is not dyn compatible + --> $DIR/invalid_const_in_lifetime_position.rs:4:20 + | +LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} + | ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | trait X { + | - this trait is not dyn compatible... +LL | type Y<'a>; + | ^ ...because it contains the generic associated type `Y` + = help: consider moving `Y` to another trait + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/rustdoc-ui/invalid_infered_static_and_const.rs b/tests/rustdoc-ui/invalid_infered_static_and_const.rs new file mode 100644 index 00000000000..3f8e68dc020 --- /dev/null +++ b/tests/rustdoc-ui/invalid_infered_static_and_const.rs @@ -0,0 +1,2 @@ +const FOO: dyn Fn() -> _ = ""; //~ ERROR E0121 +static BOO: dyn Fn() -> _ = ""; //~ ERROR E0121 diff --git a/tests/rustdoc-ui/invalid_infered_static_and_const.stderr b/tests/rustdoc-ui/invalid_infered_static_and_const.stderr new file mode 100644 index 00000000000..3e116826c49 --- /dev/null +++ b/tests/rustdoc-ui/invalid_infered_static_and_const.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/invalid_infered_static_and_const.rs:1:24 + | +LL | const FOO: dyn Fn() -> _ = ""; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for statics + --> $DIR/invalid_infered_static_and_const.rs:2:25 + | +LL | static BOO: dyn Fn() -> _ = ""; + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/rustdoc-ui/issues/auxiliary/empty-fn.rs b/tests/rustdoc-ui/issues/auxiliary/empty-fn.rs new file mode 100644 index 00000000000..b270c93fd63 --- /dev/null +++ b/tests/rustdoc-ui/issues/auxiliary/empty-fn.rs @@ -0,0 +1,3 @@ +//@ no-prefer-dynamic +#![crate_type = "lib"] +pub fn empty() {} diff --git a/tests/rustdoc-ui/issues/auxiliary/issue-61592.rs b/tests/rustdoc-ui/issues/auxiliary/issue-61592.rs new file mode 100644 index 00000000000..57a365b3f38 --- /dev/null +++ b/tests/rustdoc-ui/issues/auxiliary/issue-61592.rs @@ -0,0 +1,3 @@ +#![crate_name = "foo"] + +pub trait Foo {} diff --git a/tests/rustdoc-ui/issues/auxiliary/panic-handler.rs b/tests/rustdoc-ui/issues/auxiliary/panic-handler.rs new file mode 100644 index 00000000000..d157c6a434e --- /dev/null +++ b/tests/rustdoc-ui/issues/auxiliary/panic-handler.rs @@ -0,0 +1,9 @@ +//@ compile-flags: -C panic=abort + +#![no_std] +#![no_main] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/tests/rustdoc-ui/issues/duplicate-panic-impl-107918.rs b/tests/rustdoc-ui/issues/duplicate-panic-impl-107918.rs new file mode 100644 index 00000000000..ec35b52e33b --- /dev/null +++ b/tests/rustdoc-ui/issues/duplicate-panic-impl-107918.rs @@ -0,0 +1,13 @@ +//@ aux-build:panic-handler.rs +//@ compile-flags: --document-private-items +//@ build-pass +//@ only-linux +// https://github.com/rust-lang/rust/issues/107918 + +#![no_std] +#![no_main] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/tests/rustdoc-ui/issues/ice-associated-type-bounds-110900.rs b/tests/rustdoc-ui/issues/ice-associated-type-bounds-110900.rs new file mode 100644 index 00000000000..4fa60f8878d --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-associated-type-bounds-110900.rs @@ -0,0 +1,28 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/110900 + +#![crate_type="lib"] + +trait A<'a> {} +trait B<'b> {} + +trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { + type As; +} + +trait E<'e> { + type As; +} +trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {} +struct G<T> +where + T: for<'l, 'i> H<'l, 'i, As: for<'a> A<'a> + 'i> +{ + t: std::marker::PhantomData<T>, +} + +trait I<'a, 'b, 'c> { + type As; +} + +trait H<'d, 'e>: for<'f> I<'d, 'f, 'e> + 'd {} diff --git a/tests/rustdoc-ui/issues/ice-bare-dyn-106213.rs b/tests/rustdoc-ui/issues/ice-bare-dyn-106213.rs new file mode 100644 index 00000000000..c954162589d --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-bare-dyn-106213.rs @@ -0,0 +1,8 @@ +//@ compile-flags: --document-private-items +//@ edition:2021 +// https://github.com/rust-lang/rust/issues/106213 + +fn use_avx() -> dyn { + //~^ ERROR at least one trait is required for an object type + !( ident_error ) +} diff --git a/tests/rustdoc-ui/issues/ice-bare-dyn-106213.stderr b/tests/rustdoc-ui/issues/ice-bare-dyn-106213.stderr new file mode 100644 index 00000000000..b029fee510e --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-bare-dyn-106213.stderr @@ -0,0 +1,9 @@ +error[E0224]: at least one trait is required for an object type + --> $DIR/ice-bare-dyn-106213.rs:5:17 + | +LL | fn use_avx() -> dyn { + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs new file mode 100644 index 00000000000..33f3c2ff506 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.rs @@ -0,0 +1,69 @@ +//@ compile-flags: -Znormalize-docs +//@ dont-require-annotations: NOTE + +// https://github.com/rust-lang/rust/issues/105742 +use std::ops::Index; + +pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument + //~| ERROR the trait `SVec` is not dyn compatible + //~| NOTE `SVec` is not dyn compatible + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + let _ = s; +} + +pub trait SVec: Index< + <Self as SVec>::Item, + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + Output = <Index<<Self as SVec>::Item, + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + Output = <Self as SVec>::Item> as SVec>::Item, + //~^ NOTE expected 1 lifetime argument + //~| NOTE expected 1 generic argument + //~| NOTE expected 1 lifetime argument + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| NOTE expected 1 generic argument + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` + //~| ERROR missing generics for associated type `SVec::Item` +> { + type Item<'a, T>; + + fn len(&self) -> <Self as SVec>::Item; + //~^ NOTE expected 1 lifetime argument + //~| ERROR missing generics for associated type `SVec::Item` + //~| NOTE expected 1 generic argument + //~| ERROR missing generics for associated type `SVec::Item` +} diff --git a/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr new file mode 100644 index 00000000000..642847733a8 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-generic-type-alias-105742.stderr @@ -0,0 +1,633 @@ +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | <Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | <Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = <Index<<Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = <Index<<Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:7:40 + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item<'_> = T, Output = T>) { + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:7:40 + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item<T> = T, Output = T>) { + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | <Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | <Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Index<<Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Index<<Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<T>, + | +++ + +error[E0038]: the trait `SVec` is not dyn compatible + --> $DIR/ice-generic-type-alias-105742.rs:7:35 + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/ice-generic-type-alias-105742.rs:17:17 + | +LL | pub trait SVec: Index< + | ____________----__^ + | | | + | | this trait is not dyn compatible... +LL | | <Self as SVec>::Item, +... | +LL | |/ Output = <Index<<Self as SVec>::Item, +... || +LL | || Output = <Self as SVec>::Item> as SVec>::Item, + | ||_________________________________________________^ ...because it uses `Self` as a type parameter +... | +LL | | > { + | |__^ ...because it uses `Self` as a type parameter +help: consider using an opaque type instead + | +LL - pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) { +LL + pub fn next<'a, T>(s: &'a mut impl SVec<Item = T, Output = T>) { + | + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | <Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | <Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Index<<Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Index<<Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | <Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:18:21 + | +LL | <Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | <Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Index<<Self as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:29:37 + | +LL | Output = <Index<<Self as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Index<<Self as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:30 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item<T>> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:40:46 + | +LL | Output = <Self as SVec>::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | Output = <Self as SVec>::Item> as SVec>::Item<T>, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:64:38 + | +LL | fn len(&self) -> <Self as SVec>::Item; + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | fn len(&self) -> <Self as SVec>::Item<'_>; + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/ice-generic-type-alias-105742.rs:64:38 + | +LL | fn len(&self) -> <Self as SVec>::Item; + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/ice-generic-type-alias-105742.rs:62:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | fn len(&self) -> <Self as SVec>::Item<T>; + | +++ + +error: aborting due to 37 previous errors + +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/rustdoc-ui/issues/ice-impl-fn-generic-105737.rs b/tests/rustdoc-ui/issues/ice-impl-fn-generic-105737.rs new file mode 100644 index 00000000000..651fd9ab4b8 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-impl-fn-generic-105737.rs @@ -0,0 +1,5 @@ +// https://github.com/rust-lang/rust/issues/105737 +impl Vec<lol> {} +//~^ ERROR + +pub fn lol() {} diff --git a/tests/rustdoc-ui/issues/ice-impl-fn-generic-105737.stderr b/tests/rustdoc-ui/issues/ice-impl-fn-generic-105737.stderr new file mode 100644 index 00000000000..49cbebc91d9 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-impl-fn-generic-105737.stderr @@ -0,0 +1,12 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/ice-impl-fn-generic-105737.rs:2:10 + | +LL | impl Vec<lol> {} + | ^^^ + | + = help: `lol` is a function item, not a type + = help: function item types cannot be named directly + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/rustdoc-ui/issues/ice-macro-hidden-exported-macro-defid-101076.rs b/tests/rustdoc-ui/issues/ice-macro-hidden-exported-macro-defid-101076.rs new file mode 100644 index 00000000000..0c9a8b9175b --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-macro-hidden-exported-macro-defid-101076.rs @@ -0,0 +1,15 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/101076 + +const _: () = { + #[macro_export] + macro_rules! first_macro { + () => {} + } + mod foo { + #[macro_export] + macro_rules! second_macro { + () => {} + } + } +}; diff --git a/tests/rustdoc-ui/issues/ice-placeholder-type-alias-106226.rs b/tests/rustdoc-ui/issues/ice-placeholder-type-alias-106226.rs new file mode 100644 index 00000000000..71b497a9adc --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-placeholder-type-alias-106226.rs @@ -0,0 +1,3 @@ +// This is a regression test for <https://github.com/rust-lang/rust/issues/106226>. +type F = [_; ()]; +//~^ ERROR diff --git a/tests/rustdoc-ui/issues/ice-placeholder-type-alias-106226.stderr b/tests/rustdoc-ui/issues/ice-placeholder-type-alias-106226.stderr new file mode 100644 index 00000000000..e9080925450 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-placeholder-type-alias-106226.stderr @@ -0,0 +1,9 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases + --> $DIR/ice-placeholder-type-alias-106226.rs:2:11 + | +LL | type F = [_; ()]; + | ^ not allowed in type signatures + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/rustdoc-ui/issues/ice-raw-str-105334.rs b/tests/rustdoc-ui/issues/ice-raw-str-105334.rs new file mode 100644 index 00000000000..f18f0456fdd --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-raw-str-105334.rs @@ -0,0 +1,3 @@ +// https://github.com/rust-lang/rust/issues/105334 +impl Vec< br##"*.."## > {} +//~^ ERROR diff --git a/tests/rustdoc-ui/issues/ice-raw-str-105334.stderr b/tests/rustdoc-ui/issues/ice-raw-str-105334.stderr new file mode 100644 index 00000000000..2096757fbb9 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-raw-str-105334.stderr @@ -0,0 +1,9 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/ice-raw-str-105334.rs:2:11 + | +LL | impl Vec< br##"*.."## > {} + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/rustdoc-ui/issues/ice-typeof-102986.rs b/tests/rustdoc-ui/issues/ice-typeof-102986.rs new file mode 100644 index 00000000000..b1ad19cb9ff --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-typeof-102986.rs @@ -0,0 +1,5 @@ +// https://github.com/rust-lang/rust/issues/102986 +struct Struct { + y: (typeof("hey"),), + //~^ ERROR `typeof` is a reserved keyword but unimplemented +} diff --git a/tests/rustdoc-ui/issues/ice-typeof-102986.stderr b/tests/rustdoc-ui/issues/ice-typeof-102986.stderr new file mode 100644 index 00000000000..02e257a9163 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-typeof-102986.stderr @@ -0,0 +1,15 @@ +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/ice-typeof-102986.rs:3:9 + | +LL | y: (typeof("hey"),), + | ^^^^^^^^^^^^^ reserved keyword + | +help: consider replacing `typeof(...)` with an actual type + | +LL - y: (typeof("hey"),), +LL + y: (&str,), + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0516`. diff --git a/tests/rustdoc-ui/issues/ice-unresolved-self-103997.rs b/tests/rustdoc-ui/issues/ice-unresolved-self-103997.rs new file mode 100644 index 00000000000..b6ba4e48cff --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-unresolved-self-103997.rs @@ -0,0 +1,7 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/103997 + +pub fn foo() {} + +/// [`foo`](Self::foo) //~ WARNING unresolved link to `Self::foo` +pub use foo as bar; diff --git a/tests/rustdoc-ui/issues/ice-unresolved-self-103997.stderr b/tests/rustdoc-ui/issues/ice-unresolved-self-103997.stderr new file mode 100644 index 00000000000..9cb64079c61 --- /dev/null +++ b/tests/rustdoc-ui/issues/ice-unresolved-self-103997.stderr @@ -0,0 +1,10 @@ +warning: unresolved link to `Self::foo` + --> $DIR/ice-unresolved-self-103997.rs:6:13 + | +LL | /// [`foo`](Self::foo) + | ^^^^^^^^^ no item named `Self` in scope + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/issues/issue-109282-import-inline-merge.rs b/tests/rustdoc-ui/issues/issue-109282-import-inline-merge.rs new file mode 100644 index 00000000000..e4486ab26f9 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-109282-import-inline-merge.rs @@ -0,0 +1,14 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/109282>. +// Import for `ValueEnum` is inlined and doc comments on the import and `ValueEnum` itself are +// merged. After the merge they still have correct parent scopes to resolve both `[ValueEnum]`. + +//@ check-pass + +mod m { + pub enum ValueEnum {} +} +mod m2 { + /// [`ValueEnum`] + pub use crate::m::ValueEnum; +} +pub use m2::ValueEnum; diff --git a/tests/rustdoc-ui/issues/issue-120444-1.rs b/tests/rustdoc-ui/issues/issue-120444-1.rs new file mode 100644 index 00000000000..51f2b98fb30 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-120444-1.rs @@ -0,0 +1,17 @@ +//@ compile-flags: --document-private-items + +#![deny(rustdoc::redundant_explicit_links)] + +mod webdavfs { + pub struct A; + pub struct B; +} + +/// [`Vfs`][crate::Vfs] +pub use webdavfs::A; +//~^^ error: redundant explicit link target + +/// [`Vfs`] +pub use webdavfs::B; + +pub struct Vfs; diff --git a/tests/rustdoc-ui/issues/issue-120444-1.stderr b/tests/rustdoc-ui/issues/issue-120444-1.stderr new file mode 100644 index 00000000000..aabdc91df2b --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-120444-1.stderr @@ -0,0 +1,23 @@ +error: redundant explicit link target + --> $DIR/issue-120444-1.rs:10:13 + | +LL | /// [`Vfs`][crate::Vfs] + | ----- ^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +note: the lint level is defined here + --> $DIR/issue-120444-1.rs:3:9 + | +LL | #![deny(rustdoc::redundant_explicit_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: remove explicit link target + | +LL - /// [`Vfs`][crate::Vfs] +LL + /// [`Vfs`] + | + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/issues/issue-120444-2.rs b/tests/rustdoc-ui/issues/issue-120444-2.rs new file mode 100644 index 00000000000..f0e842fd858 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-120444-2.rs @@ -0,0 +1,17 @@ +//@ compile-flags: --document-private-items + +#![deny(rustdoc::redundant_explicit_links)] + +pub mod webdavfs { + pub struct A; + pub struct B; +} + +/// [`Vfs`][crate::Vfs] +pub use webdavfs::A; +//~^^ error: redundant explicit link target + +/// [`Vfs`] +pub use webdavfs::B; + +pub struct Vfs; diff --git a/tests/rustdoc-ui/issues/issue-120444-2.stderr b/tests/rustdoc-ui/issues/issue-120444-2.stderr new file mode 100644 index 00000000000..ee160736b4d --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-120444-2.stderr @@ -0,0 +1,23 @@ +error: redundant explicit link target + --> $DIR/issue-120444-2.rs:10:13 + | +LL | /// [`Vfs`][crate::Vfs] + | ----- ^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +note: the lint level is defined here + --> $DIR/issue-120444-2.rs:3:9 + | +LL | #![deny(rustdoc::redundant_explicit_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: remove explicit link target + | +LL - /// [`Vfs`][crate::Vfs] +LL + /// [`Vfs`] + | + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/issues/issue-58473-2.rs b/tests/rustdoc-ui/issues/issue-58473-2.rs new file mode 100644 index 00000000000..1653da0d139 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-58473-2.rs @@ -0,0 +1,12 @@ +//@ check-pass + +#![deny(rustdoc::private_doc_tests)] + +mod foo { + /** + Does nothing, returns `()` + + yadda-yadda-yadda + */ + fn foo() {} +} diff --git a/tests/rustdoc-ui/issues/issue-58473.rs b/tests/rustdoc-ui/issues/issue-58473.rs new file mode 100644 index 00000000000..2d3772ed752 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-58473.rs @@ -0,0 +1,10 @@ +//@ check-pass + +pub trait Foo { + /** + Does nothing, returns `()` + + yadda-yadda-yadda + */ + fn foo() {} +} diff --git a/tests/rustdoc-ui/issues/issue-61592-2.rs b/tests/rustdoc-ui/issues/issue-61592-2.rs new file mode 100644 index 00000000000..3553f51ed96 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-61592-2.rs @@ -0,0 +1,10 @@ +//@ aux-build:issue-61592.rs + +extern crate foo; + +#[doc = "bar"] +#[doc(inline)] //~ ERROR +#[doc = "baz"] +pub use foo::Foo as _; + +fn main() {} diff --git a/tests/rustdoc-ui/issues/issue-61592-2.stderr b/tests/rustdoc-ui/issues/issue-61592-2.stderr new file mode 100644 index 00000000000..de376ad809e --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-61592-2.stderr @@ -0,0 +1,12 @@ +error[E0780]: anonymous imports cannot be inlined + --> $DIR/issue-61592-2.rs:6:7 + | +LL | #[doc(inline)] + | ^^^^^^ +LL | #[doc = "baz"] +LL | pub use foo::Foo as _; + | ---------------------- anonymous import + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0780`. diff --git a/tests/rustdoc-ui/issues/issue-61592.rs b/tests/rustdoc-ui/issues/issue-61592.rs new file mode 100644 index 00000000000..4721f7d35c5 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-61592.rs @@ -0,0 +1,8 @@ +//@ aux-build:issue-61592.rs + +extern crate foo; + +#[doc(inline)] //~ ERROR +pub use foo::Foo as _; + +fn main() {} diff --git a/tests/rustdoc-ui/issues/issue-61592.stderr b/tests/rustdoc-ui/issues/issue-61592.stderr new file mode 100644 index 00000000000..0b96b659309 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-61592.stderr @@ -0,0 +1,11 @@ +error[E0780]: anonymous imports cannot be inlined + --> $DIR/issue-61592.rs:5:7 + | +LL | #[doc(inline)] + | ^^^^^^ +LL | pub use foo::Foo as _; + | ---------------------- anonymous import + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0780`. diff --git a/tests/rustdoc-ui/issues/issue-61732.rs b/tests/rustdoc-ui/issues/issue-61732.rs new file mode 100644 index 00000000000..d5d9ad5e463 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-61732.rs @@ -0,0 +1,4 @@ +// This previously triggered an ICE. + +pub(in crate::r#mod) fn main() {} +//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `r#mod` diff --git a/tests/rustdoc-ui/issues/issue-61732.stderr b/tests/rustdoc-ui/issues/issue-61732.stderr new file mode 100644 index 00000000000..c4e6997ab74 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-61732.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `r#mod` + --> $DIR/issue-61732.rs:3:15 + | +LL | pub(in crate::r#mod) fn main() {} + | ^^^^^ use of unresolved module or unlinked crate `r#mod` + | +help: you might be missing a crate named `r#mod`, add it to your project and import it in your code + | +LL + extern crate r#mod; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/rustdoc-ui/issues/issue-74134.private.stderr b/tests/rustdoc-ui/issues/issue-74134.private.stderr new file mode 100644 index 00000000000..44c88b6183a --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-74134.private.stderr @@ -0,0 +1,11 @@ +warning: public documentation for `public_item` links to private item `PrivateType` + --> $DIR/issue-74134.rs:19:11 + | +LL | /// [`PrivateType`] + | ^^^^^^^^^^^ 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: 1 warning emitted + diff --git a/tests/rustdoc-ui/issues/issue-74134.public.stderr b/tests/rustdoc-ui/issues/issue-74134.public.stderr new file mode 100644 index 00000000000..5b1887b8310 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-74134.public.stderr @@ -0,0 +1,11 @@ +warning: public documentation for `public_item` links to private item `PrivateType` + --> $DIR/issue-74134.rs:19:11 + | +LL | /// [`PrivateType`] + | ^^^^^^^^^^^ 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/issues/issue-74134.rs b/tests/rustdoc-ui/issues/issue-74134.rs new file mode 100644 index 00000000000..919435c64b5 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-74134.rs @@ -0,0 +1,41 @@ +//@ revisions: public private +//@ [private]compile-flags: --document-private-items +//@ check-pass + +// There are 4 cases here: +// 1. public item -> public type: no warning +// 2. public item -> private type: warning +// 3. private item -> public type: no warning +// 4. private item -> private type: no warning +// All 4 cases are tested with and without --document-private-items. +// +// Case 4 without --document-private-items is the one described in issue #74134. + +struct PrivateType; +pub struct PublicType; + +pub struct Public { + /// [`PublicType`] + /// [`PrivateType`] + //~^ WARNING public documentation for `public_item` links to private item `PrivateType` + pub public_item: u32, + + /// [`PublicType`] + /// [`PrivateType`] + private_item: u32, +} + +// The following cases are identical to the ones above, except that they are in a private +// module. Thus they all fall into cases 3 and 4 and should not produce a warning. + +mod private { + pub struct Public { + /// [`super::PublicType`] + /// [`super::PrivateType`] + pub public_item: u32, + + /// [`super::PublicType`] + /// [`super::PrivateType`] + private_item: u32, + } +} diff --git a/tests/rustdoc-ui/issues/issue-79465.rs b/tests/rustdoc-ui/issues/issue-79465.rs new file mode 100644 index 00000000000..e50f3995b83 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-79465.rs @@ -0,0 +1,2 @@ +pub fn f1<T>(x: T::A) {} +//~^ ERROR diff --git a/tests/rustdoc-ui/issues/issue-79465.stderr b/tests/rustdoc-ui/issues/issue-79465.stderr new file mode 100644 index 00000000000..e7b433268e8 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-79465.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `A` not found for `T` + --> $DIR/issue-79465.rs:1:20 + | +LL | pub fn f1<T>(x: T::A) {} + | ^ associated type `A` not found + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/rustdoc-ui/issues/issue-79467.rs b/tests/rustdoc-ui/issues/issue-79467.rs new file mode 100644 index 00000000000..eb0b9b38071 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-79467.rs @@ -0,0 +1,8 @@ +fn g() +where + 'static: 'static, + dyn 'static: 'static + Copy, //~ ERROR at least one trait is required for an object type +{ +} + +fn main() {} diff --git a/tests/rustdoc-ui/issues/issue-79467.stderr b/tests/rustdoc-ui/issues/issue-79467.stderr new file mode 100644 index 00000000000..cb030a3113f --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-79467.stderr @@ -0,0 +1,9 @@ +error[E0224]: at least one trait is required for an object type + --> $DIR/issue-79467.rs:4:5 + | +LL | dyn 'static: 'static + Copy, + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/rustdoc-ui/issues/issue-79494.rs b/tests/rustdoc-ui/issues/issue-79494.rs new file mode 100644 index 00000000000..28ef82dac0f --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-79494.rs @@ -0,0 +1,5 @@ +//@ only-x86_64-unknown-linux-gnu + +#![feature(const_transmute)] + +pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types diff --git a/tests/rustdoc-ui/issues/issue-79494.stderr b/tests/rustdoc-ui/issues/issue-79494.stderr new file mode 100644 index 00000000000..20e568d8eab --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-79494.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/issue-79494.rs:5:33 + | +LL | pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `usize` (64 bits) + = note: target type: `&[u8]` (128 bits) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/rustdoc-ui/issues/issue-80992.rs b/tests/rustdoc-ui/issues/issue-80992.rs new file mode 100644 index 00000000000..c328ac53e53 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-80992.rs @@ -0,0 +1,11 @@ +//@ check-pass +//@ compile-flags:--test +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +pub fn test() -> Result<(), ()> { + //! ```compile_fail + //! fn test() -> Result< {} + //! ``` + Ok(()) +} diff --git a/tests/rustdoc-ui/issues/issue-80992.stdout b/tests/rustdoc-ui/issues/issue-80992.stdout new file mode 100644 index 00000000000..d2b1cd1d550 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-80992.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/issue-80992.rs - test (line 7) - compile fail ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs new file mode 100644 index 00000000000..5d1951dbe3e --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs @@ -0,0 +1,14 @@ +//@ compile-flags:--test --error-format=short +//@ check-stdout +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ failure-status: 101 + +/// ```rust +/// foo(); +/// ``` +fn foo() { + println!("Hello, world!"); +} + +//~? RAW cannot find function `foo` diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout new file mode 100644 index 00000000000..94a82cf0afc --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout @@ -0,0 +1,16 @@ + +running 1 test +test $DIR/issue-81662-shortness.rs - foo (line 7) ... FAILED + +failures: + +---- $DIR/issue-81662-shortness.rs - foo (line 7) stdout ---- +$DIR/issue-81662-shortness.rs:8:1: error[E0425]: cannot find function `foo` in this scope: not found in this scope +error: aborting due to 1 previous error +Couldn't compile the test. + +failures: + $DIR/issue-81662-shortness.rs - foo (line 7) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs new file mode 100644 index 00000000000..62a0942df1b --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs @@ -0,0 +1,11 @@ +//@ compile-flags: -W help +//@ check-pass +//@ check-stdout +// +// ignore-tidy-linelength +// +//@ normalize-stdout: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" +//@ normalize-stdout: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" + +//~? RAW Lint checks provided +//~? RAW rustdoc::broken-intra-doc-links diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout b/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout new file mode 100644 index 00000000000..6021bce6939 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.stdout @@ -0,0 +1,24 @@ + +Available lint options: + -W <foo> Warn about <foo> + -A <foo> Allow <foo> + -D <foo> Deny <foo> + -F <foo> Forbid <foo> (deny <foo> and all attempts to override) + + +Lint checks provided by rustc: + + $NAMES $LEVELS $MEANINGS + +Lint groups provided by rustc: + + $NAMES $SUB_LINTS + +Lint checks loaded by this crate: + + $NAMES $LEVELS $MEANINGS + +Lint groups loaded by this crate: + + $NAMES $SUB_LINTS + diff --git a/tests/rustdoc-ui/issues/issue-91134.rs b/tests/rustdoc-ui/issues/issue-91134.rs new file mode 100644 index 00000000000..1c53ecfeb8b --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-91134.rs @@ -0,0 +1,14 @@ +//@ compile-flags: --test --crate-name=empty_fn --extern=empty_fn --test-args=--test-threads=1 +//@ aux-build:empty-fn.rs +//@ check-pass +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ edition:2021 + +/// <https://github.com/rust-lang/rust/issues/91134> +/// +/// ``` +/// extern crate empty_fn; +/// empty_fn::empty(); +/// ``` +pub struct Something; diff --git a/tests/rustdoc-ui/issues/issue-91134.stdout b/tests/rustdoc-ui/issues/issue-91134.stdout new file mode 100644 index 00000000000..084062743da --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-91134.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/issue-91134.rs - Something (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/issues/issue-91713.rs b/tests/rustdoc-ui/issues/issue-91713.rs new file mode 100644 index 00000000000..68240726007 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-91713.rs @@ -0,0 +1,4 @@ +//@ check-pass +//@ compile-flags: --passes list + +//~? WARN the `passes` flag no longer functions diff --git a/tests/rustdoc-ui/issues/issue-91713.stderr b/tests/rustdoc-ui/issues/issue-91713.stderr new file mode 100644 index 00000000000..44ead7a1de2 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-91713.stderr @@ -0,0 +1,5 @@ +warning: the `passes` flag no longer functions + | + = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information + = help: you may want to use --document-private-items + diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout new file mode 100644 index 00000000000..30aadfe89f4 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -0,0 +1,31 @@ +Available passes for running rustdoc: + check-doc-cfg - checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs +check_doc_test_visibility - run various visibility-related lints on doctests +strip-aliased-non-local - strips all non-local private aliased items from the output + strip-hidden - strips all `#[doc(hidden)]` items from the output + strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports + strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate + propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items + propagate-stability - propagates stability to child items +collect-intra-doc-links - resolves intra-doc links + collect-trait-impls - retrieves trait impls for items in the crate +calculate-doc-coverage - counts the number of items with and without documentation + run-lints - runs some of rustdoc's lints + +Default passes for rustdoc: + collect-trait-impls +check_doc_test_visibility + check-doc-cfg +strip-aliased-non-local + strip-hidden (when not --document-hidden-items) + strip-private (when not --document-private-items) + strip-priv-imports (when --document-private-items) +collect-intra-doc-links + propagate-doc-cfg + propagate-stability + run-lints + +Passes run with `--show-coverage`: + strip-hidden (when not --document-hidden-items) + strip-private (when not --document-private-items) +calculate-doc-coverage diff --git a/tests/rustdoc-ui/issues/issue-96287.rs b/tests/rustdoc-ui/issues/issue-96287.rs new file mode 100644 index 00000000000..b490c2fc03f --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-96287.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +pub trait TraitWithAssoc { + type Assoc; +} + +pub type Foo<V> = impl Trait<V::Assoc>; +//~^ ERROR +//~| ERROR + +pub trait Trait<U> {} + +impl<W> Trait<W> for () {} + +pub fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T> { + () +} diff --git a/tests/rustdoc-ui/issues/issue-96287.stderr b/tests/rustdoc-ui/issues/issue-96287.stderr new file mode 100644 index 00000000000..40dc1cc0e70 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-96287.stderr @@ -0,0 +1,26 @@ +error[E0220]: associated type `Assoc` not found for `V` + --> $DIR/issue-96287.rs:7:33 + | +LL | pub type Foo<V> = impl Trait<V::Assoc>; + | ^^^^^ there is an associated type `Assoc` in the trait `TraitWithAssoc` + | +help: consider restricting type parameter `V` with trait `TraitWithAssoc` + | +LL | pub type Foo<V: TraitWithAssoc> = impl Trait<V::Assoc>; + | ++++++++++++++++ + +error[E0220]: associated type `Assoc` not found for `V` + --> $DIR/issue-96287.rs:7:33 + | +LL | pub type Foo<V> = impl Trait<V::Assoc>; + | ^^^^^ there is an associated type `Assoc` in the trait `TraitWithAssoc` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider restricting type parameter `V` with trait `TraitWithAssoc` + | +LL | pub type Foo<V: TraitWithAssoc> = impl Trait<V::Assoc>; + | ++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/rustdoc-ui/issues/issue-98690.rs b/tests/rustdoc-ui/issues/issue-98690.rs new file mode 100644 index 00000000000..01708f3f64d --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-98690.rs @@ -0,0 +1,10 @@ +//@ compile-flags: --test --persist-doctests /../../ -Z unstable-options +//@ failure-status: 101 +//@ only-linux + +#![crate_name = "foo"] + +//! ```rust +//! use foo::dummy; +//! dummy(); +//! ``` diff --git a/tests/rustdoc-ui/issues/issue-98690.stderr b/tests/rustdoc-ui/issues/issue-98690.stderr new file mode 100644 index 00000000000..47d94f99a45 --- /dev/null +++ b/tests/rustdoc-ui/issues/issue-98690.stderr @@ -0,0 +1 @@ +Couldn't create directory for doctest executables: Permission denied (os error 13) diff --git a/tests/rustdoc-ui/lints/bare-urls-limit.rs b/tests/rustdoc-ui/lints/bare-urls-limit.rs new file mode 100644 index 00000000000..f64154b0496 --- /dev/null +++ b/tests/rustdoc-ui/lints/bare-urls-limit.rs @@ -0,0 +1,12 @@ +//@ check-fail + +#![deny(rustdoc::bare_urls)] + +// examples of bare urls that are beyond our ability to generate suggestions for + +// this falls through every heuristic in `source_span_for_markdown_range`, +// and thus does not get any suggestion. +#[doc = "good: <https://example.com/> \n\n"] +//~^ ERROR this URL is not a hyperlink +#[doc = "bad: https://example.com/"] +pub fn duplicate_raw() {} diff --git a/tests/rustdoc-ui/lints/bare-urls-limit.stderr b/tests/rustdoc-ui/lints/bare-urls-limit.stderr new file mode 100644 index 00000000000..9573665cb13 --- /dev/null +++ b/tests/rustdoc-ui/lints/bare-urls-limit.stderr @@ -0,0 +1,18 @@ +error: this URL is not a hyperlink + --> $DIR/bare-urls-limit.rs:9:9 + | +LL | #[doc = "good: <https://example.com/> \n\n"] + | _________^ +LL | | +LL | | #[doc = "bad: https://example.com/"] + | |___________________________________^ + | + = note: bare URLs are not automatically turned into clickable links +note: the lint level is defined here + --> $DIR/bare-urls-limit.rs:3:9 + | +LL | #![deny(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/bare-urls.fixed b/tests/rustdoc-ui/lints/bare-urls.fixed new file mode 100644 index 00000000000..a91573146b8 --- /dev/null +++ b/tests/rustdoc-ui/lints/bare-urls.fixed @@ -0,0 +1,70 @@ +//@ run-rustfix + +#![deny(rustdoc::bare_urls)] + +/// <https://somewhere.com> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com/a> +//~^ ERROR this URL is not a hyperlink +/// <https://www.somewhere.com> +//~^ ERROR this URL is not a hyperlink +/// <https://www.somewhere.com/a> +//~^ ERROR this URL is not a hyperlink +/// <https://subdomain.example.com> +//~^ ERROR not a hyperlink +/// <https://somewhere.com?> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com/a?> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com?hello=12> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com/a?hello=12> +//~^ ERROR this URL is not a hyperlink +/// <https://example.com?hello=12#xyz> +//~^ ERROR this URL is not a hyperlink +/// <https://example.com/a?hello=12#xyz> +//~^ ERROR this URL is not a hyperlink +/// <https://example.com#xyz> +//~^ ERROR this URL is not a hyperlink +/// <https://example.com/a#xyz> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com?hello=12&bye=11> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com/a?hello=12&bye=11> +//~^ ERROR this URL is not a hyperlink +/// <https://somewhere.com?hello=12&bye=11#xyz> +//~^ ERROR this URL is not a hyperlink +/// hey! <https://somewhere.com/a?hello=12&bye=11#xyz> +//~^ ERROR this URL is not a hyperlink +pub fn c() {} + +#[doc = "here's a thing: <https://example.com/>"] +//~^ ERROR this URL is not a hyperlink +pub fn f() {} + +/// <https://example.com/sugar> +//~^ ERROR this URL is not a hyperlink +#[doc = "<https://example.com/raw>"] +//~^ ERROR this URL is not a hyperlink +pub fn mixed() {} + +/// <https://somewhere.com> +/// [a](http://a.com) +/// [b] +/// +/// [b]: http://b.com +/// +/// ``` +/// This link should not be linted: http://example.com +/// +/// Nor this one: <http://example.com> or this one: [x](http://example.com) +/// ``` +/// +/// [should_not.lint](should_not.lint) +pub fn everything_is_fine_here() {} + +#[allow(rustdoc::bare_urls)] +pub mod foo { + /// https://somewhere.com/a?hello=12&bye=11#xyz + pub fn bar() {} +} diff --git a/tests/rustdoc-ui/lints/bare-urls.rs b/tests/rustdoc-ui/lints/bare-urls.rs new file mode 100644 index 00000000000..5b008cdafa2 --- /dev/null +++ b/tests/rustdoc-ui/lints/bare-urls.rs @@ -0,0 +1,70 @@ +//@ run-rustfix + +#![deny(rustdoc::bare_urls)] + +/// https://somewhere.com +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a +//~^ ERROR this URL is not a hyperlink +/// https://www.somewhere.com +//~^ ERROR this URL is not a hyperlink +/// https://www.somewhere.com/a +//~^ ERROR this URL is not a hyperlink +/// https://subdomain.example.com +//~^ ERROR not a hyperlink +/// https://somewhere.com? +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a? +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com?hello=12 +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a?hello=12 +//~^ ERROR this URL is not a hyperlink +/// https://example.com?hello=12#xyz +//~^ ERROR this URL is not a hyperlink +/// https://example.com/a?hello=12#xyz +//~^ ERROR this URL is not a hyperlink +/// https://example.com#xyz +//~^ ERROR this URL is not a hyperlink +/// https://example.com/a#xyz +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com?hello=12&bye=11 +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a?hello=12&bye=11 +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com?hello=12&bye=11#xyz +//~^ ERROR this URL is not a hyperlink +/// hey! https://somewhere.com/a?hello=12&bye=11#xyz +//~^ ERROR this URL is not a hyperlink +pub fn c() {} + +#[doc = "here's a thing: https://example.com/"] +//~^ ERROR this URL is not a hyperlink +pub fn f() {} + +/// https://example.com/sugar +//~^ ERROR this URL is not a hyperlink +#[doc = "https://example.com/raw"] +//~^ ERROR this URL is not a hyperlink +pub fn mixed() {} + +/// <https://somewhere.com> +/// [a](http://a.com) +/// [b] +/// +/// [b]: http://b.com +/// +/// ``` +/// This link should not be linted: http://example.com +/// +/// Nor this one: <http://example.com> or this one: [x](http://example.com) +/// ``` +/// +/// [should_not.lint](should_not.lint) +pub fn everything_is_fine_here() {} + +#[allow(rustdoc::bare_urls)] +pub mod foo { + /// https://somewhere.com/a?hello=12&bye=11#xyz + pub fn bar() {} +} diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr new file mode 100644 index 00000000000..e1108c7e7f8 --- /dev/null +++ b/tests/rustdoc-ui/lints/bare-urls.stderr @@ -0,0 +1,247 @@ +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:5:5 + | +LL | /// https://somewhere.com + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +note: the lint level is defined here + --> $DIR/bare-urls.rs:3:9 + | +LL | #![deny(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | /// <https://somewhere.com> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:7:5 + | +LL | /// https://somewhere.com/a + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com/a> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:9:5 + | +LL | /// https://www.somewhere.com + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://www.somewhere.com> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:11:5 + | +LL | /// https://www.somewhere.com/a + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://www.somewhere.com/a> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:13:5 + | +LL | /// https://subdomain.example.com + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://subdomain.example.com> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:15:5 + | +LL | /// https://somewhere.com? + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com?> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:17:5 + | +LL | /// https://somewhere.com/a? + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com/a?> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:19:5 + | +LL | /// https://somewhere.com?hello=12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com?hello=12> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:21:5 + | +LL | /// https://somewhere.com/a?hello=12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com/a?hello=12> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:23:5 + | +LL | /// https://example.com?hello=12#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://example.com?hello=12#xyz> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:25:5 + | +LL | /// https://example.com/a?hello=12#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://example.com/a?hello=12#xyz> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:27:5 + | +LL | /// https://example.com#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://example.com#xyz> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:29:5 + | +LL | /// https://example.com/a#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://example.com/a#xyz> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:31:5 + | +LL | /// https://somewhere.com?hello=12&bye=11 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com?hello=12&bye=11> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:33:5 + | +LL | /// https://somewhere.com/a?hello=12&bye=11 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com/a?hello=12&bye=11> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:35:5 + | +LL | /// https://somewhere.com?hello=12&bye=11#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://somewhere.com?hello=12&bye=11#xyz> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:37:10 + | +LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// hey! <https://somewhere.com/a?hello=12&bye=11#xyz> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:41:26 + | +LL | #[doc = "here's a thing: https://example.com/"] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | #[doc = "here's a thing: <https://example.com/>"] + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:45:5 + | +LL | /// https://example.com/sugar + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// <https://example.com/sugar> + | + + + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:47:10 + | +LL | #[doc = "https://example.com/raw"] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | #[doc = "<https://example.com/raw>"] + | + + + +error: aborting due to 20 previous errors + diff --git a/tests/rustdoc-ui/lints/check-attr.rs b/tests/rustdoc-ui/lints/check-attr.rs new file mode 100644 index 00000000000..3c06e6c076b --- /dev/null +++ b/tests/rustdoc-ui/lints/check-attr.rs @@ -0,0 +1,58 @@ +#![deny(rustdoc::invalid_codeblock_attributes)] + +/// foo +//~^ ERROR +//~^^ ERROR +//~^^^ ERROR +/// +/// ```compile-fail,compilefail,comPile_fail +/// boo +/// ``` +pub fn foo() {} + +/// bar +//~^ ERROR +//~^^ ERROR +//~^^^ ERROR +/// +/// ```should-panic,shouldpanic,sHould_panic +/// boo +/// ``` +pub fn bar() {} + +/// foobar +//~^ ERROR +//~^^ ERROR +//~^^^ ERROR +/// +/// ```no-run,norun,no_Run +/// boo +/// ``` +pub fn foobar() {} + +/// b +//~^ ERROR +//~^^ ERROR +//~^^^ ERROR +/// +/// ```test-harness,testharness,teSt_harness +/// boo +/// ``` +pub fn b() {} + +/// b +//~^ ERROR +/// +/// ```rust2018 +/// boo +/// ``` +pub fn c() {} + +/// b +//~^ ERROR +//~| ERROR +/// +/// ```rust2018 shouldpanic +/// boo +/// ``` +pub fn d() {} diff --git a/tests/rustdoc-ui/lints/check-attr.stderr b/tests/rustdoc-ui/lints/check-attr.stderr new file mode 100644 index 00000000000..3366c021727 --- /dev/null +++ b/tests/rustdoc-ui/lints/check-attr.stderr @@ -0,0 +1,193 @@ +error: unknown attribute `compile-fail` + --> $DIR/check-attr.rs:3:1 + | +LL | / /// foo +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` +note: the lint level is defined here + --> $DIR/check-attr.rs:1:9 + | +LL | #![deny(rustdoc::invalid_codeblock_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown attribute `compilefail` + --> $DIR/check-attr.rs:3:1 + | +LL | / /// foo +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `comPile_fail` + --> $DIR/check-attr.rs:3:1 + | +LL | / /// foo +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `should-panic` + --> $DIR/check-attr.rs:13:1 + | +LL | / /// bar +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `shouldpanic` + --> $DIR/check-attr.rs:13:1 + | +LL | / /// bar +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `sHould_panic` + --> $DIR/check-attr.rs:13:1 + | +LL | / /// bar +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `no-run` + --> $DIR/check-attr.rs:23:1 + | +LL | / /// foobar +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `no_run` to compile, but not run, the code sample during testing + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `norun` + --> $DIR/check-attr.rs:23:1 + | +LL | / /// foobar +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `no_run` to compile, but not run, the code sample during testing + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `no_Run` + --> $DIR/check-attr.rs:23:1 + | +LL | / /// foobar +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `no_run` to compile, but not run, the code sample during testing + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `test-harness` + --> $DIR/check-attr.rs:33:1 + | +LL | / /// b +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `testharness` + --> $DIR/check-attr.rs:33:1 + | +LL | / /// b +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `teSt_harness` + --> $DIR/check-attr.rs:33:1 + | +LL | / /// b +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: unknown attribute `rust2018` + --> $DIR/check-attr.rs:43:1 + | +LL | / /// b +LL | | +LL | | /// +LL | | /// ```rust2018 +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: there is an attribute with a similar name: `edition2018` + +error: unknown attribute `rust2018` + --> $DIR/check-attr.rs:51:1 + | +LL | / /// b +LL | | +LL | | +LL | | /// +LL | | /// ```rust2018 shouldpanic +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: there is an attribute with a similar name: `edition2018` + +error: unknown attribute `shouldpanic` + --> $DIR/check-attr.rs:51:1 + | +LL | / /// b +LL | | +LL | | +LL | | /// +LL | | /// ```rust2018 shouldpanic +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: aborting due to 15 previous errors + diff --git a/tests/rustdoc-ui/lints/check-fail.rs b/tests/rustdoc-ui/lints/check-fail.rs new file mode 100644 index 00000000000..903cbdb532a --- /dev/null +++ b/tests/rustdoc-ui/lints/check-fail.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Z unstable-options --check + +#![feature(rustdoc_missing_doc_code_examples)] +#![deny(missing_docs)] +#![deny(rustdoc::missing_doc_code_examples)] +#![deny(rustdoc::all)] + +//! ```rust,testharness +//~^ ERROR +//! let x = 12; +//! ``` + +pub fn foo() {} +//~^ ERROR +//~^^ ERROR + +/// hello +//~^ ERROR +/// +/// ```rust,testharness +/// let x = 12; +/// ``` +pub fn bar() {} diff --git a/tests/rustdoc-ui/lints/check-fail.stderr b/tests/rustdoc-ui/lints/check-fail.stderr new file mode 100644 index 00000000000..2eb9496e5dc --- /dev/null +++ b/tests/rustdoc-ui/lints/check-fail.stderr @@ -0,0 +1,58 @@ +error: missing documentation for a function + --> $DIR/check-fail.rs:13:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:4:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/check-fail.rs:13:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:5:9 + | +LL | #![deny(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown attribute `testharness` + --> $DIR/check-fail.rs:8:1 + | +LL | / //! ```rust,testharness +LL | | +LL | | //! let x = 12; +LL | | //! ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` +note: the lint level is defined here + --> $DIR/check-fail.rs:6:9 + | +LL | #![deny(rustdoc::all)] + | ^^^^^^^^^^^^ + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]` + +error: unknown attribute `testharness` + --> $DIR/check-fail.rs:17:1 + | +LL | / /// hello +LL | | +LL | | /// +LL | | /// ```rust,testharness +LL | | /// let x = 12; +LL | | /// ``` + | |_______^ + | + = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/lints/check.rs b/tests/rustdoc-ui/lints/check.rs new file mode 100644 index 00000000000..0943f9f6053 --- /dev/null +++ b/tests/rustdoc-ui/lints/check.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ compile-flags: -Z unstable-options --check +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" + +#![feature(rustdoc_missing_doc_code_examples)] +//~^ WARN + +#![warn(missing_docs)] +#![warn(rustdoc::missing_doc_code_examples)] +#![warn(rustdoc::all)] + +pub fn foo() {} +//~^ WARN +//~^^ WARN + +//~? WARN no documentation found for this crate's top-level module diff --git a/tests/rustdoc-ui/lints/check.stderr b/tests/rustdoc-ui/lints/check.stderr new file mode 100644 index 00000000000..dcdf25dda64 --- /dev/null +++ b/tests/rustdoc-ui/lints/check.stderr @@ -0,0 +1,48 @@ +warning: missing documentation for the crate + --> $DIR/check.rs:5:1 + | +LL | / #![feature(rustdoc_missing_doc_code_examples)] +LL | | +LL | | +LL | | #![warn(missing_docs)] +... | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check.rs:8:9 + | +LL | #![warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a function + --> $DIR/check.rs:12:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + +warning: no documentation found for this crate's top-level module + | + = help: The following guide may be of use: + https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html +note: the lint level is defined here + --> $DIR/check.rs:10:9 + | +LL | #![warn(rustdoc::all)] + | ^^^^^^^^^^^^ + = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]` + +warning: missing code example in this documentation + --> $DIR/check.rs:12:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check.rs:9:9 + | +LL | #![warn(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted + diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-crate.rs b/tests/rustdoc-ui/lints/deny-missing-docs-crate.rs new file mode 100644 index 00000000000..b74eba3f66b --- /dev/null +++ b/tests/rustdoc-ui/lints/deny-missing-docs-crate.rs @@ -0,0 +1,3 @@ +#![deny(missing_docs)] //~ ERROR + +pub struct Foo; //~ ERROR diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr b/tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr new file mode 100644 index 00000000000..5025b0b0ca8 --- /dev/null +++ b/tests/rustdoc-ui/lints/deny-missing-docs-crate.stderr @@ -0,0 +1,22 @@ +error: missing documentation for the crate + --> $DIR/deny-missing-docs-crate.rs:1:1 + | +LL | / #![deny(missing_docs)] +LL | | +LL | | pub struct Foo; + | |_______________^ + | +note: the lint level is defined here + --> $DIR/deny-missing-docs-crate.rs:1:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: missing documentation for a struct + --> $DIR/deny-missing-docs-crate.rs:3:1 + | +LL | pub struct Foo; + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-macro.rs b/tests/rustdoc-ui/lints/deny-missing-docs-macro.rs new file mode 100644 index 00000000000..b1c1253176b --- /dev/null +++ b/tests/rustdoc-ui/lints/deny-missing-docs-macro.rs @@ -0,0 +1,8 @@ +//! foo + +#![deny(missing_docs)] + +#[macro_export] +macro_rules! foo { //~ ERROR + () => {} +} diff --git a/tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr b/tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr new file mode 100644 index 00000000000..24597f09db6 --- /dev/null +++ b/tests/rustdoc-ui/lints/deny-missing-docs-macro.stderr @@ -0,0 +1,14 @@ +error: missing documentation for a macro + --> $DIR/deny-missing-docs-macro.rs:6:1 + | +LL | macro_rules! foo { + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/deny-missing-docs-macro.rs:3:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/doc-attr.rs b/tests/rustdoc-ui/lints/doc-attr.rs new file mode 100644 index 00000000000..666aeb55cbe --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-attr.rs @@ -0,0 +1,17 @@ +#![crate_type = "lib"] +#![doc(as_ptr)] +//~^ ERROR unknown `doc` attribute + +#[doc(as_ptr)] +//~^ ERROR unknown `doc` attribute +pub fn foo() {} + +#[doc(123)] +//~^ ERROR invalid `doc` attribute +#[doc("hello", "bar")] +//~^ ERROR invalid `doc` attribute +//~| ERROR invalid `doc` attribute +#[doc(foo::bar, crate::bar::baz = "bye")] +//~^ ERROR unknown `doc` attribute +//~| ERROR unknown `doc` attribute +fn bar() {} diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr new file mode 100644 index 00000000000..091ffc20d46 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-attr.stderr @@ -0,0 +1,46 @@ +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:5:7 + | +LL | #[doc(as_ptr)] + | ^^^^^^ + | + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: invalid `doc` attribute + --> $DIR/doc-attr.rs:9:7 + | +LL | #[doc(123)] + | ^^^ + +error: invalid `doc` attribute + --> $DIR/doc-attr.rs:11:7 + | +LL | #[doc("hello", "bar")] + | ^^^^^^^ + +error: invalid `doc` attribute + --> $DIR/doc-attr.rs:11:16 + | +LL | #[doc("hello", "bar")] + | ^^^^^ + +error: unknown `doc` attribute `foo::bar` + --> $DIR/doc-attr.rs:14:7 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^ + +error: unknown `doc` attribute `crate::bar::baz` + --> $DIR/doc-attr.rs:14:17 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:2:8 + | +LL | #![doc(as_ptr)] + | ^^^^^^ + +error: aborting due to 7 previous errors + diff --git a/tests/rustdoc-ui/lints/doc-spotlight.fixed b/tests/rustdoc-ui/lints/doc-spotlight.fixed new file mode 100644 index 00000000000..0f8f11a9430 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-spotlight.fixed @@ -0,0 +1,6 @@ +//@ run-rustfix +#![feature(doc_notable_trait)] + +#[doc(notable_trait)] +//~^ ERROR unknown `doc` attribute `spotlight` +trait MyTrait {} diff --git a/tests/rustdoc-ui/lints/doc-spotlight.rs b/tests/rustdoc-ui/lints/doc-spotlight.rs new file mode 100644 index 00000000000..c1f90dd442b --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-spotlight.rs @@ -0,0 +1,6 @@ +//@ run-rustfix +#![feature(doc_notable_trait)] + +#[doc(spotlight)] +//~^ ERROR unknown `doc` attribute `spotlight` +trait MyTrait {} diff --git a/tests/rustdoc-ui/lints/doc-spotlight.stderr b/tests/rustdoc-ui/lints/doc-spotlight.stderr new file mode 100644 index 00000000000..9682a3c0c8b --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-spotlight.stderr @@ -0,0 +1,12 @@ +error: unknown `doc` attribute `spotlight` + --> $DIR/doc-spotlight.rs:4:7 + | +LL | #[doc(spotlight)] + | ^^^^^^^^^ help: use `notable_trait` instead + | + = note: `doc(spotlight)` was renamed to `doc(notable_trait)` + = note: `doc(spotlight)` is now a no-op + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/doc-without-codeblock.rs b/tests/rustdoc-ui/lints/doc-without-codeblock.rs new file mode 100644 index 00000000000..ccb241d4037 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-without-codeblock.rs @@ -0,0 +1,22 @@ +#![feature(rustdoc_missing_doc_code_examples)] +#![deny(rustdoc::missing_doc_code_examples)] + +/// Some docs. +//~^ ERROR missing code example in this documentation +pub struct Foo; + +/// And then, the princess died. +pub mod foo { + /// Or maybe not because she saved herself! + //~^ ERROR missing code example in this documentation + pub fn bar() {} +} + +// This impl is here to ensure the lint isn't emitted for foreign traits implementations. +impl std::ops::Neg for Foo { + type Output = Self; + + fn neg(self) -> Self::Output { + Self + } +} diff --git a/tests/rustdoc-ui/lints/doc-without-codeblock.stderr b/tests/rustdoc-ui/lints/doc-without-codeblock.stderr new file mode 100644 index 00000000000..d230f160693 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-without-codeblock.stderr @@ -0,0 +1,20 @@ +error: missing code example in this documentation + --> $DIR/doc-without-codeblock.rs:10:5 + | +LL | /// Or maybe not because she saved herself! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/doc-without-codeblock.rs:2:9 + | +LL | #![deny(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/doc-without-codeblock.rs:4:1 + | +LL | /// Some docs. + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs new file mode 100644 index 00000000000..9a8bce2a92a --- /dev/null +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs @@ -0,0 +1,7 @@ +#![feature(doc_cfg_hide)] + +#![doc(cfg_hide = "test")] //~ ERROR +#![doc(cfg_hide)] //~ ERROR + +#[doc(cfg_hide(doc))] //~ ERROR +pub fn foo() {} diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr new file mode 100644 index 00000000000..0c9d0879b0a --- /dev/null +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr @@ -0,0 +1,27 @@ +error: this attribute can only be applied at the crate level + --> $DIR/doc_cfg_hide.rs:6:7 + | +LL | #[doc(cfg_hide(doc))] + | ^^^^^^^^^^^^^ + | + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information + = note: `#[deny(invalid_doc_attributes)]` on by default +help: to apply to the crate, use an inner attribute + | +LL | #![doc(cfg_hide(doc))] + | + + +error: `#[doc(cfg_hide(...))]` takes a list of attributes + --> $DIR/doc_cfg_hide.rs:3:8 + | +LL | #![doc(cfg_hide = "test")] + | ^^^^^^^^^^^^^^^^^ + +error: `#[doc(cfg_hide(...))]` takes a list of attributes + --> $DIR/doc_cfg_hide.rs:4:8 + | +LL | #![doc(cfg_hide)] + | ^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs new file mode 100644 index 00000000000..87e6aa0c256 --- /dev/null +++ b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.rs @@ -0,0 +1,155 @@ +//@ check-pass + +//! This file tests the `#[expect]` attribute implementation for tool lints. The same +//! file is used to test clippy and rustdoc. Any changes to this file should be synced +//! to the other test files as well. +//! +//! Expectations: +//! * rustc: only rustc lint expectations are emitted +//! * clippy: rustc and Clippy's expectations are emitted +//! * rustdoc: only rustdoc lint expectations are emitted +//! +//! This test can't cover every lint from Clippy, rustdoc and potentially other +//! tools that will be developed. This therefore only tests a small subset of lints + +#![expect(rustdoc::missing_crate_level_docs)] +//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] +//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default + +mod rustc_ok { + //! See <https://doc.rust-lang.org/rustc/lints/index.html> + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42.0; + + #[expect(invalid_nan_comparisons)] + match x { + f32::NAN => {} + _ => {} + } + } +} + +mod rustc_warn { + //! See <https://doc.rust-lang.org/rustc/lints/index.html> + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42; + + #[expect(invalid_nan_comparisons)] + match x { + 5 => {} + 6 => {} + _ => {} + } + } +} + +pub mod rustdoc_ok { + //! See <https://doc.rust-lang.org/rustdoc/lints.html> + + #[expect(rustdoc::broken_intra_doc_links)] + /// I want to link to [`Nonexistent`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + /// <h1> + pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + /// http://example.org + pub fn baz() {} +} + +pub mod rustdoc_warn { + //! See <https://doc.rust-lang.org/rustdoc/lints.html> + + #[expect(rustdoc::broken_intra_doc_links)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + /// I want to link to [`bar`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + /// <h1></h1> + pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + /// <http://example.org> + pub fn baz() {} +} + +mod clippy_ok { + //! See <https://rust-lang.github.io/rust-clippy/master/index.html> + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + b = a; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".bytes().nth(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { + 42 + } else { + 42 + }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + + if a && b || a {} + } +} + +mod clippy_warn { + //! See <https://rust-lang.github.io/rust-clippy/master/index.html> + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".as_bytes().get(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { + 33 + } else { + 42 + }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + let c = false; + + if a && b || c {} + } +} + +fn main() { + rustc_warn::rustc_lints(); +} diff --git a/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr new file mode 100644 index 00000000000..306496b6c85 --- /dev/null +++ b/tests/rustdoc-ui/lints/expect-tool-lint-rfc-2383.stderr @@ -0,0 +1,28 @@ +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:15:11 + | +LL | #![expect(rustdoc::missing_crate_level_docs)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:69:14 + | +LL | #[expect(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:74:14 + | +LL | #[expect(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:79:14 + | +LL | #[expect(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted + diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs new file mode 100644 index 00000000000..46e337cf2b3 --- /dev/null +++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.rs @@ -0,0 +1,8 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes +#![deny(unknown_lints)] +//~^ NOTE defined here +#![allow(rustdoc::missing_doc_code_examples)] +//~^ ERROR unknown lint +//~| NOTE lint is unstable +//~| NOTE see issue +//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr new file mode 100644 index 00000000000..e017b1f34a1 --- /dev/null +++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr @@ -0,0 +1,18 @@ +error: unknown lint: `rustdoc::missing_doc_code_examples` + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:10 + | +LL | #![allow(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the `rustdoc::missing_doc_code_examples` lint is unstable + = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information + = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +note: the lint level is defined here + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:2:9 + | +LL | #![deny(unknown_lints)] + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/inline-doc-link.rs b/tests/rustdoc-ui/lints/inline-doc-link.rs new file mode 100644 index 00000000000..0792bc38af4 --- /dev/null +++ b/tests/rustdoc-ui/lints/inline-doc-link.rs @@ -0,0 +1,13 @@ +// Regression test for <https://github.com/rust-lang/rust/pull/113167> + +//@ check-pass +#![deny(rustdoc::redundant_explicit_links)] + +mod m { + pub enum ValueEnum {} +} +mod m2 { + /// [`ValueEnum`] + pub use crate::m::ValueEnum; +} +pub use m2::ValueEnum; diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs new file mode 100644 index 00000000000..e1cc08ca242 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs @@ -0,0 +1,38 @@ +#![crate_type = "lib"] +#![feature(doc_masked)] + +#![doc(masked)] +//~^ ERROR this attribute can only be applied to an `extern crate` item + +#[doc(test(no_crate_inject))] +//~^ ERROR can only be applied at the crate level +//~| HELP to apply to the crate, use an inner attribute +//~| SUGGESTION ! +#[doc(inline)] +//~^ ERROR can only be applied to a `use` item +pub fn foo() {} + +pub mod bar { + #![doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + + #[doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + #[doc(inline)] + //~^ ERROR can only be applied to a `use` item + pub fn baz() {} +} + +#[doc(inline)] +#[doc(no_inline)] +//~^^ ERROR conflicting doc inlining attributes +//~| HELP remove one of the conflicting attributes +pub use bar::baz; + +#[doc(masked)] +//~^ ERROR this attribute can only be applied to an `extern crate` item +pub struct Masked; + +#[doc(masked)] +//~^ ERROR this attribute cannot be applied to an `extern crate self` item +pub extern crate self as reexport; diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr new file mode 100644 index 00000000000..7621999a8ca --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr @@ -0,0 +1,91 @@ +error: this attribute can only be applied at the crate level + --> $DIR/invalid-doc-attr.rs:7:7 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information + = note: `#[deny(invalid_doc_attributes)]` on by default +help: to apply to the crate, use an inner attribute + | +LL | #![doc(test(no_crate_inject))] + | + + +error: this attribute can only be applied to a `use` item + --> $DIR/invalid-doc-attr.rs:11:7 + | +LL | #[doc(inline)] + | ^^^^^^ only applicable on `use` items +LL | +LL | pub fn foo() {} + | ------------ not a `use` item + | + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information + +error: this attribute can only be applied at the crate level + --> $DIR/invalid-doc-attr.rs:16:12 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information + +error: conflicting doc inlining attributes + --> $DIR/invalid-doc-attr.rs:26:7 + | +LL | #[doc(inline)] + | ^^^^^^ this attribute... +LL | #[doc(no_inline)] + | ^^^^^^^^^ ...conflicts with this attribute + | + = help: remove one of the conflicting attributes + +error: this attribute can only be applied to an `extern crate` item + --> $DIR/invalid-doc-attr.rs:32:7 + | +LL | #[doc(masked)] + | ^^^^^^ only applicable on `extern crate` items +LL | +LL | pub struct Masked; + | ----------------- not an `extern crate` item + | + = note: read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information + +error: this attribute cannot be applied to an `extern crate self` item + --> $DIR/invalid-doc-attr.rs:36:7 + | +LL | #[doc(masked)] + | ^^^^^^ not applicable on `extern crate self` items +LL | +LL | pub extern crate self as reexport; + | --------------------------------- `extern crate self` defined here + +error: this attribute can only be applied to an `extern crate` item + --> $DIR/invalid-doc-attr.rs:4:8 + | +LL | #![doc(masked)] + | ^^^^^^ only applicable on `extern crate` items + | + = note: read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information + +error: this attribute can only be applied at the crate level + --> $DIR/invalid-doc-attr.rs:19:11 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information + +error: this attribute can only be applied to a `use` item + --> $DIR/invalid-doc-attr.rs:21:11 + | +LL | #[doc(inline)] + | ^^^^^^ only applicable on `use` items +LL | +LL | pub fn baz() {} + | ------------ not a `use` item + | + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information + +error: aborting due to 9 previous errors + diff --git a/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs new file mode 100644 index 00000000000..d973a53cbc7 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.rs @@ -0,0 +1,70 @@ +#![deny(rustdoc::invalid_html_tags)] + +/// <p/> +//~^ ERROR invalid self-closing HTML tag `p` +pub struct A; + +/// <p style/> +//~^ ERROR invalid self-closing HTML tag `p` +pub struct B; + +/// <p style=""/> +//~^ ERROR invalid self-closing HTML tag `p` +pub struct C; + +/// <p style="x"/> +//~^ ERROR invalid self-closing HTML tag `p` +pub struct D; + +/// <p style="x/></p> +//~^ ERROR unclosed quoted HTML attribute +pub struct E; + +/// <p style='x/></p> +//~^ ERROR unclosed quoted HTML attribute +pub struct F; + +/// <p style="x/"></p> +pub struct G; + +/// <p style="x/"/> +//~^ ERROR invalid self-closing HTML tag `p` +pub struct H; + +/// <p / > +//~^ ERROR invalid self-closing HTML tag `p` +pub struct I; + +/// <br/> +pub struct J; + +/// <a href=/></a> +pub struct K; + +/// <a href=//></a> +pub struct L; + +/// <a href="/"/> +//~^ ERROR invalid self-closing HTML tag `a` +pub struct M; + +/// <a href=x /> +//~^ ERROR invalid self-closing HTML tag `a` +pub struct N; + +/// <a href= /> +//~^ ERROR invalid self-closing HTML tag `a` +pub struct O; + +/// <a href=x/></a> +pub struct P; + +/// <svg><rect width=1 height=1 /></svg> +pub struct Q; + +/// <svg><rect width=1 height=/></svg> +//~^ ERROR unclosed HTML tag `rect` +pub struct R; + +/// <svg / q> +pub struct S; diff --git a/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr new file mode 100644 index 00000000000..e45edfb43ff --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-self-closing-tag.stderr @@ -0,0 +1,80 @@ +error: invalid self-closing HTML tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:3:5 + | +LL | /// <p/> + | ^^ + | +note: the lint level is defined here + --> $DIR/invalid-html-self-closing-tag.rs:1:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: invalid self-closing HTML tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:7:5 + | +LL | /// <p style/> + | ^^ + +error: invalid self-closing HTML tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:11:5 + | +LL | /// <p style=""/> + | ^^ + +error: invalid self-closing HTML tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:15:5 + | +LL | /// <p style="x"/> + | ^^ + +error: unclosed quoted HTML attribute on tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:19:14 + | +LL | /// <p style="x/></p> + | ^ + +error: unclosed quoted HTML attribute on tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:23:14 + | +LL | /// <p style='x/></p> + | ^ + +error: invalid self-closing HTML tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:30:5 + | +LL | /// <p style="x/"/> + | ^^ + +error: invalid self-closing HTML tag `p` + --> $DIR/invalid-html-self-closing-tag.rs:34:5 + | +LL | /// <p / > + | ^^ + +error: invalid self-closing HTML tag `a` + --> $DIR/invalid-html-self-closing-tag.rs:47:5 + | +LL | /// <a href="/"/> + | ^^ + +error: invalid self-closing HTML tag `a` + --> $DIR/invalid-html-self-closing-tag.rs:51:5 + | +LL | /// <a href=x /> + | ^^ + +error: invalid self-closing HTML tag `a` + --> $DIR/invalid-html-self-closing-tag.rs:55:5 + | +LL | /// <a href= /> + | ^^ + +error: unclosed HTML tag `rect` + --> $DIR/invalid-html-self-closing-tag.rs:65:10 + | +LL | /// <svg><rect width=1 height=/></svg> + | ^^^^^ + +error: aborting due to 12 previous errors + diff --git a/tests/rustdoc-ui/lints/invalid-html-tags.rs b/tests/rustdoc-ui/lints/invalid-html-tags.rs new file mode 100644 index 00000000000..317f1fd1d46 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-tags.rs @@ -0,0 +1,123 @@ +#![deny(rustdoc::invalid_html_tags)] + +//! <p>💩<p> +//~^ ERROR unclosed HTML tag `p` +//~^^ ERROR unclosed HTML tag `p` + +/// <img><input> +/// <script> +/// <img><input> +/// </script> +/// <unknown> +//~^ ERROR unclosed HTML tag `unknown` +/// < ok +/// <script> +//~^ ERROR unclosed HTML tag `script` +pub fn foo() {} + +/// <h1> +/// <h2> +//~^ ERROR unclosed HTML tag `h2` +/// <h3> +//~^ ERROR unclosed HTML tag `h3` +/// </h1> +/// </hello> +//~^ ERROR unopened HTML tag `hello` +pub fn bar() {} + +/// <div> +/// <br/> <p> +//~^ ERROR unclosed HTML tag `p` +/// </div> +pub fn a() {} + +/// <div> +/// <p> +/// <div></div> +/// </p> +/// </div> +pub fn b() {} + +/// <div style="hello"> +//~^ ERROR unclosed HTML tag `div` +/// <h3> +//~^ ERROR unclosed HTML tag `h3` +/// <script +//~^ ERROR unclosed HTML tag `script` +pub fn c() {} + +// Unclosed tags shouldn't warn if they are nested inside a <script> elem. +/// <script> +/// <h3><div> +/// </script> +/// <script> +/// <div> +/// <p> +/// </div> +/// </script> +pub fn d() {} + +// Unclosed tags shouldn't warn if they are nested inside a <style> elem. +/// <style> +/// <h3><div> +/// </style> +/// <stYle> +/// <div> +/// <p> +/// </div> +/// </style> +pub fn e() {} + +// Closing tags need to have ">" at the end, otherwise it's not a closing tag! +/// <div></div > +/// <div></div +//~^ ERROR unclosed HTML tag `div` +pub fn f() {} + +/// <!----> +/// <!-- --> +/// <!-- <div> --> +/// <!-- <!-- --> +pub fn g() {} + +/// <!-- +/// --> +pub fn h() {} + +/// <!-- +//~^ ERROR Unclosed HTML comment +pub fn i() {} + +/// hello +/// +/// ``` +/// uiapp.run(&env::args().collect::<Vec<_>>()); +/// ``` +pub fn j() {} + +// Check that nested codeblocks are working as well +/// hello +/// +/// ``````markdown +/// normal markdown +/// +/// ``` +/// uiapp.run(&env::args().collect::<Vec<_>>()); +/// ``` +/// +/// <Vec<_> shouldn't warn! +/// `````` +pub fn k() {} + +/// Web Components style <dashed-tags> +//~^ ERROR unclosed HTML tag `dashed-tags` +/// Web Components style </unopened-tag> +//~^ ERROR unopened HTML tag `unopened-tag` +pub fn m() {} + +/// backslashed \<a href=""> +pub fn no_error_1() {} + +/// backslashed \<<a href=""> +//~^ ERROR unclosed HTML tag `a` +pub fn p() {} diff --git a/tests/rustdoc-ui/lints/invalid-html-tags.stderr b/tests/rustdoc-ui/lints/invalid-html-tags.stderr new file mode 100644 index 00000000000..9c2bfcf2c3d --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-tags.stderr @@ -0,0 +1,104 @@ +error: unclosed HTML tag `p` + --> $DIR/invalid-html-tags.rs:3:5 + | +LL | //! <p>💩<p> + | ^^^ + | +note: the lint level is defined here + --> $DIR/invalid-html-tags.rs:1:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unclosed HTML tag `p` + --> $DIR/invalid-html-tags.rs:3:9 + | +LL | //! <p>💩<p> + | ^^^ + +error: unclosed HTML tag `unknown` + --> $DIR/invalid-html-tags.rs:11:5 + | +LL | /// <unknown> + | ^^^^^^^^^ + +error: unclosed HTML tag `script` + --> $DIR/invalid-html-tags.rs:14:5 + | +LL | /// <script> + | ^^^^^^^^ + +error: unclosed HTML tag `h2` + --> $DIR/invalid-html-tags.rs:19:7 + | +LL | /// <h2> + | ^^^^ + +error: unclosed HTML tag `h3` + --> $DIR/invalid-html-tags.rs:21:9 + | +LL | /// <h3> + | ^^^^ + +error: unopened HTML tag `hello` + --> $DIR/invalid-html-tags.rs:24:5 + | +LL | /// </hello> + | ^^^^^^^^ + +error: unclosed HTML tag `p` + --> $DIR/invalid-html-tags.rs:29:14 + | +LL | /// <br/> <p> + | ^^^ + +error: unclosed HTML tag `div` + --> $DIR/invalid-html-tags.rs:41:5 + | +LL | /// <div style="hello"> + | ^^^^ + +error: unclosed HTML tag `h3` + --> $DIR/invalid-html-tags.rs:43:7 + | +LL | /// <h3> + | ^^^^ + +error: unclosed HTML tag `script` + --> $DIR/invalid-html-tags.rs:45:5 + | +LL | /// <script + | ^^^^^^ + +error: unclosed HTML tag `div` + --> $DIR/invalid-html-tags.rs:73:5 + | +LL | /// <div></div + | ^^^^^ + +error: Unclosed HTML comment + --> $DIR/invalid-html-tags.rs:87:5 + | +LL | /// <!-- + | ^^^ + +error: unopened HTML tag `unopened-tag` + --> $DIR/invalid-html-tags.rs:114:26 + | +LL | /// Web Components style </unopened-tag> + | ^^^^^^^^^^^^^^^ + +error: unclosed HTML tag `dashed-tags` + --> $DIR/invalid-html-tags.rs:112:26 + | +LL | /// Web Components style <dashed-tags> + | ^^^^^^^^^^^^^ + +error: unclosed HTML tag `a` + --> $DIR/invalid-html-tags.rs:121:19 + | +LL | /// backslashed \<<a href=""> + | ^^ + +error: aborting due to 16 previous errors + diff --git a/tests/rustdoc-ui/lints/lint-group.rs b/tests/rustdoc-ui/lints/lint-group.rs new file mode 100644 index 00000000000..ad88157f64f --- /dev/null +++ b/tests/rustdoc-ui/lints/lint-group.rs @@ -0,0 +1,32 @@ +#![feature(rustdoc_missing_doc_code_examples)] + +//! Documenting the kinds of lints emitted by rustdoc. +//! +//! ``` +//! println!("sup"); +//! ``` + +#![deny(rustdoc::missing_doc_code_examples)] +#![deny(rustdoc::all)] + +/// what up, let's make an [error] +/// +/// ``` +/// println!("sup"); +/// ``` +pub fn link_error() {} //~^^^^^ ERROR unresolved link to `error` + +/// wait, this doesn't have a doctest? +pub fn no_doctest() {} //~^ ERROR missing code example in this documentation + +/// wait, this *does* have a doctest? +/// +/// ``` +/// println!("sup"); +/// ``` +fn private_doctest() {} //~^^^^^ ERROR documentation test in private item + +/// <unknown> +//~^ ERROR unclosed HTML tag `unknown` +//~^^ ERROR missing code example +pub fn c() {} diff --git a/tests/rustdoc-ui/lints/lint-group.stderr b/tests/rustdoc-ui/lints/lint-group.stderr new file mode 100644 index 00000000000..7ff09fcc45a --- /dev/null +++ b/tests/rustdoc-ui/lints/lint-group.stderr @@ -0,0 +1,54 @@ +error: missing code example in this documentation + --> $DIR/lint-group.rs:19:1 + | +LL | /// wait, this doesn't have a doctest? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-group.rs:9:9 + | +LL | #![deny(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: documentation test in private item + --> $DIR/lint-group.rs:22:1 + | +LL | / /// wait, this *does* have a doctest? +LL | | /// +LL | | /// ``` +LL | | /// println!("sup"); +LL | | /// ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/lint-group.rs:10:9 + | +LL | #![deny(rustdoc::all)] + | ^^^^^^^^^^^^ + = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]` + +error: missing code example in this documentation + --> $DIR/lint-group.rs:29:1 + | +LL | /// <unknown> + | ^^^^^^^^^^^^^ + +error: unresolved link to `error` + --> $DIR/lint-group.rs:12:29 + | +LL | /// what up, let's make an [error] + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]` + +error: unclosed HTML tag `unknown` + --> $DIR/lint-group.rs:29:5 + | +LL | /// <unknown> + | ^^^^^^^^^ + | + = note: `#[deny(rustdoc::invalid_html_tags)]` implied by `#[deny(rustdoc::all)]` + +error: aborting due to 5 previous errors + diff --git a/tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs new file mode 100644 index 00000000000..8e5c31d50ed --- /dev/null +++ b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.rs @@ -0,0 +1,101 @@ +#![feature(rustdoc_missing_doc_code_examples)] +#![deny(missing_docs)] +#![deny(rustdoc::missing_doc_code_examples)] + +//! crate level doc +//! ``` +//! println!("hello"): +//! ``` + + +/// doc +/// +/// ``` +/// println!("hello"); +/// ``` +pub fn test() { +} + +#[allow(missing_docs)] +pub mod module1 { +} + +#[allow(rustdoc::missing_doc_code_examples)] +/// doc +pub mod module2 { + + /// doc + pub fn test() {} +} + +/// doc +/// +/// ``` +/// println!("hello"); +/// ``` +pub mod module3 { + + /// doc + //~^ ERROR + pub fn test() {} +} + +/// Doc, but no code example and it's fine! +pub const Const: u32 = 0; +/// Doc, but no code example and it's fine! +pub static Static: u32 = 0; +/// Doc, but no code example and it's fine! +pub type Type = u32; + +/// Doc +//~^ ERROR +pub struct Struct { + /// Doc, but no code example and it's fine! + pub field: u32, +} + +/// Doc +//~^ ERROR +pub enum Enum { + /// Doc, but no code example and it's fine! + X, +} + +/// Doc +//~^ ERROR +#[repr(C)] +pub union Union { + /// Doc, but no code example and it's fine! + a: i32, + /// Doc, but no code example and it's fine! + b: f32, +} + +// no code example and it's fine! +impl Clone for Struct { + fn clone(&self) -> Self { + Self { field: self.field } + } +} + + + +/// doc +/// +/// ``` +/// println!("hello"); +/// ``` +#[derive(Clone)] +pub struct NiceStruct; + +#[doc(hidden)] +pub mod foo { + pub fn bar() {} +} + +fn babar() {} + + +mod fofoo { + pub fn tadam() {} +} diff --git a/tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr new file mode 100644 index 00000000000..22533b9816a --- /dev/null +++ b/tests/rustdoc-ui/lints/lint-missing-doc-code-example.stderr @@ -0,0 +1,32 @@ +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:38:3 + | +LL | /// doc + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-missing-doc-code-example.rs:3:9 + | +LL | #![deny(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:50:1 + | +LL | /// Doc + | ^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:57:1 + | +LL | /// Doc + | ^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:64:1 + | +LL | /// Doc + | ^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs new file mode 100644 index 00000000000..5e7dc377f5d --- /dev/null +++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs @@ -0,0 +1,7 @@ +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +#![deny(rustdoc::missing_crate_level_docs)] +//^~ NOTE defined here + +pub fn foo() {} + +//~? ERROR no documentation found for this crate's top-level module diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr new file mode 100644 index 00000000000..721d3662c93 --- /dev/null +++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr @@ -0,0 +1,12 @@ +error: no documentation found for this crate's top-level module + | + = help: The following guide may be of use: + https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html +note: the lint level is defined here + --> $DIR/no-crate-level-doc-lint.rs:2:9 + | +LL | #![deny(rustdoc::missing_crate_level_docs)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/no-redundancy.rs b/tests/rustdoc-ui/lints/no-redundancy.rs new file mode 100644 index 00000000000..6609ce6a4f8 --- /dev/null +++ b/tests/rustdoc-ui/lints/no-redundancy.rs @@ -0,0 +1,7 @@ +//@ check-pass + +#![deny(rustdoc::redundant_explicit_links)] + +/// [Vec][std::vec::Vec#examples] should not warn, because it's not actually redundant! +/// [This is just an `Option`][std::option::Option] has different display content to actual link! +pub fn func() {} diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-expansion.rs b/tests/rustdoc-ui/lints/redundant_explicit_links-expansion.rs new file mode 100644 index 00000000000..2e42a0a5c5d --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links-expansion.rs @@ -0,0 +1,40 @@ +// This is a regression test for <https://github.com/rust-lang/rust/issues/141553>. +// If the link is generated from expansion, we should not emit the lint. + +#![deny(rustdoc::redundant_explicit_links)] + +macro_rules! mac1 { + () => { + "provided by a [`BufferProvider`](crate::BufferProvider)." + }; +} + +macro_rules! mac2 { + () => { + #[doc = mac1!()] + pub struct BufferProvider; + } +} + +macro_rules! mac3 { + () => { + "Provided by" + }; +} + +// Should not lint. +#[doc = mac1!()] +pub struct Foo; + +// Should not lint. +mac2!{} + +#[doc = "provided by a [`BufferProvider`](crate::BufferProvider)."] +/// bla +//~^^ ERROR: redundant_explicit_links +pub struct Bla; + +#[doc = mac3!()] +/// a [`BufferProvider`](crate::BufferProvider). +//~^ ERROR: redundant_explicit_links +pub fn f() {} diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-expansion.stderr b/tests/rustdoc-ui/lints/redundant_explicit_links-expansion.stderr new file mode 100644 index 00000000000..a81931fb073 --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links-expansion.stderr @@ -0,0 +1,39 @@ +error: redundant explicit link target + --> $DIR/redundant_explicit_links-expansion.rs:32:43 + | +LL | #[doc = "provided by a [`BufferProvider`](crate::BufferProvider)."] + | ---------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +note: the lint level is defined here + --> $DIR/redundant_explicit_links-expansion.rs:4:9 + | +LL | #![deny(rustdoc::redundant_explicit_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: remove explicit link target + | +LL - #[doc = "provided by a [`BufferProvider`](crate::BufferProvider)."] +LL + #[doc = "provided by a [`BufferProvider`]."] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links-expansion.rs:38:26 + | +LL | /// a [`BufferProvider`](crate::BufferProvider). + | ---------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// a [`BufferProvider`](crate::BufferProvider). +LL + /// a [`BufferProvider`]. + | + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs new file mode 100644 index 00000000000..4f4590d45fc --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs @@ -0,0 +1,18 @@ +//@ check-pass + +/// [`…foo`] [`…bar`] [`Err`] +pub struct Broken {} + +/// [`…`] [`…`] [`Err`] +pub struct Broken2 {} + +/// [`…`][…] [`…`][…] [`Err`] +pub struct Broken3 {} + +/// […………………………][Broken3] +pub struct Broken4 {} + +/// [Broken3][…………………………] +pub struct Broken5 {} + +pub struct Err; diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links.fixed b/tests/rustdoc-ui/lints/redundant_explicit_links.fixed new file mode 100644 index 00000000000..c40c5691e60 --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links.fixed @@ -0,0 +1,158 @@ +//@ run-rustfix + +#![deny(rustdoc::redundant_explicit_links)] + +pub fn dummy_target() {} + +/// [dummy_target] +//~^ ERROR redundant explicit link target +/// [`dummy_target`] +//~^ ERROR redundant explicit link target +/// +/// [Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`] +//~^ ERROR redundant explicit link target +/// [Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`] +//~^ ERROR redundant explicit link target +/// +/// [usize] +//~^ ERROR redundant explicit link target +/// [`usize`] +//~^ ERROR redundant explicit link target +/// [usize] +//~^ ERROR redundant explicit link target +/// [`usize`] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`] +//~^ ERROR redundant explicit link target +/// +/// [dummy_target] TEXT +//~^ ERROR redundant explicit link target +/// [`dummy_target`] TEXT +//~^ ERROR redundant explicit link target +pub fn should_warn_inline() {} + +/// [`Vec<T>`](Vec) +/// [`Vec<T>`](std::vec::Vec) +pub fn should_not_warn_inline() {} + +/// [dummy_target] +//~^ ERROR redundant explicit link target +/// [`dummy_target`] +//~^ ERROR redundant explicit link target +/// +/// [Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`] +//~^ ERROR redundant explicit link target +/// [Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`] +//~^ ERROR redundant explicit link target +/// +/// [usize] +//~^ ERROR redundant explicit link target +/// [`usize`] +//~^ ERROR redundant explicit link target +/// [usize] +//~^ ERROR redundant explicit link target +/// [`usize`] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`] +//~^ ERROR redundant explicit link target +/// +/// [dummy_target] TEXT +//~^ ERROR redundant explicit link target +/// [`dummy_target`] TEXT +//~^ ERROR redundant explicit link target +pub fn should_warn_reference_unknown() {} + +/// [`Vec<T>`][Vec] +/// [`Vec<T>`][std::vec::Vec] +pub fn should_not_warn_reference_unknown() {} + +/// [dummy_target] +//~^ ERROR redundant explicit link target +/// [`dummy_target`] +//~^ ERROR redundant explicit link target +/// +/// [Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`] +//~^ ERROR redundant explicit link target +/// [Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`] +//~^ ERROR redundant explicit link target +/// +/// [usize] +//~^ ERROR redundant explicit link target +/// [`usize`] +//~^ ERROR redundant explicit link target +/// [usize] +//~^ ERROR redundant explicit link target +/// [`usize`] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`] +//~^ ERROR redundant explicit link target +/// +/// [dummy_target] TEXT +//~^ ERROR redundant explicit link target +/// [`dummy_target`] TEXT +//~^ ERROR redundant explicit link target +/// +/// [dummy_target]: dummy_target +/// [Vec]: Vec +/// [std::vec::Vec]: Vec +/// [usize]: usize +/// [std::primitive::usize]: usize +pub fn should_warn_reference() {} + +/// [`Vec<T>`]: Vec +/// [`Vec<T>`]: std::vec::Vec +pub fn should_not_warn_reference() {} diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links.rs b/tests/rustdoc-ui/lints/redundant_explicit_links.rs new file mode 100644 index 00000000000..dc64a5613fb --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links.rs @@ -0,0 +1,158 @@ +//@ run-rustfix + +#![deny(rustdoc::redundant_explicit_links)] + +pub fn dummy_target() {} + +/// [dummy_target](dummy_target) +//~^ ERROR redundant explicit link target +/// [`dummy_target`](dummy_target) +//~^ ERROR redundant explicit link target +/// +/// [Vec](Vec) +//~^ ERROR redundant explicit link target +/// [`Vec`](Vec) +//~^ ERROR redundant explicit link target +/// [Vec](std::vec::Vec) +//~^ ERROR redundant explicit link target +/// [`Vec`](std::vec::Vec) +//~^ ERROR redundant explicit link target +/// [std::vec::Vec](Vec) +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`](Vec) +//~^ ERROR redundant explicit link target +/// [std::vec::Vec](std::vec::Vec) +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`](std::vec::Vec) +//~^ ERROR redundant explicit link target +/// +/// [usize](usize) +//~^ ERROR redundant explicit link target +/// [`usize`](usize) +//~^ ERROR redundant explicit link target +/// [usize](std::primitive::usize) +//~^ ERROR redundant explicit link target +/// [`usize`](std::primitive::usize) +//~^ ERROR redundant explicit link target +/// [std::primitive::usize](usize) +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`](usize) +//~^ ERROR redundant explicit link target +/// [std::primitive::usize](std::primitive::usize) +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`](std::primitive::usize) +//~^ ERROR redundant explicit link target +/// +/// [dummy_target](dummy_target) TEXT +//~^ ERROR redundant explicit link target +/// [`dummy_target`](dummy_target) TEXT +//~^ ERROR redundant explicit link target +pub fn should_warn_inline() {} + +/// [`Vec<T>`](Vec) +/// [`Vec<T>`](std::vec::Vec) +pub fn should_not_warn_inline() {} + +/// [dummy_target][dummy_target] +//~^ ERROR redundant explicit link target +/// [`dummy_target`][dummy_target] +//~^ ERROR redundant explicit link target +/// +/// [Vec][Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`][Vec] +//~^ ERROR redundant explicit link target +/// [Vec][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec][Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`][Vec] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// +/// [usize][usize] +//~^ ERROR redundant explicit link target +/// [`usize`][usize] +//~^ ERROR redundant explicit link target +/// [usize][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`usize`][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize][usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`][usize] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// +/// [dummy_target][dummy_target] TEXT +//~^ ERROR redundant explicit link target +/// [`dummy_target`][dummy_target] TEXT +//~^ ERROR redundant explicit link target +pub fn should_warn_reference_unknown() {} + +/// [`Vec<T>`][Vec] +/// [`Vec<T>`][std::vec::Vec] +pub fn should_not_warn_reference_unknown() {} + +/// [dummy_target][dummy_target] +//~^ ERROR redundant explicit link target +/// [`dummy_target`][dummy_target] +//~^ ERROR redundant explicit link target +/// +/// [Vec][Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`][Vec] +//~^ ERROR redundant explicit link target +/// [Vec][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`Vec`][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec][Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`][Vec] +//~^ ERROR redundant explicit link target +/// [std::vec::Vec][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// [`std::vec::Vec`][std::vec::Vec] +//~^ ERROR redundant explicit link target +/// +/// [usize][usize] +//~^ ERROR redundant explicit link target +/// [`usize`][usize] +//~^ ERROR redundant explicit link target +/// [usize][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`usize`][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize][usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`][usize] +//~^ ERROR redundant explicit link target +/// [std::primitive::usize][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// [`std::primitive::usize`][std::primitive::usize] +//~^ ERROR redundant explicit link target +/// +/// [dummy_target][dummy_target] TEXT +//~^ ERROR redundant explicit link target +/// [`dummy_target`][dummy_target] TEXT +//~^ ERROR redundant explicit link target +/// +/// [dummy_target]: dummy_target +/// [Vec]: Vec +/// [std::vec::Vec]: Vec +/// [usize]: usize +/// [std::primitive::usize]: usize +pub fn should_warn_reference() {} + +/// [`Vec<T>`]: Vec +/// [`Vec<T>`]: std::vec::Vec +pub fn should_not_warn_reference() {} diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links.stderr b/tests/rustdoc-ui/lints/redundant_explicit_links.stderr new file mode 100644 index 00000000000..f90c41af9f1 --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links.stderr @@ -0,0 +1,1067 @@ +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:7:20 + | +LL | /// [dummy_target](dummy_target) + | ------------ ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +note: the lint level is defined here + --> $DIR/redundant_explicit_links.rs:3:9 + | +LL | #![deny(rustdoc::redundant_explicit_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: remove explicit link target + | +LL - /// [dummy_target](dummy_target) +LL + /// [dummy_target] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:9:22 + | +LL | /// [`dummy_target`](dummy_target) + | -------------- ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`dummy_target`](dummy_target) +LL + /// [`dummy_target`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:12:11 + | +LL | /// [Vec](Vec) + | --- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [Vec](Vec) +LL + /// [Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:14:13 + | +LL | /// [`Vec`](Vec) + | ----- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`Vec`](Vec) +LL + /// [`Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:16:11 + | +LL | /// [Vec](std::vec::Vec) + | --- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [Vec](std::vec::Vec) +LL + /// [Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:18:13 + | +LL | /// [`Vec`](std::vec::Vec) + | ----- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`Vec`](std::vec::Vec) +LL + /// [`Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:20:21 + | +LL | /// [std::vec::Vec](Vec) + | ------------- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::vec::Vec](Vec) +LL + /// [std::vec::Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:22:23 + | +LL | /// [`std::vec::Vec`](Vec) + | --------------- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::vec::Vec`](Vec) +LL + /// [`std::vec::Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:24:21 + | +LL | /// [std::vec::Vec](std::vec::Vec) + | ------------- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::vec::Vec](std::vec::Vec) +LL + /// [std::vec::Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:26:23 + | +LL | /// [`std::vec::Vec`](std::vec::Vec) + | --------------- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::vec::Vec`](std::vec::Vec) +LL + /// [`std::vec::Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:29:13 + | +LL | /// [usize](usize) + | ----- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [usize](usize) +LL + /// [usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:31:15 + | +LL | /// [`usize`](usize) + | ------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`usize`](usize) +LL + /// [`usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:33:13 + | +LL | /// [usize](std::primitive::usize) + | ----- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [usize](std::primitive::usize) +LL + /// [usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:35:15 + | +LL | /// [`usize`](std::primitive::usize) + | ------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`usize`](std::primitive::usize) +LL + /// [`usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:37:29 + | +LL | /// [std::primitive::usize](usize) + | --------------------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::primitive::usize](usize) +LL + /// [std::primitive::usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:39:31 + | +LL | /// [`std::primitive::usize`](usize) + | ----------------------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::primitive::usize`](usize) +LL + /// [`std::primitive::usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:41:29 + | +LL | /// [std::primitive::usize](std::primitive::usize) + | --------------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::primitive::usize](std::primitive::usize) +LL + /// [std::primitive::usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:43:31 + | +LL | /// [`std::primitive::usize`](std::primitive::usize) + | ----------------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::primitive::usize`](std::primitive::usize) +LL + /// [`std::primitive::usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:46:20 + | +LL | /// [dummy_target](dummy_target) TEXT + | ------------ ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [dummy_target](dummy_target) TEXT +LL + /// [dummy_target] TEXT + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:48:22 + | +LL | /// [`dummy_target`](dummy_target) TEXT + | -------------- ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`dummy_target`](dummy_target) TEXT +LL + /// [`dummy_target`] TEXT + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:56:20 + | +LL | /// [dummy_target][dummy_target] + | ------------ ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [dummy_target][dummy_target] +LL + /// [dummy_target] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:58:22 + | +LL | /// [`dummy_target`][dummy_target] + | -------------- ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`dummy_target`][dummy_target] +LL + /// [`dummy_target`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:61:11 + | +LL | /// [Vec][Vec] + | --- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [Vec][Vec] +LL + /// [Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:63:13 + | +LL | /// [`Vec`][Vec] + | ----- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`Vec`][Vec] +LL + /// [`Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:65:11 + | +LL | /// [Vec][std::vec::Vec] + | --- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [Vec][std::vec::Vec] +LL + /// [Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:67:13 + | +LL | /// [`Vec`][std::vec::Vec] + | ----- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`Vec`][std::vec::Vec] +LL + /// [`Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:69:21 + | +LL | /// [std::vec::Vec][Vec] + | ------------- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::vec::Vec][Vec] +LL + /// [std::vec::Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:71:23 + | +LL | /// [`std::vec::Vec`][Vec] + | --------------- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::vec::Vec`][Vec] +LL + /// [`std::vec::Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:73:21 + | +LL | /// [std::vec::Vec][std::vec::Vec] + | ------------- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::vec::Vec][std::vec::Vec] +LL + /// [std::vec::Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:75:23 + | +LL | /// [`std::vec::Vec`][std::vec::Vec] + | --------------- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::vec::Vec`][std::vec::Vec] +LL + /// [`std::vec::Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:78:13 + | +LL | /// [usize][usize] + | ----- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [usize][usize] +LL + /// [usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:80:15 + | +LL | /// [`usize`][usize] + | ------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`usize`][usize] +LL + /// [`usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:82:13 + | +LL | /// [usize][std::primitive::usize] + | ----- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [usize][std::primitive::usize] +LL + /// [usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:84:15 + | +LL | /// [`usize`][std::primitive::usize] + | ------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`usize`][std::primitive::usize] +LL + /// [`usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:86:29 + | +LL | /// [std::primitive::usize][usize] + | --------------------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::primitive::usize][usize] +LL + /// [std::primitive::usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:88:31 + | +LL | /// [`std::primitive::usize`][usize] + | ----------------------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::primitive::usize`][usize] +LL + /// [`std::primitive::usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:90:29 + | +LL | /// [std::primitive::usize][std::primitive::usize] + | --------------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::primitive::usize][std::primitive::usize] +LL + /// [std::primitive::usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:92:31 + | +LL | /// [`std::primitive::usize`][std::primitive::usize] + | ----------------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::primitive::usize`][std::primitive::usize] +LL + /// [`std::primitive::usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:95:20 + | +LL | /// [dummy_target][dummy_target] TEXT + | ------------ ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [dummy_target][dummy_target] TEXT +LL + /// [dummy_target] TEXT + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:97:22 + | +LL | /// [`dummy_target`][dummy_target] TEXT + | -------------- ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`dummy_target`][dummy_target] TEXT +LL + /// [`dummy_target`] TEXT + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:105:20 + | +LL | /// [dummy_target][dummy_target] + | ------------ ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:149:21 + | +LL | /// [dummy_target]: dummy_target + | ^^^^^^^^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [dummy_target][dummy_target] +LL + /// [dummy_target] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:107:22 + | +LL | /// [`dummy_target`][dummy_target] + | -------------- ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:149:21 + | +LL | /// [dummy_target]: dummy_target + | ^^^^^^^^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`dummy_target`][dummy_target] +LL + /// [`dummy_target`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:110:11 + | +LL | /// [Vec][Vec] + | --- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:150:12 + | +LL | /// [Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [Vec][Vec] +LL + /// [Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:112:13 + | +LL | /// [`Vec`][Vec] + | ----- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:150:12 + | +LL | /// [Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`Vec`][Vec] +LL + /// [`Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:114:11 + | +LL | /// [Vec][std::vec::Vec] + | --- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:151:22 + | +LL | /// [std::vec::Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [Vec][std::vec::Vec] +LL + /// [Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:116:13 + | +LL | /// [`Vec`][std::vec::Vec] + | ----- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:151:22 + | +LL | /// [std::vec::Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`Vec`][std::vec::Vec] +LL + /// [`Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:118:21 + | +LL | /// [std::vec::Vec][Vec] + | ------------- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:150:12 + | +LL | /// [Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::vec::Vec][Vec] +LL + /// [std::vec::Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:120:23 + | +LL | /// [`std::vec::Vec`][Vec] + | --------------- ^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:150:12 + | +LL | /// [Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::vec::Vec`][Vec] +LL + /// [`std::vec::Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:122:21 + | +LL | /// [std::vec::Vec][std::vec::Vec] + | ------------- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:151:22 + | +LL | /// [std::vec::Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::vec::Vec][std::vec::Vec] +LL + /// [std::vec::Vec] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:124:23 + | +LL | /// [`std::vec::Vec`][std::vec::Vec] + | --------------- ^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:151:22 + | +LL | /// [std::vec::Vec]: Vec + | ^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::vec::Vec`][std::vec::Vec] +LL + /// [`std::vec::Vec`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:127:13 + | +LL | /// [usize][usize] + | ----- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:152:14 + | +LL | /// [usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [usize][usize] +LL + /// [usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:129:15 + | +LL | /// [`usize`][usize] + | ------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:152:14 + | +LL | /// [usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`usize`][usize] +LL + /// [`usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:131:13 + | +LL | /// [usize][std::primitive::usize] + | ----- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:153:30 + | +LL | /// [std::primitive::usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [usize][std::primitive::usize] +LL + /// [usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:133:15 + | +LL | /// [`usize`][std::primitive::usize] + | ------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:153:30 + | +LL | /// [std::primitive::usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`usize`][std::primitive::usize] +LL + /// [`usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:135:29 + | +LL | /// [std::primitive::usize][usize] + | --------------------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:152:14 + | +LL | /// [usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::primitive::usize][usize] +LL + /// [std::primitive::usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:137:31 + | +LL | /// [`std::primitive::usize`][usize] + | ----------------------- ^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:152:14 + | +LL | /// [usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::primitive::usize`][usize] +LL + /// [`std::primitive::usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:139:29 + | +LL | /// [std::primitive::usize][std::primitive::usize] + | --------------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:153:30 + | +LL | /// [std::primitive::usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [std::primitive::usize][std::primitive::usize] +LL + /// [std::primitive::usize] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:141:31 + | +LL | /// [`std::primitive::usize`][std::primitive::usize] + | ----------------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:153:30 + | +LL | /// [std::primitive::usize]: usize + | ^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`std::primitive::usize`][std::primitive::usize] +LL + /// [`std::primitive::usize`] + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:144:20 + | +LL | /// [dummy_target][dummy_target] TEXT + | ------------ ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:149:21 + | +LL | /// [dummy_target]: dummy_target + | ^^^^^^^^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [dummy_target][dummy_target] TEXT +LL + /// [dummy_target] TEXT + | + +error: redundant explicit link target + --> $DIR/redundant_explicit_links.rs:146:22 + | +LL | /// [`dummy_target`][dummy_target] TEXT + | -------------- ^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | +note: referenced explicit link target defined here + --> $DIR/redundant_explicit_links.rs:149:21 + | +LL | /// [dummy_target]: dummy_target + | ^^^^^^^^^^^^ + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +help: remove explicit link target + | +LL - /// [`dummy_target`][dummy_target] TEXT +LL + /// [`dummy_target`] TEXT + | + +error: aborting due to 60 previous errors + diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs b/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs new file mode 100644 index 00000000000..a4d3a4b4971 --- /dev/null +++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.rs @@ -0,0 +1,10 @@ +// compile-args: --crate-type lib +#![deny(broken_intra_doc_links)] +//~^ WARNING renamed to `rustdoc::broken_intra_doc_links` +//! [x] +//~^ ERROR unresolved link + +#![deny(rustdoc::non_autolinks)] +//~^ WARNING renamed to `rustdoc::bare_urls` +//! http://example.com +//~^ ERROR not a hyperlink diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr new file mode 100644 index 00000000000..88807dfb495 --- /dev/null +++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr @@ -0,0 +1,46 @@ +warning: lint `broken_intra_doc_links` has been renamed to `rustdoc::broken_intra_doc_links` + --> $DIR/renamed-lint-still-applies.rs:2:9 + | +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links` + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +warning: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls` + --> $DIR/renamed-lint-still-applies.rs:7:9 + | +LL | #![deny(rustdoc::non_autolinks)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls` + +error: unresolved link to `x` + --> $DIR/renamed-lint-still-applies.rs:4:6 + | +LL | //! [x] + | ^ no item named `x` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/renamed-lint-still-applies.rs:2:9 + | +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: this URL is not a hyperlink + --> $DIR/renamed-lint-still-applies.rs:9:5 + | +LL | //! http://example.com + | ^^^^^^^^^^^^^^^^^^ + | + = note: bare URLs are not automatically turned into clickable links +note: the lint level is defined here + --> $DIR/renamed-lint-still-applies.rs:7:9 + | +LL | #![deny(rustdoc::non_autolinks)] + | ^^^^^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | //! <http://example.com> + | + + + +error: aborting due to 2 previous errors; 2 warnings emitted + diff --git a/tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs b/tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs new file mode 100644 index 00000000000..d628867cb9b --- /dev/null +++ b/tests/rustdoc-ui/lints/rustdoc-all-only-stable-lints.rs @@ -0,0 +1,6 @@ +//@ check-pass + +// Ensure `rustdoc::all` only affects stable lints. See #106289. + +#![deny(unknown_lints)] +#![allow(rustdoc::all)] diff --git a/tests/rustdoc-ui/lints/unknown-renamed-lints.rs b/tests/rustdoc-ui/lints/unknown-renamed-lints.rs new file mode 100644 index 00000000000..ddf03dd079f --- /dev/null +++ b/tests/rustdoc-ui/lints/unknown-renamed-lints.rs @@ -0,0 +1,24 @@ +#![deny(unknown_lints)] +//~^ NOTE lint level is defined +#![deny(renamed_and_removed_lints)] +//~^ NOTE lint level is defined +#![deny(x)] +//~^ ERROR unknown lint +#![deny(rustdoc::x)] +//~^ ERROR unknown lint: `rustdoc::x` +#![deny(intra_doc_link_resolution_failure)] +//~^ ERROR renamed to `rustdoc::broken_intra_doc_links` +#![deny(non_autolinks)] +//~^ ERROR renamed to `rustdoc::bare_urls` +#![deny(rustdoc::non_autolinks)] +//~^ ERROR renamed to `rustdoc::bare_urls` + +#![deny(private_doc_tests)] +//~^ ERROR renamed to `rustdoc::private_doc_tests` + +#![deny(rustdoc)] +//~^ ERROR removed: use `rustdoc::all` instead + +// Explicitly don't try to handle this case, it was never valid +#![deny(rustdoc::intra_doc_link_resolution_failure)] +//~^ ERROR unknown lint diff --git a/tests/rustdoc-ui/lints/unknown-renamed-lints.stderr b/tests/rustdoc-ui/lints/unknown-renamed-lints.stderr new file mode 100644 index 00000000000..bf529b9f8e2 --- /dev/null +++ b/tests/rustdoc-ui/lints/unknown-renamed-lints.stderr @@ -0,0 +1,62 @@ +error: unknown lint: `x` + --> $DIR/unknown-renamed-lints.rs:5:9 + | +LL | #![deny(x)] + | ^ + | +note: the lint level is defined here + --> $DIR/unknown-renamed-lints.rs:1:9 + | +LL | #![deny(unknown_lints)] + | ^^^^^^^^^^^^^ + +error: unknown lint: `rustdoc::x` + --> $DIR/unknown-renamed-lints.rs:7:9 + | +LL | #![deny(rustdoc::x)] + | ^^^^^^^^^^ help: did you mean: `rustdoc::all` + +error: lint `intra_doc_link_resolution_failure` has been renamed to `rustdoc::broken_intra_doc_links` + --> $DIR/unknown-renamed-lints.rs:9:9 + | +LL | #![deny(intra_doc_link_resolution_failure)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links` + | +note: the lint level is defined here + --> $DIR/unknown-renamed-lints.rs:3:9 + | +LL | #![deny(renamed_and_removed_lints)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: lint `non_autolinks` has been renamed to `rustdoc::bare_urls` + --> $DIR/unknown-renamed-lints.rs:11:9 + | +LL | #![deny(non_autolinks)] + | ^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls` + +error: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls` + --> $DIR/unknown-renamed-lints.rs:13:9 + | +LL | #![deny(rustdoc::non_autolinks)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls` + +error: lint `private_doc_tests` has been renamed to `rustdoc::private_doc_tests` + --> $DIR/unknown-renamed-lints.rs:16:9 + | +LL | #![deny(private_doc_tests)] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::private_doc_tests` + +error: lint `rustdoc` has been removed: use `rustdoc::all` instead + --> $DIR/unknown-renamed-lints.rs:19:9 + | +LL | #![deny(rustdoc)] + | ^^^^^^^ + +error: unknown lint: `rustdoc::intra_doc_link_resolution_failure` + --> $DIR/unknown-renamed-lints.rs:23:9 + | +LL | #![deny(rustdoc::intra_doc_link_resolution_failure)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/rustdoc-ui/lints/unused-braces-lint.rs b/tests/rustdoc-ui/lints/unused-braces-lint.rs new file mode 100644 index 00000000000..fc5dcbf4d74 --- /dev/null +++ b/tests/rustdoc-ui/lints/unused-braces-lint.rs @@ -0,0 +1,14 @@ +//@ check-pass + +// This tests the bug in #70814, where the unused_braces lint triggered on the following code +// without providing a span. + +#![deny(unused_braces)] + +fn main() { + { + { + use std; + } + } +} diff --git a/tests/rustdoc-ui/lints/unused.rs b/tests/rustdoc-ui/lints/unused.rs new file mode 100644 index 00000000000..f52f4c9c9e3 --- /dev/null +++ b/tests/rustdoc-ui/lints/unused.rs @@ -0,0 +1,14 @@ +//@ check-pass + +// This test purpose is to check that unused_imports lint isn't fired +// by rustdoc. Why would it? Because when rustdoc is running, it uses +// "everybody-loops" which replaces parts of code with "loop {}" to get +// huge performance improvements. + +#![deny(unused_imports)] + +use std::fs::File; + +pub fn f() { + let _: File; +} diff --git a/tests/rustdoc-ui/macro-docs.rs b/tests/rustdoc-ui/macro-docs.rs new file mode 100644 index 00000000000..f7040289e03 --- /dev/null +++ b/tests/rustdoc-ui/macro-docs.rs @@ -0,0 +1,12 @@ +//@ check-pass + +macro_rules! m { + () => { + /// A + //~^ WARNING + #[path = "auxiliary/module_macro_doc.rs"] + pub mod mymodule; + } +} + +m!(); diff --git a/tests/rustdoc-ui/macro-docs.stderr b/tests/rustdoc-ui/macro-docs.stderr new file mode 100644 index 00000000000..2b136f5be16 --- /dev/null +++ b/tests/rustdoc-ui/macro-docs.stderr @@ -0,0 +1,20 @@ +warning: unresolved link to `long_cat` + --> $DIR/macro-docs.rs:5:9 + | +LL | /// A + | ^^^^^ +... +LL | m!(); + | ---- in this macro invocation + | + = note: the link appears in this line: + + [`long_cat`] is really long + ^^^^^^^^^^ + = note: no item named `long_cat` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 1 warning emitted + diff --git a/tests/rustdoc-ui/mismatched_arg_count.rs b/tests/rustdoc-ui/mismatched_arg_count.rs new file mode 100644 index 00000000000..7841442987b --- /dev/null +++ b/tests/rustdoc-ui/mismatched_arg_count.rs @@ -0,0 +1,8 @@ +trait Trait<'a> { + type Assoc; +} + +type Alias<'a, T> = <T as Trait<'a>>::Assoc; + +fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} +//~^ error: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied diff --git a/tests/rustdoc-ui/mismatched_arg_count.stderr b/tests/rustdoc-ui/mismatched_arg_count.stderr new file mode 100644 index 00000000000..5daeef2eb18 --- /dev/null +++ b/tests/rustdoc-ui/mismatched_arg_count.stderr @@ -0,0 +1,17 @@ +error[E0107]: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/mismatched_arg_count.rs:7:29 + | +LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} + | ^^^^^ ---- help: remove the lifetime argument + | | + | expected 1 lifetime argument + | +note: type alias defined here, with 1 lifetime parameter: `'a` + --> $DIR/mismatched_arg_count.rs:5:6 + | +LL | type Alias<'a, T> = <T as Trait<'a>>::Assoc; + | ^^^^^ -- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/rustdoc-ui/multi-par-footnote.rs b/tests/rustdoc-ui/multi-par-footnote.rs new file mode 100644 index 00000000000..bb6a85db0db --- /dev/null +++ b/tests/rustdoc-ui/multi-par-footnote.rs @@ -0,0 +1,18 @@ +//@ check-pass +//@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +// Regression test for #139064. + +/// Example +/// +/// Footnote with multiple paragraphs[^multiple] +/// +/// [^multiple]: +/// One +/// +/// Two +/// +/// Three +pub fn add(left: u64, right: u64) -> u64 { + left + right +} diff --git a/tests/rustdoc-ui/multi-par-footnote.stdout b/tests/rustdoc-ui/multi-par-footnote.stdout new file mode 100644 index 00000000000..7326c0a25a0 --- /dev/null +++ b/tests/rustdoc-ui/multi-par-footnote.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/nested-extern-crate-46271.rs b/tests/rustdoc-ui/nested-extern-crate-46271.rs new file mode 100644 index 00000000000..9efc8063f92 --- /dev/null +++ b/tests/rustdoc-ui/nested-extern-crate-46271.rs @@ -0,0 +1,8 @@ +//@ check-pass +// hopefully this doesn't cause an ICE + +// https://github.com/rust-lang/rust/issues/46271 + +pub fn foo() { + extern crate std; +} diff --git a/tests/rustdoc-ui/nested-macro-rules-47639.rs b/tests/rustdoc-ui/nested-macro-rules-47639.rs new file mode 100644 index 00000000000..32c4e7b10b4 --- /dev/null +++ b/tests/rustdoc-ui/nested-macro-rules-47639.rs @@ -0,0 +1,9 @@ +//@ check-pass +// This should not ICE + +// https://github.com/rust-lang/rust/issues/47639 +pub fn test() { + macro_rules! foo { + () => () + } +} diff --git a/tests/rustdoc-ui/normalize-cycle.rs b/tests/rustdoc-ui/normalize-cycle.rs new file mode 100644 index 00000000000..35c03df0ca9 --- /dev/null +++ b/tests/rustdoc-ui/normalize-cycle.rs @@ -0,0 +1,26 @@ +//@ check-pass +//@ compile-flags: -Znormalize-docs +// Regression test for <https://github.com/rust-lang/rust/issues/79459>. +pub trait Query {} + +pub trait AsQuery { + type Query; +} + +impl<T: Query> AsQuery for T { + type Query = T; +} + +pub trait SelectDsl<Selection> { + type Output; +} + +impl<T, Selection> SelectDsl<Selection> for T +where + T: AsQuery, + T::Query: SelectDsl<Selection>, +{ + type Output = <T::Query as SelectDsl<Selection>>::Output; +} + +pub type Select<Source, Selection> = <Source as SelectDsl<Selection>>::Output; diff --git a/tests/rustdoc-ui/normalize-in-inlined-type-alias.rs b/tests/rustdoc-ui/normalize-in-inlined-type-alias.rs new file mode 100644 index 00000000000..2f92f173c35 --- /dev/null +++ b/tests/rustdoc-ui/normalize-in-inlined-type-alias.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ compile-flags: -Znormalize-docs + +trait Woo<T> { + type Assoc; +} + +impl<T> Woo<T> for () { + type Assoc = (); +} + +type Alias<P> = <() as Woo<P>>::Assoc; + +pub fn hello<S>() -> Alias<S> {} diff --git a/tests/rustdoc-ui/normalize-overflow.rs b/tests/rustdoc-ui/normalize-overflow.rs new file mode 100644 index 00000000000..30b0d2f26e8 --- /dev/null +++ b/tests/rustdoc-ui/normalize-overflow.rs @@ -0,0 +1,5 @@ +//@ aux-crate:overflow=overflow.rs +//@ check-pass +// Regression test for <https://github.com/rust-lang/rust/issues/79506>. + +extern crate overflow; diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs new file mode 100644 index 00000000000..9f7d6db5d26 --- /dev/null +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Znormalize-docs + +#![feature(type_alias_impl_trait)] + +trait Allocator { + type Buffer; +} + +struct DefaultAllocator; + +// This unconstrained impl parameter causes the normalization of +// `<DefaultAllocator as Allocator>::Buffer` to be ambiguous, +// which caused an ICE with `-Znormalize-docs`. +impl<T> Allocator for DefaultAllocator { + //~^ ERROR: the type parameter `T` is not constrained + type Buffer = (); +} + +type A = impl Fn(<DefaultAllocator as Allocator>::Buffer); + +fn foo() -> A { + |_| () +} + +fn main() {} diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr new file mode 100644 index 00000000000..55ab144b924 --- /dev/null +++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/not-wf-ambiguous-normalization.rs:14:6 + | +LL | impl<T> Allocator for DefaultAllocator { + | ^ unconstrained type parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/rustdoc-ui/output-format-html-stable.rs b/tests/rustdoc-ui/output-format-html-stable.rs new file mode 100644 index 00000000000..f178c51a714 --- /dev/null +++ b/tests/rustdoc-ui/output-format-html-stable.rs @@ -0,0 +1,4 @@ +//@ compile-flags: --output-format html +//@ check-pass +// This tests that `--output-format html` is accepted without `-Z unstable-options`, +// since it has been stable since 1.0. diff --git a/tests/rustdoc-ui/private-type-cycle-110629.rs b/tests/rustdoc-ui/private-type-cycle-110629.rs new file mode 100644 index 00000000000..fecb0239a3c --- /dev/null +++ b/tests/rustdoc-ui/private-type-cycle-110629.rs @@ -0,0 +1,16 @@ +//@ check-pass +// https://github.com/rust-lang/rust/issues/110629 + +#![feature(type_alias_impl_trait)] + +type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug; + +fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + i +} + +fn main() { + let meh = 42; + let muh = 42; + assert_eq!(bar(&meh), bar(&muh)); +} diff --git a/tests/rustdoc-ui/private-type-cycle-dyn-110629.rs b/tests/rustdoc-ui/private-type-cycle-dyn-110629.rs new file mode 100644 index 00000000000..91bf64cdc56 --- /dev/null +++ b/tests/rustdoc-ui/private-type-cycle-dyn-110629.rs @@ -0,0 +1,14 @@ +// https://github.com/rust-lang/rust/issues/110629 + +type Bar<'a, 'b> = Box<dyn PartialEq<Bar<'a, 'b>>>; +//~^ ERROR cycle detected when expanding type alias + +fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + Box::new(i) +} + +fn main() { + let meh = 42; + let muh = 42; + assert!(bar(&meh) == bar(&muh)); +} diff --git a/tests/rustdoc-ui/private-type-cycle-dyn-110629.stderr b/tests/rustdoc-ui/private-type-cycle-dyn-110629.stderr new file mode 100644 index 00000000000..6ee7e4b781c --- /dev/null +++ b/tests/rustdoc-ui/private-type-cycle-dyn-110629.stderr @@ -0,0 +1,20 @@ +error[E0391]: cycle detected when expanding type alias `Bar` + --> $DIR/private-type-cycle-dyn-110629.rs:3:38 + | +LL | type Bar<'a, 'b> = Box<dyn PartialEq<Bar<'a, 'b>>>; + | ^^^^^^^^^^^ + | + = note: ...which immediately requires expanding type alias `Bar` again + = note: type aliases cannot be recursive + = help: consider using a struct, enum, or union instead to break the cycle + = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information +note: cycle used when checking that `Bar` is well-formed + --> $DIR/private-type-cycle-dyn-110629.rs:3:1 + | +LL | type Bar<'a, 'b> = Box<dyn PartialEq<Bar<'a, 'b>>>; + | ^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/rustdoc-ui/proc_macro_bug.rs b/tests/rustdoc-ui/proc_macro_bug.rs new file mode 100644 index 00000000000..e384e4863ad --- /dev/null +++ b/tests/rustdoc-ui/proc_macro_bug.rs @@ -0,0 +1,12 @@ +// regression test for failing to pass `--crate-type proc-macro` to rustdoc +// when documenting a proc macro crate https://github.com/rust-lang/rust/pull/107291 + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(DeriveA)] +//~^ ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type +pub fn a_derive(input: TokenStream) -> TokenStream { + input +} diff --git a/tests/rustdoc-ui/proc_macro_bug.stderr b/tests/rustdoc-ui/proc_macro_bug.stderr new file mode 100644 index 00000000000..77bdf201924 --- /dev/null +++ b/tests/rustdoc-ui/proc_macro_bug.stderr @@ -0,0 +1,8 @@ +error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/proc_macro_bug.rs:8:1 + | +LL | #[proc_macro_derive(DeriveA)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/projection-as-union-type-error.rs b/tests/rustdoc-ui/projection-as-union-type-error.rs new file mode 100644 index 00000000000..d1d2e72249d --- /dev/null +++ b/tests/rustdoc-ui/projection-as-union-type-error.rs @@ -0,0 +1,14 @@ +// Test to ensure that there is no ICE when normalizing a projection. +// See also <https://github.com/rust-lang/rust/pull/106938>. +// issue: rust-lang/rust#107872 + +pub trait Identity { + type Identity; +} + +pub type Foo = u8; + +pub union Bar { + a: <Foo as Identity>::Identity, //~ ERROR the trait bound `u8: Identity` is not satisfied + b: u8, +} diff --git a/tests/rustdoc-ui/projection-as-union-type-error.stderr b/tests/rustdoc-ui/projection-as-union-type-error.stderr new file mode 100644 index 00000000000..32598015864 --- /dev/null +++ b/tests/rustdoc-ui/projection-as-union-type-error.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `u8: Identity` is not satisfied + --> $DIR/projection-as-union-type-error.rs:12:9 + | +LL | a: <Foo as Identity>::Identity, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Identity` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/projection-as-union-type-error.rs:5:1 + | +LL | pub trait Identity { + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/rustdoc-ui/pub-use-primitive-document-private-items-95633.rs b/tests/rustdoc-ui/pub-use-primitive-document-private-items-95633.rs new file mode 100644 index 00000000000..d53a67cde8b --- /dev/null +++ b/tests/rustdoc-ui/pub-use-primitive-document-private-items-95633.rs @@ -0,0 +1,9 @@ +//@ check-pass +//@ compile-flags: --document-private-items + +// This ensures that no ICE is triggered when rustdoc is run on this code. +// https://github.com/rust-lang/rust/issues/95633 + +mod stdlib { + pub (crate) use std::i8; +} diff --git a/tests/rustdoc-ui/range-pattern.rs b/tests/rustdoc-ui/range-pattern.rs new file mode 100644 index 00000000000..5e47dc826fe --- /dev/null +++ b/tests/rustdoc-ui/range-pattern.rs @@ -0,0 +1,3 @@ +//@ check-pass + +fn func(0u8..=255: u8) {} diff --git a/tests/rustdoc-ui/recursive-deref-ice.rs b/tests/rustdoc-ui/recursive-deref-ice.rs new file mode 100644 index 00000000000..5957434e85b --- /dev/null +++ b/tests/rustdoc-ui/recursive-deref-ice.rs @@ -0,0 +1,22 @@ +//@ check-pass + +// ICE found in https://github.com/rust-lang/rust/issues/83123 + +pub struct Attribute; + +pub struct Map<'hir> { + lt: &'hir (), +} + +impl<'hir> Map<'hir> { + pub fn attrs(&self) -> &'hir [Attribute] { &[] } +} + +pub struct List<T>(T); + +impl<T> std::ops::Deref for List<T> { + type Target = [T]; + fn deref(&self) -> &[T] { + &[] + } +} diff --git a/tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs new file mode 100644 index 00000000000..9f8053d5538 --- /dev/null +++ b/tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs @@ -0,0 +1,23 @@ +// issue: rust-lang/rust#98250 +//@ check-pass + +#![feature(type_alias_impl_trait)] + +mod foo { + pub type Foo = impl PartialEq<(Foo, i32)>; + + fn foo() -> Foo { + super::Bar + } +} +use foo::Foo; + +struct Bar; + +impl PartialEq<(Foo, i32)> for Bar { + fn eq(&self, _other: &(Foo, i32)) -> bool { + true + } +} + +fn main() {} diff --git a/tests/rustdoc-ui/redundant-explicit-links-123677.rs b/tests/rustdoc-ui/redundant-explicit-links-123677.rs new file mode 100644 index 00000000000..f3a5e81f89d --- /dev/null +++ b/tests/rustdoc-ui/redundant-explicit-links-123677.rs @@ -0,0 +1,14 @@ +//@ check-pass +#![deny(rustdoc::redundant_explicit_links)] + +mod bar { + /// [`Rc`](std::rc::Rc) + pub enum Baz {} +} + +pub use bar::*; + +use std::rc::Rc; + +/// [`Rc::allocator`] [foo](std::rc::Rc) +pub fn winit_runner() {} diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs new file mode 100644 index 00000000000..72c3330709a --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs @@ -0,0 +1,14 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ failure-status: 101 +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "exit (status|code): 101" -> "exit status: 101" + +// doctest fails at runtime +/// ``` +/// panic!("oh no"); +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout new file mode 100644 index 00000000000..87d1e772b80 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout @@ -0,0 +1,22 @@ + +running 1 test +test remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) ... FAILED + +failures: + +---- remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) stdout ---- +Test executable failed (exit status: 101). + +stderr: + +thread 'main' panicked at remapped_path/remap-path-prefix-failed-doctest-output.rs:3:1: +oh no +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + + +failures: + remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs new file mode 100644 index 00000000000..c18a416d43f --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs @@ -0,0 +1,13 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ failure-status: 101 +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// doctest fails to compile +/// ``` +/// this is not real code +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout new file mode 100644 index 00000000000..c0d2515998f --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout @@ -0,0 +1,22 @@ + +running 1 test +test remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) ... FAILED + +failures: + +---- remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) stdout ---- +error: expected one of `!` or `::`, found `is` + --> remapped_path/remap-path-prefix-invalid-doctest.rs:11:6 + | +LL | this is not real code + | ^^ expected one of `!` or `::` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/remap-path-prefix-lint.rs b/tests/rustdoc-ui/remap-path-prefix-lint.rs new file mode 100644 index 00000000000..d003e19f200 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-lint.rs @@ -0,0 +1,12 @@ +// Regression test for remapped paths in rustdoc errors +// <https://github.com/rust-lang/rust/issues/69264>. + +//@ compile-flags:-Z unstable-options --remap-path-prefix={{src-base}}=remapped_path +//@ rustc-env:RUST_BACKTRACE=0 + +#![deny(rustdoc::invalid_html_tags)] + +/// </script> +pub struct Bar; + +//~? ERROR unopened HTML tag `script` diff --git a/tests/rustdoc-ui/remap-path-prefix-lint.stderr b/tests/rustdoc-ui/remap-path-prefix-lint.stderr new file mode 100644 index 00000000000..d7c1bb1965d --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-lint.stderr @@ -0,0 +1,14 @@ +error: unopened HTML tag `script` + --> remapped_path/remap-path-prefix-lint.rs:9:5 + | +LL | /// </script> + | ^^^^^^^^^ + | +note: the lint level is defined here + --> remapped_path/remap-path-prefix-lint.rs:7:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/remap-path-prefix-macro.rs b/tests/rustdoc-ui/remap-path-prefix-macro.rs new file mode 100644 index 00000000000..1be22694b8c --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-macro.rs @@ -0,0 +1,9 @@ +// Regression test for "attempted to remap an already remapped filename" ICE in rustdoc +// when using --remap-path-prefix with macro rendering. +// <https://github.com/rust-lang/rust/issues/138520> + +//@ compile-flags:-Z unstable-options --remap-path-prefix={{src-base}}=remapped_path +//@ rustc-env:RUST_BACKTRACE=0 +//@ build-pass + +macro_rules! f(() => {}); diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs new file mode 100644 index 00000000000..6fa04ef77f3 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ check-run-results + +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" + +// doctest passes at runtime +/// ``` +/// assert!(true); +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout new file mode 100644 index 00000000000..8ffb5694885 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout @@ -0,0 +1,6 @@ + +running 1 test +test remapped_path/remap-path-prefix-passed-doctest-output.rs - SomeStruct (line 11) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/rustc-check-passes.rs b/tests/rustdoc-ui/rustc-check-passes.rs new file mode 100644 index 00000000000..56d59164d68 --- /dev/null +++ b/tests/rustdoc-ui/rustc-check-passes.rs @@ -0,0 +1,4 @@ +#![feature(rustdoc_internals)] +#![feature(rustdoc_internals)] //~ ERROR + +pub fn foo() {} diff --git a/tests/rustdoc-ui/rustc-check-passes.stderr b/tests/rustdoc-ui/rustc-check-passes.stderr new file mode 100644 index 00000000000..5b20d1128c5 --- /dev/null +++ b/tests/rustdoc-ui/rustc-check-passes.stderr @@ -0,0 +1,9 @@ +error[E0636]: the feature `rustdoc_internals` has already been enabled + --> $DIR/rustc-check-passes.rs:2:12 + | +LL | #![feature(rustdoc_internals)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0636`. diff --git a/tests/rustdoc-ui/scrape-examples/scrape-examples-fail-if-type-error.rs b/tests/rustdoc-ui/scrape-examples/scrape-examples-fail-if-type-error.rs new file mode 100644 index 00000000000..c8e82d3a20b --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-fail-if-type-error.rs @@ -0,0 +1,9 @@ +//@ check-fail +//@ compile-flags: -Z unstable-options --scrape-examples-output-path {{build-base}}/t.calls --scrape-examples-target-crate foobar + +pub fn foo() { + INVALID_FUNC(); + //~^ ERROR could not resolve path +} + +//~? ERROR Compilation failed, aborting rustdoc diff --git a/tests/rustdoc-ui/scrape-examples/scrape-examples-fail-if-type-error.stderr b/tests/rustdoc-ui/scrape-examples/scrape-examples-fail-if-type-error.stderr new file mode 100644 index 00000000000..750aa320719 --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-fail-if-type-error.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: could not resolve path `INVALID_FUNC` + --> $DIR/scrape-examples-fail-if-type-error.rs:5:3 + | +LL | INVALID_FUNC(); + | ^^^^^^^^^^^^ could not resolve path `INVALID_FUNC` + | + = note: this error was originally ignored because you are running `rustdoc` + = note: try running again with `rustc` or `cargo check` and you may get a more detailed error + +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/scrape-examples/scrape-examples-ice.rs b/tests/rustdoc-ui/scrape-examples/scrape-examples-ice.rs new file mode 100644 index 00000000000..0c7aeb800dc --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-ice.rs @@ -0,0 +1,4 @@ +//@ compile-flags: -Z unstable-options --scrape-examples-output-path {{build-base}}/t.calls --scrape-examples-target-crate foobar +//@ check-pass +#![no_std] +use core as _; diff --git a/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-1.rs b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-1.rs new file mode 100644 index 00000000000..3db7924dbe1 --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-1.rs @@ -0,0 +1,3 @@ +//@ compile-flags: -Z unstable-options --scrape-examples-target-crate foobar + +//~? ERROR must use --scrape-examples-output-path and --scrape-examples-target-crate together diff --git a/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-1.stderr b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-1.stderr new file mode 100644 index 00000000000..eb8e9f79968 --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-1.stderr @@ -0,0 +1,2 @@ +error: must use --scrape-examples-output-path and --scrape-examples-target-crate together + diff --git a/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-2.rs b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-2.rs new file mode 100644 index 00000000000..7b6a30291ce --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-2.rs @@ -0,0 +1,3 @@ +//@ compile-flags: -Z unstable-options --scrape-examples-output-path ex.calls + +//~? ERROR must use --scrape-examples-output-path and --scrape-examples-target-crate together diff --git a/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-2.stderr b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-2.stderr new file mode 100644 index 00000000000..eb8e9f79968 --- /dev/null +++ b/tests/rustdoc-ui/scrape-examples/scrape-examples-wrong-options-2.stderr @@ -0,0 +1,2 @@ +error: must use --scrape-examples-output-path and --scrape-examples-target-crate together + diff --git a/tests/rustdoc-ui/search-index-generics-recursion-bug-issue-59502.rs b/tests/rustdoc-ui/search-index-generics-recursion-bug-issue-59502.rs new file mode 100644 index 00000000000..d889024802f --- /dev/null +++ b/tests/rustdoc-ui/search-index-generics-recursion-bug-issue-59502.rs @@ -0,0 +1,11 @@ +//@ check-pass + +// Minimization of issue #59502 + +trait MyTrait<T> { + type Output; +} + +pub fn pow<T: MyTrait<T, Output = T>>(arg: T) -> T { + arg +} diff --git a/tests/rustdoc-ui/show-coverage-json.rs b/tests/rustdoc-ui/show-coverage-json.rs new file mode 100644 index 00000000000..3851e34fe35 --- /dev/null +++ b/tests/rustdoc-ui/show-coverage-json.rs @@ -0,0 +1,13 @@ +//@ compile-flags: -Z unstable-options --show-coverage --output-format=json +//@ check-pass + +mod bar { + /// a + /// + /// ``` + /// let x = 0; + /// ``` + pub struct Foo; +} + +pub use bar::Foo; diff --git a/tests/rustdoc-ui/show-coverage-json.stdout b/tests/rustdoc-ui/show-coverage-json.stdout new file mode 100644 index 00000000000..e6e882b2c57 --- /dev/null +++ b/tests/rustdoc-ui/show-coverage-json.stdout @@ -0,0 +1 @@ +{"$DIR/show-coverage-json.rs":{"total":2,"with_docs":1,"total_examples":1,"with_examples":1}} diff --git a/tests/rustdoc-ui/show-coverage.rs b/tests/rustdoc-ui/show-coverage.rs new file mode 100644 index 00000000000..00bb1606a82 --- /dev/null +++ b/tests/rustdoc-ui/show-coverage.rs @@ -0,0 +1,13 @@ +//@ compile-flags: -Z unstable-options --show-coverage +//@ check-pass + +mod bar { + /// a + /// + /// ``` + /// let x = 0; + /// ``` + pub struct Foo; +} + +pub use bar::Foo; diff --git a/tests/rustdoc-ui/show-coverage.stdout b/tests/rustdoc-ui/show-coverage.stdout new file mode 100644 index 00000000000..b9e0316545e --- /dev/null +++ b/tests/rustdoc-ui/show-coverage.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...ests/rustdoc-ui/show-coverage.rs | 1 | 50.0% | 1 | 100.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 1 | 50.0% | 1 | 100.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/tests/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs b/tests/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs new file mode 100644 index 00000000000..476e3b2d43e --- /dev/null +++ b/tests/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs @@ -0,0 +1,80 @@ +#![deny(rustdoc::invalid_html_tags)] + +/// This Vec<32> thing! +// Numbers aren't valid HTML tags, so no error. +pub struct ConstGeneric; + +/// This Vec<i32, i32> thing! +// HTML tags cannot contain commas, so no error. +pub struct MultipleGenerics; + +/// This <[u32] as Iterator<Item>> thing! +//~^ERROR unclosed HTML tag `Item` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +// +// The important part is that we don't produce any *wrong* suggestions. +// While several other examples below are added to make sure we don't +// produce suggestions when given complex paths, this example is the actual +// reason behind not just using the real path parser. It's ambiguous: there's +// no way to locally reason out whether that `[u32]` is intended to be a slice +// or an intra-doc link. +pub struct FullyQualifiedPathsDoNotCount; + +/// This <Vec as IntoIter>::Iter thing! +//~^ERROR unclosed HTML tag `Vec` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount1; + +/// This Vec<Vec as IntoIter>::Iter thing! +//~^ERROR unclosed HTML tag `Vec` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount2; + +/// This Vec<Vec as IntoIter> thing! +//~^ERROR unclosed HTML tag `Vec` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount3; + +/// This Vec<Vec<i32> as IntoIter> thing! +//~^ERROR unclosed HTML tag `i32` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount4; + +/// This Vec<i32 class="test"> thing! +//~^ERROR unclosed HTML tag `i32` +// HTML attributes shouldn't be treated as Rust syntax, so no suggestions. +pub struct TagWithAttributes; + +/// This Vec<i32></i32> thing! +// There should be no error, and no suggestion, since the tags are balanced. +pub struct DoNotWarnOnMatchingTags; + +/// This Vec</i32> thing! +//~^ERROR unopened HTML tag `i32` +// This should produce an error, but no suggestion. +pub struct EndTagsAreNotValidRustSyntax; + +/// This 123<i32> thing! +//~^ERROR unclosed HTML tag `i32` +// This should produce an error, but no suggestion. +pub struct NumbersAreNotPaths; + +/// This Vec:<i32> thing! +//~^ERROR unclosed HTML tag `i32` +// This should produce an error, but no suggestion. +pub struct InvalidTurbofish; + +/// This [link](https://rust-lang.org)<i32> thing! +//~^ERROR unclosed HTML tag `i32` +// This should produce an error, but no suggestion. +pub struct BareTurbofish; diff --git a/tests/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr b/tests/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr new file mode 100644 index 00000000000..3856a251321 --- /dev/null +++ b/tests/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr @@ -0,0 +1,68 @@ +error: unclosed HTML tag `Item` + --> $DIR/html-as-generics-no-suggestions.rs:11:28 + | +LL | /// This <[u32] as Iterator<Item>> thing! + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/html-as-generics-no-suggestions.rs:1:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unclosed HTML tag `Vec` + --> $DIR/html-as-generics-no-suggestions.rs:25:10 + | +LL | /// This <Vec as IntoIter>::Iter thing! + | ^^^^ + +error: unclosed HTML tag `Vec` + --> $DIR/html-as-generics-no-suggestions.rs:32:13 + | +LL | /// This Vec<Vec as IntoIter>::Iter thing! + | ^^^^ + +error: unclosed HTML tag `Vec` + --> $DIR/html-as-generics-no-suggestions.rs:39:13 + | +LL | /// This Vec<Vec as IntoIter> thing! + | ^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:46:17 + | +LL | /// This Vec<Vec<i32> as IntoIter> thing! + | ^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:53:13 + | +LL | /// This Vec<i32 class="test"> thing! + | ^^^^ + +error: unopened HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:62:13 + | +LL | /// This Vec</i32> thing! + | ^^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:67:13 + | +LL | /// This 123<i32> thing! + | ^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:72:14 + | +LL | /// This Vec:<i32> thing! + | ^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:77:39 + | +LL | /// This [link](https://rust-lang.org)<i32> thing! + | ^^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/rustdoc-ui/suggestions/html-as-generics.fixed b/tests/rustdoc-ui/suggestions/html-as-generics.fixed new file mode 100644 index 00000000000..6c004b53704 --- /dev/null +++ b/tests/rustdoc-ui/suggestions/html-as-generics.fixed @@ -0,0 +1,82 @@ +//@ run-rustfix +#![deny(rustdoc::invalid_html_tags)] + +/// This `Vec<i32>` thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct Generic; + +/// This `vec::Vec<i32>` thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct GenericPath; + +/// This `i32<i32>` thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct PathsCanContainTrailingNumbers; + +/// This `Vec::<i32>` thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct Turbofish; + +/// This [link](https://rust-lang.org)`::<i32>` thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct BareTurbofish; + +/// This <span>`Vec::<i32>`</span> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct Nested; + +/// Nested generics `Vec<Vec<u32>>` +//~^ ERROR unclosed HTML tag `u32` +//~|HELP try marking as source +pub struct NestedGenerics; + +/// Generics with path `Vec<i32>::Iter` +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct GenericsWithPath; + +/// Generics with path `<Vec<i32>>::Iter` +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath; + +/// Generics with path `Vec<Vec<i32>>::Iter` +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath2; + +/// Generics with bump `<Vec<i32>>`s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump; + +/// Generics with bump `Vec<Vec<i32>>`s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump2; + +/// Generics with punct `<Vec<i32>>`! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct; + +/// Generics with punct `Vec<Vec<i32>>`! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct2; + +/// This [`Vec<i32>`] thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct IntraDocLink; + +/// This [`Vec::<i32>`] thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct IntraDocLinkTurbofish; diff --git a/tests/rustdoc-ui/suggestions/html-as-generics.rs b/tests/rustdoc-ui/suggestions/html-as-generics.rs new file mode 100644 index 00000000000..1b54b598b2c --- /dev/null +++ b/tests/rustdoc-ui/suggestions/html-as-generics.rs @@ -0,0 +1,82 @@ +//@ run-rustfix +#![deny(rustdoc::invalid_html_tags)] + +/// This Vec<i32> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct Generic; + +/// This vec::Vec<i32> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct GenericPath; + +/// This i32<i32> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct PathsCanContainTrailingNumbers; + +/// This Vec::<i32> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct Turbofish; + +/// This [link](https://rust-lang.org)::<i32> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct BareTurbofish; + +/// This <span>Vec::<i32></span> thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct Nested; + +/// Nested generics Vec<Vec<u32>> +//~^ ERROR unclosed HTML tag `u32` +//~|HELP try marking as source +pub struct NestedGenerics; + +/// Generics with path Vec<i32>::Iter +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct GenericsWithPath; + +/// Generics with path <Vec<i32>>::Iter +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath; + +/// Generics with path Vec<Vec<i32>>::Iter +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath2; + +/// Generics with bump <Vec<i32>>s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump; + +/// Generics with bump Vec<Vec<i32>>s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump2; + +/// Generics with punct <Vec<i32>>! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct; + +/// Generics with punct Vec<Vec<i32>>! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct2; + +/// This [Vec<i32>] thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct IntraDocLink; + +/// This [Vec::<i32>] thing! +//~^ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct IntraDocLinkTurbofish; diff --git a/tests/rustdoc-ui/suggestions/html-as-generics.stderr b/tests/rustdoc-ui/suggestions/html-as-generics.stderr new file mode 100644 index 00000000000..481278bdaf9 --- /dev/null +++ b/tests/rustdoc-ui/suggestions/html-as-generics.stderr @@ -0,0 +1,183 @@ +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:4:13 + | +LL | /// This Vec<i32> thing! + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/html-as-generics.rs:2:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: try marking as source code + | +LL | /// This `Vec<i32>` thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:9:18 + | +LL | /// This vec::Vec<i32> thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This `vec::Vec<i32>` thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:14:13 + | +LL | /// This i32<i32> thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This `i32<i32>` thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:19:15 + | +LL | /// This Vec::<i32> thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This `Vec::<i32>` thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:24:41 + | +LL | /// This [link](https://rust-lang.org)::<i32> thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This [link](https://rust-lang.org)`::<i32>` thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:29:21 + | +LL | /// This <span>Vec::<i32></span> thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This <span>`Vec::<i32>`</span> thing! + | + + + +error: unclosed HTML tag `u32` + --> $DIR/html-as-generics.rs:34:28 + | +LL | /// Nested generics Vec<Vec<u32>> + | ^^^^^ + | +help: try marking as source code + | +LL | /// Nested generics `Vec<Vec<u32>>` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:39:27 + | +LL | /// Generics with path Vec<i32>::Iter + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with path `Vec<i32>::Iter` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:44:28 + | +LL | /// Generics with path <Vec<i32>>::Iter + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with path `<Vec<i32>>::Iter` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:49:31 + | +LL | /// Generics with path Vec<Vec<i32>>::Iter + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with path `Vec<Vec<i32>>::Iter` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:54:28 + | +LL | /// Generics with bump <Vec<i32>>s + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with bump `<Vec<i32>>`s + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:59:31 + | +LL | /// Generics with bump Vec<Vec<i32>>s + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with bump `Vec<Vec<i32>>`s + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:64:29 + | +LL | /// Generics with punct <Vec<i32>>! + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with punct `<Vec<i32>>`! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:69:32 + | +LL | /// Generics with punct Vec<Vec<i32>>! + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with punct `Vec<Vec<i32>>`! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:74:14 + | +LL | /// This [Vec<i32>] thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This [`Vec<i32>`] thing! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:79:16 + | +LL | /// This [Vec::<i32>] thing! + | ^^^^^ + | +help: try marking as source code + | +LL | /// This [`Vec::<i32>`] thing! + | + + + +error: aborting due to 16 previous errors + diff --git a/tests/rustdoc-ui/super-glob-40936.rs b/tests/rustdoc-ui/super-glob-40936.rs new file mode 100644 index 00000000000..75dd40bb37a --- /dev/null +++ b/tests/rustdoc-ui/super-glob-40936.rs @@ -0,0 +1,9 @@ +//@ aux-build:issue-40936.rs +//@ check-pass +//@ build-aux-docs + +// https://github.com/rust-lang/rust/issues/40936 + +#![crate_name = "foo"] + +extern crate issue_40936; diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/const-in-super-trait-and-item-bound.rs b/tests/rustdoc-ui/synthetic-auto-trait-impls/const-in-super-trait-and-item-bound.rs new file mode 100644 index 00000000000..df6de6769d5 --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/const-in-super-trait-and-item-bound.rs @@ -0,0 +1,23 @@ +// We used to ICE here while trying to synthesize auto trait impls. +// issue: 107715 +//@ check-pass + +pub const N: usize = 1; + +pub struct MapType<K: Supertrait<V>, V> { + _array: K::Array, +} + +pub trait Subtrait: Supertrait<[u8; N]> {} + +pub trait Supertrait<V> { + type Array: AnotherTrait<V>; +} + +pub trait AnotherTrait<V> { + const LENGTH: usize; +} + +pub struct Container<S: Subtrait> { + _x: MapType<S, [u8; N]>, +} diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/lifetime-generic-user-impl-normalize.rs b/tests/rustdoc-ui/synthetic-auto-trait-impls/lifetime-generic-user-impl-normalize.rs new file mode 100644 index 00000000000..1b67c2bc875 --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/lifetime-generic-user-impl-normalize.rs @@ -0,0 +1,17 @@ +// We used to ICE here while trying to synthesize auto trait impls. +// issue: 112242 +//@ check-pass +//@ compile-flags: -Znormalize-docs + +pub trait MyTrait<'a> { + type MyItem; +} +pub struct Inner<Q>(Q); +pub struct Outer<Q>(Inner<Q>); + +impl<'a, Q> std::marker::Unpin for Inner<Q> +where + Q: MyTrait<'a>, + <Q as MyTrait<'a>>::MyItem: Copy, +{ +} diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/lifetime-generic-user-impl.rs b/tests/rustdoc-ui/synthetic-auto-trait-impls/lifetime-generic-user-impl.rs new file mode 100644 index 00000000000..31d1b11ff31 --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/lifetime-generic-user-impl.rs @@ -0,0 +1,11 @@ +// We used to ICE here while trying to synthesize auto trait impls. +// issue: 123370 +//@ check-pass + +pub struct Inner<'a, Q>(&'a (), Q); + +pub struct Outer<'a, Q>(Inner<'a, Q>); + +impl<'a, Q: Trait<'a>> std::marker::Unpin for Inner<'static, Q> {} + +pub trait Trait<'a> {} diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs new file mode 100644 index 00000000000..f62f8396e99 --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs @@ -0,0 +1,18 @@ +// We used to ICE here while trying to synthesize auto trait impls. +// issue: 114657 + +pub trait Foo { + type FooType; +} + +pub trait Bar<const A: usize>: Foo<FooType = <Self as Bar<A>>::BarType> { + type BarType; +} + +pub(crate) const B: usize = 5; + +pub trait Tec: Bar<B> {} + +pub struct Structure<C: Tec> { //~ ERROR the trait bound `C: Bar<5>` is not satisfied + _field: C::BarType, //~ ERROR the trait bound `C: Bar<5>` is not satisfied +} diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr new file mode 100644 index 00000000000..045516d7d2f --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `C: Bar<5>` is not satisfied + --> $DIR/projections-in-super-trait-bound-unsatisfied.rs:16:1 + | +LL | pub struct Structure<C: Tec> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar<5>` is not implemented for `C` + | +help: consider further restricting type parameter `C` with trait `Bar` + | +LL | pub struct Structure<C: Tec + Bar<5>> { + | ++++++++ + +error[E0277]: the trait bound `C: Bar<5>` is not satisfied + --> $DIR/projections-in-super-trait-bound-unsatisfied.rs:17:13 + | +LL | _field: C::BarType, + | ^^^^^^^^^^ the trait `Bar<5>` is not implemented for `C` + | +help: consider further restricting type parameter `C` with trait `Bar` + | +LL | pub struct Structure<C: Tec + Bar<5>> { + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.rs b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.rs new file mode 100644 index 00000000000..6c62415e06d --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.rs @@ -0,0 +1,10 @@ +// We used to ICE here while trying to synthesize auto trait impls. +// issue: 112828 + +struct Outer(Inner); +struct Inner; + +unsafe impl<Q: Trait> Send for Inner {} +//~^ ERROR the type parameter `Q` is not constrained by the impl trait, self type, or predicates + +trait Trait {} diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr new file mode 100644 index 00000000000..38d1a537fe4 --- /dev/null +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/unconstrained-param-in-impl-ambiguity.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `Q` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-param-in-impl-ambiguity.rs:7:13 + | +LL | unsafe impl<Q: Trait> Send for Inner {} + | ^ unconstrained type parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs new file mode 100644 index 00000000000..77512987219 --- /dev/null +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -0,0 +1,34 @@ +//! This is a regression test for <https://github.com/rust-lang/rust/issues/137366>, ensuring +//! that we can use the `neon` target feature on ARM32 targets in rustdoc despite there +//! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the +//! target features of all targets. +//@ check-pass +//@ revisions: arm aarch64 +//@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf +//@[arm] needs-llvm-components: arm +//@[aarch64] compile-flags: --target aarch64-unknown-none-softfloat +//@[aarch64] needs-llvm-components: aarch64 + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![feature(arm_target_feature)] +#![no_core] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +// `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`. +#[target_feature(enable = "fp-armv8")] +pub fn fun1() {} + +// This would usually be rejected as it changes the ABI. +// But we disable that check in rustdoc since we are building "for all targets" and the +// check can't really handle that. +#[target_feature(enable = "soft-float")] +pub fn fun2() {} diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs new file mode 100644 index 00000000000..f8e710659a5 --- /dev/null +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -0,0 +1,13 @@ +//@ compile-flags: -Z track-diagnostics + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" + +struct A; +struct B; + +pub const S: A = B; +//~^ ERROR mismatched types +//~| NOTE created at +//~| NOTE expected `A`, found `B` diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr new file mode 100644 index 00000000000..a25fd2862aa --- /dev/null +++ b/tests/rustdoc-ui/track-diagnostics.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/track-diagnostics.rs:LL:CC + | +LL | pub const S: A = B; + | ^ expected `A`, found `B` + | + = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/rustdoc-ui/tuple-variadic-check.rs b/tests/rustdoc-ui/tuple-variadic-check.rs new file mode 100644 index 00000000000..505de53481f --- /dev/null +++ b/tests/rustdoc-ui/tuple-variadic-check.rs @@ -0,0 +1,15 @@ +#![feature(rustdoc_internals)] + +trait Mine {} + +// This one is fine +#[doc(fake_variadic)] +impl<T> Mine for (T,) {} + +trait Mine2 {} + +// This one is not +#[doc(fake_variadic)] //~ ERROR +impl<T, U> Mine for (T,U) {} + +fn main() {} diff --git a/tests/rustdoc-ui/tuple-variadic-check.stderr b/tests/rustdoc-ui/tuple-variadic-check.stderr new file mode 100644 index 00000000000..51fb87214fd --- /dev/null +++ b/tests/rustdoc-ui/tuple-variadic-check.stderr @@ -0,0 +1,8 @@ +error: `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity + --> $DIR/tuple-variadic-check.rs:12:7 + | +LL | #[doc(fake_variadic)] + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs new file mode 100644 index 00000000000..49dce32072b --- /dev/null +++ b/tests/rustdoc-ui/unable-fulfill-trait.rs @@ -0,0 +1,14 @@ +// This test ensures that it's not crashing rustdoc. + +pub struct Foo<'a, 'b, T> { + field1: dyn Bar<'a, 'b>, + //~^ ERROR +} + +pub trait Bar<'x, 's, U> +where + U: 'x, + Self: 'x, + Self: 's, +{ +} diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr new file mode 100644 index 00000000000..2786a005cd1 --- /dev/null +++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr @@ -0,0 +1,19 @@ +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/unable-fulfill-trait.rs:4:17 + | +LL | field1: dyn Bar<'a, 'b>, + | ^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `U` + --> $DIR/unable-fulfill-trait.rs:8:11 + | +LL | pub trait Bar<'x, 's, U> + | ^^^ - +help: add missing generic argument + | +LL | field1: dyn Bar<'a, 'b, U>, + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/rustdoc-ui/unescaped_backticks.rs b/tests/rustdoc-ui/unescaped_backticks.rs new file mode 100644 index 00000000000..8d6239296bf --- /dev/null +++ b/tests/rustdoc-ui/unescaped_backticks.rs @@ -0,0 +1,355 @@ +#![deny(rustdoc::unescaped_backticks)] +#![allow(rustdoc::broken_intra_doc_links)] +#![allow(rustdoc::invalid_html_tags)] +#![allow(rustdoc::redundant_explicit_links)] + +/// +pub fn empty() {} + +#[doc = ""] +pub fn empty2() {} + +/// ` +//~^ ERROR unescaped backtick +pub fn single() {} + +/// \` +pub fn escaped() {} + +/// \\` +//~^ ERROR unescaped backtick +pub fn not_escaped() {} + +/// \\\` +pub fn not_not_escaped() {} + +/// [`link1] +//~^ ERROR unescaped backtick +pub fn link1() {} + +/// [link2`] +//~^ ERROR unescaped backtick +pub fn link2() {} + +/// [`link_long](link_long) +//~^ ERROR unescaped backtick +pub fn link_long() {} + +/// [`broken-link] +//~^ ERROR unescaped backtick +pub fn broken_link() {} + +/// <xx:`> +pub fn url() {} + +/// <x:`> +//~^ ERROR unescaped backtick +pub fn not_url() {} + +/// <h1>`</h1> +pub fn html_tag() {} + +/// ` +pub fn html_escape() {} + +/// 🦀`🦀 +//~^ ERROR unescaped backtick +pub fn unicode() {} + +/// `foo( +//~^ ERROR unescaped backtick +/// +/// paragraph +pub fn paragraph() {} + +/// `foo `bar` +//~^ ERROR unescaped backtick +/// +/// paragraph +pub fn paragraph2() {} + +/// `foo( +//~^ ERROR unescaped backtick +/// not paragraph +pub fn not_paragraph() {} + +/// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (add(n, 42)`), +/// or even to add a number `n` to 42 (`add(42, b)`)! +//~^ ERROR unescaped backtick +pub fn add1(a: i32, b: i32) -> i32 { a + b } + +/// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (`add(n, 42)), +/// or even to add a number `n` to 42 (`add(42, n)`)! +//~^ ERROR unescaped backtick +pub fn add2(a: i32, b: i32) -> i32 { a + b } + +/// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (`add(n, 42)`), +/// or even to add a number `n` to 42 (add(42, n)`)! +//~^ ERROR unescaped backtick +pub fn add3(a: i32, b: i32) -> i32 { a + b } + +/// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). +//~^ ERROR unescaped backtick +/// +/// You could use this function to add 42 to a number `n` (`add(n, 42)), +/// or even to add a number `n` to 42 (`add(42, n)`)! +//~^ ERROR unescaped backtick +pub fn add4(a: i32, b: i32) -> i32 { a + b } + +#[doc = "`"] +//~^ ERROR unescaped backtick +pub fn attr() {} + +#[doc = concat!("\\", "`")] +pub fn attr_escaped() {} + +#[doc = concat!("\\\\", "`")] +//~^ ERROR unescaped backtick +pub fn attr_not_escaped() {} + +#[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] +//~^ ERROR unescaped backtick +pub fn attr_add1(a: i32, b: i32) -> i32 { a + b } + +#[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] +//~^ ERROR unescaped backtick +pub fn attr_add2(a: i32, b: i32) -> i32 { a + b } + +#[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] +//~^ ERROR unescaped backtick +pub fn attr_add3(a: i32, b: i32) -> i32 { a + b } + +#[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] +//~^ ERROR unescaped backtick +pub fn attr_add4(a: i32, b: i32) -> i32 { a + b } + +/// ``double backticks`` +/// `foo +//~^ ERROR unescaped backtick +pub fn double_backticks() {} + +/// # `(heading +//~^ ERROR unescaped backtick +/// ## heading2)` +//~^ ERROR unescaped backtick +/// +/// multi `( +//~^ ERROR unescaped backtick +/// line +/// ) heading +/// = +/// +/// para)`(graph +//~^ ERROR unescaped backtick +/// +/// para)`(graph2 +//~^ ERROR unescaped backtick +/// +/// 1. foo)` +//~^ ERROR unescaped backtick +/// 2. `(bar +//~^ ERROR unescaped backtick +/// * baz)` +//~^ ERROR unescaped backtick +/// * `(quux +//~^ ERROR unescaped backtick +/// +/// `#![this_is_actually_an_image(and(not), an = "attribute")] +//~^ ERROR unescaped backtick +/// +/// #![this_is_actually_an_image(and(not), an = "attribute")]` +//~^ ERROR unescaped backtick +/// +/// [this_is_actually_an_image(and(not), an = "attribute")]: `.png +/// +/// | `table( | )head` | +//~^ ERROR unescaped backtick +//~| ERROR unescaped backtick +/// |---------|--------| +/// | table`( | )`body | +//~^ ERROR unescaped backtick +//~| ERROR unescaped backtick +pub fn complicated_markdown() {} + +/// The `custom_mir` attribute tells the compiler to treat the function as being custom MIR. This +/// attribute only works on functions - there is no way to insert custom MIR into the middle of +/// another function. The `dialect` and `phase` parameters indicate which [version of MIR][dialect +/// docs] you are inserting here. Generally you'll want to use `#![custom_mir(dialect = "built")]` +/// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = +//~^ ERROR unescaped backtick +/// "runtime", phase = "optimized")] if you don't. +pub mod mir {} + +pub mod rustc { + /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to + //~^ ERROR unescaped backtick + /// ensure it gets used. + pub fn ty_error_with_message() {} + + pub struct WhereClause { + /// `true` if we ate a `where` token: this can happen + /// if we parsed no predicates (e.g. `struct Foo where {} + /// This allows us to accurately pretty-print + /// in `nt_to_tokenstream` + //~^ ERROR unescaped backtick + pub has_where_token: bool, + } + + /// A symbol is an interned or gensymed string. The use of `newtype_index!` means + /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index! reserves + //~^ ERROR unescaped backtick + /// the last 256 values for tagging purposes. + pub struct Symbol(); + + /// It is equivalent to `OpenOptions::new()` but allows you to write more + /// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")` + /// you can write `File::with_options().read(true).open("foo.txt"). This + /// also avoids the need to import `OpenOptions`. + //~^ ERROR unescaped backtick + pub fn with_options() {} + + /// Subtracts `set from `row`. `set` can be either `BitSet` or + /// `ChunkedBitSet`. Has no effect if `row` does not exist. + //~^ ERROR unescaped backtick + /// + /// Returns true if the row was changed. + pub fn subtract_row() {} + + pub mod assert_module_sources { + //! The reason that we use `cfg=...` and not `#[cfg_attr]` is so that + //! the HIR doesn't change as a result of the annotations, which might + //! perturb the reuse results. + //! + //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] + //~^ ERROR unescaped backtick + //! allows for doing a more fine-grained check to see if pre- or post-lto data + //! was re-used. + + /// `cfg=... + //~^ ERROR unescaped backtick + pub fn foo() {} + + /// `cfg=... and not `#[cfg_attr]` + //~^ ERROR unescaped backtick + pub fn bar() {} + } + + /// Conceptually, this is like a `Vec<Vec<RWU>>`. But the number of + /// RWU`s can get very large, so it uses a more compact representation. + //~^ ERROR unescaped backtick + pub struct RWUTable {} + + /// Like [Self::canonicalize_query], but preserves distinct universes. For + /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and + /// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1` + /// in `U2`. + //~^ ERROR unescaped backtick + /// + /// This is used for Chalk integration. + pub fn canonicalize_query_preserving_universes() {} + + /// Note that we used to return `Error` here, but that was quite + /// dubious -- the premise was that an error would *eventually* be + /// reported, when the obligation was processed. But in general once + /// you see an `Error` you are supposed to be able to assume that an + /// error *has been* reported, so that you can take whatever heuristic + /// paths you want to take. To make things worse, it was possible for + /// cycles to arise, where you basically had a setup like `<MyType<$0> + /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0> as + /// Trait>::Foo> to `[type error]` would lead to an obligation of + /// `<MyType<[type error]> as Trait>::Foo`. We are supposed to report + /// an error for this obligation, but we legitimately should not, + /// because it contains `[type error]`. Yuck! (See issue #29857 for + //~^ ERROR unescaped backtick + /// one case where this arose.) + pub fn normalize_to_error() {} + + /// you don't want to cache that `B: AutoTrait` or `A: AutoTrait` + /// is `EvaluatedToOk`; this is because they were only considered + /// ok on the premise that if `A: AutoTrait` held, but we indeed + /// encountered a problem (later on) with `A: AutoTrait. So we + /// currently set a flag on the stack node for `B: AutoTrait` (as + /// well as the second instance of `A: AutoTrait`) to suppress + //~^ ERROR unescaped backtick + /// caching. + pub struct TraitObligationStack; + + /// Extend `scc` so that it can outlive some placeholder region + /// from a universe it can't name; at present, the only way for + /// this to be true is if `scc` outlives `'static`. This is + /// actually stricter than necessary: ideally, we'd support bounds + /// like `for<'a: 'b`>` that might then allow us to approximate + /// `'a` with `'b` and not `'static`. But it will have to do for + //~^ ERROR unescaped backtick + /// now. + pub fn add_incompatible_universe(){} +} + +/// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +/// which returns an `Option<Dispatch>`. If all [`Dispatch`] clones that point +/// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return +/// `None`. Otherwise, it will return `Some(Dispatch)`. +//~^ ERROR unescaped backtick +/// +/// Returns some reference to this `[`Subscriber`] value if it is of type `T`, +/// or `None` if it isn't. +//~^ ERROR unescaped backtick +/// +/// Called before the filtered [`Layer]'s [`on_event`], to determine if +/// `on_event` should be called. +//~^ ERROR unescaped backtick +/// +/// Therefore, if the `Filter will change the value returned by this +/// method, it is responsible for ensuring that +/// [`rebuild_interest_cache`][rebuild] is called after the value of the max +//~^ ERROR unescaped backtick +/// level changes. +pub mod tracing {} + +macro_rules! id { + ($($tt:tt)*) => { $($tt)* } +} + +id! { + /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + //~^ ERROR unescaped backtick + //~| ERROR unescaped backtick + //~| ERROR unescaped backtick + //~| ERROR unescaped backtick + /// which returns an `Option<Dispatch>`. If all [`Dispatch`] clones that point + /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return + /// `None`. Otherwise, it will return `Some(Dispatch)`. + /// + /// Returns some reference to this `[`Subscriber`] value if it is of type `T`, + /// or `None` if it isn't. + /// + /// Called before the filtered [`Layer]'s [`on_event`], to determine if + /// `on_event` should be called. + /// + /// Therefore, if the `Filter will change the value returned by this + /// method, it is responsible for ensuring that + /// [`rebuild_interest_cache`][rebuild] is called after the value of the max + /// level changes. + pub mod tracing_macro {} +} + +/// Regression test for <https://github.com/rust-lang/rust/issues/111117> +pub mod trillium_server_common { + /// One-indexed, because the first CloneCounter is included. If you don't + /// want the original to count, construct a [``CloneCounterObserver`] + /// instead and use [`CloneCounterObserver::counter`] to increment. + //~^ ERROR unescaped backtick + pub struct CloneCounter; + + /// This is used by the above. + pub struct CloneCounterObserver; +} diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr new file mode 100644 index 00000000000..1bcb88e108f --- /dev/null +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -0,0 +1,959 @@ +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:187:70 + | +LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = + | ^ + | +note: the lint level is defined here + --> $DIR/unescaped_backticks.rs:1:9 + | +LL | #![deny(rustdoc::unescaped_backticks)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the closing backtick of an inline code may be missing + | +LL | /// "runtime", phase = "optimized")]` if you don't. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![custom_mir(dialect = + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:232:13 + | +LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]` + | + +help: if you meant to use a literal backtick, escape it + | +LL | //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:237:13 + | +LL | /// `cfg=... + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `cfg=...` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`cfg=... + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:241:42 + | +LL | /// `cfg=... and not `#[cfg_attr]` + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// `cfg=...` and not `#[cfg_attr]` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `cfg=... and not `#[cfg_attr]\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:193:93 + | +LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given \`msg to + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:202:34 + | +LL | /// in `nt_to_tokenstream` + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// if we parsed no predicates (e.g. `struct` Foo where {} + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// in `nt_to_tokenstream\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:208:62 + | +LL | /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index! reserves + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index!` reserves + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// that `Option<Symbol>` only takes up 4 bytes, because \`newtype_index! reserves + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:216:52 + | +LL | /// also avoids the need to import `OpenOptions`. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// you can write `File::with_options().read(true).open("foo.txt")`. This + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// also avoids the need to import `OpenOptions\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:221:47 + | +LL | /// `ChunkedBitSet`. Has no effect if `row` does not exist. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Subtracts `set` from `row`. `set` can be either `BitSet` or + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `ChunkedBitSet`. Has no effect if `row\` does not exist. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:247:12 + | +LL | /// RWU`s can get very large, so it uses a more compact representation. + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `RWU`s can get very large, so it uses a more compact representation. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// RWU\`s can get very large, so it uses a more compact representation. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:254:15 + | +LL | /// in `U2`. + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// in `U2\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:271:42 + | +LL | /// because it contains `[type error]`. Yuck! (See issue #29857 for + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0>` as + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// because it contains `[type error]\`. Yuck! (See issue #29857 for + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:281:53 + | +LL | /// well as the second instance of `A: AutoTrait`) to suppress + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// encountered a problem (later on) with `A:` AutoTrait. So we + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// well as the second instance of `A: AutoTrait\`) to suppress + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:291:40 + | +LL | /// `'a` with `'b` and not `'static`. But it will have to do for + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// `'a` with `'b` and not `'static\`. But it will have to do for + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:300:54 + | +LL | /// `None`. Otherwise, it will return `Some(Dispatch)`. + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:304:13 + | +LL | /// or `None` if it isn't. + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// or `None\` if it isn't. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:308:14 + | +LL | /// `on_event` should be called. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Called before the filtered [`Layer`]'s [`on_event`], to determine if + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `on_event\` should be called. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:313:29 + | +LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Therefore, if the `Filter` will change the value returned by this + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the max + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:323:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: the opening backtick of a previous inline code may be missing + change: The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + to this: The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], + = help: if you meant to use a literal backtick, escape it + change: `None`. Otherwise, it will return `Some(Dispatch)`. + to this: `None`. Otherwise, it will return `Some(Dispatch)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:323:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: the opening or closing backtick of an inline code may be missing + = help: if you meant to use a literal backtick, escape it + change: or `None` if it isn't. + to this: or `None\` if it isn't. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:323:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: a previous inline code might be longer than expected + change: Called before the filtered [`Layer]'s [`on_event`], to determine if + to this: Called before the filtered [`Layer`]'s [`on_event`], to determine if + = help: if you meant to use a literal backtick, escape it + change: `on_event` should be called. + to this: `on_event\` should be called. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:323:5 + | +LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], +... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max +LL | | /// level changes. + | |______________________^ + | + = help: a previous inline code might be longer than expected + change: Therefore, if the `Filter will change the value returned by this + to this: Therefore, if the `Filter` will change the value returned by this + = help: if you meant to use a literal backtick, escape it + change: [`rebuild_interest_cache`][rebuild] is called after the value of the max + to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:349:56 + | +LL | /// instead and use [`CloneCounterObserver::counter`] to increment. + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// instead and use [`CloneCounterObserver::counter\`] to increment. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:12:5 + | +LL | /// ` + | ^ + | + = help: the opening or closing backtick of an inline code may be missing +help: if you meant to use a literal backtick, escape it + | +LL | /// \` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:19:7 + | +LL | /// \` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `\` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:26:6 + | +LL | /// [`link1] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// [`link1`] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [\`link1] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:30:11 + | +LL | /// [link2`] + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// [`link2`] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [link2\`] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:34:6 + | +LL | /// [`link_long](link_long) + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// [`link_long`](link_long) + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [\`link_long](link_long) + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:38:6 + | +LL | /// [`broken-link] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// [`broken-link`] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// [\`broken-link] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:45:8 + | +LL | /// <x:`> + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `<x:`> + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// <x:\`> + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:55:6 + | +LL | /// 🦀`🦀 + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `🦀`🦀 + | + +help: the closing backtick of an inline code may be missing + | +LL | /// 🦀`🦀` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// 🦀\`🦀 + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:59:5 + | +LL | /// `foo( + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `foo(` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`foo( + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:65:14 + | +LL | /// `foo `bar` + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// `foo` `bar` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// `foo `bar\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:71:5 + | +LL | /// `foo( + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// not paragraph` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`foo( + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:76:83 + | +LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:80:51 + | +LL | /// or even to add a number `n` to 42 (`add(42, b)`)! + | ^ + | +help: the opening backtick of a previous inline code may be missing + | +LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`), + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (`add(42, b)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:84:83 + | +LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:88:51 + | +LL | /// or even to add a number `n` to 42 (`add(42, n)`)! + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`), + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:92:83 + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:96:50 + | +LL | /// or even to add a number `n` to 42 (add(42, n)`)! + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// or even to add a number `n` to 42 (`add(42, n)`)! + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (add(42, n)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:100:74 + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:104:51 + | +LL | /// or even to add a number `n` to 42 (`add(42, n)`)! + | ^ + | +help: a previous inline code might be longer than expected + | +LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`), + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:108:10 + | +LL | #[doc = "`"] + | ^ + | + = help: the opening or closing backtick of an inline code may be missing + = help: if you meant to use a literal backtick, escape it + change: ` + to this: \` + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:115:26 + | +LL | #[doc = concat!("\\", "`")] + | ^ + | + = help: the opening backtick of an inline code may be missing + change: \` + to this: `\` + = help: if you meant to use a literal backtick, escape it + change: \` + to this: \\` + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:119:9 + | +LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the opening backtick of a previous inline code may be missing + change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. + to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:123:9 + | +LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: a previous inline code might be longer than expected + change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. + to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:127:9 + | +LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the opening backtick of an inline code may be missing + change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. + to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:131:9 + | +LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the closing backtick of an inline code may be missing + change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). + to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`. + = help: if you meant to use a literal backtick, escape it + change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). + to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:136:5 + | +LL | /// `foo + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `foo` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`foo + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:140:7 + | +LL | /// # `(heading + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// # `(heading` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// # \`(heading + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:142:17 + | +LL | /// ## heading2)` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// ## `heading2)` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// ## heading2)\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:145:11 + | +LL | /// multi `( + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// )` heading + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// multi \`( + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:151:10 + | +LL | /// para)`(graph + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `para)`(graph + | + +help: the closing backtick of an inline code may be missing + | +LL | /// para)`(graph` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// para)\`(graph + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:154:10 + | +LL | /// para)`(graph2 + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `para)`(graph2 + | + +help: the closing backtick of an inline code may be missing + | +LL | /// para)`(graph2` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// para)\`(graph2 + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:157:12 + | +LL | /// 1. foo)` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// 1. `foo)` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// 1. foo)\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:159:8 + | +LL | /// 2. `(bar + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// 2. `(bar` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// 2. \`(bar + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:161:11 + | +LL | /// * baz)` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// * `baz)` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// * baz)\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:163:7 + | +LL | /// * `(quux + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// * `(quux` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// * \`(quux + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:166:5 + | +LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")] + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// `#`![this_is_actually_an_image(and(not), an = "attribute")] + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")] + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:169:62 + | +LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]` + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]` + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\` + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:174:7 + | +LL | /// | `table( | )head` | + | ^ + | +help: the closing backtick of an inline code may be missing + | +LL | /// | `table(` | )head` | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | \`table( | )head` | + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:174:22 + | +LL | /// | `table( | )head` | + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// | `table( | `)head` | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | `table( | )head\` | + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:178:12 + | +LL | /// | table`( | )`body | + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// | `table`( | )`body | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | table\`( | )`body | + | + + +error: unescaped backtick + --> $DIR/unescaped_backticks.rs:178:18 + | +LL | /// | table`( | )`body | + | ^ + | +help: the opening backtick of an inline code may be missing + | +LL | /// | table`( | `)`body | + | + +help: the closing backtick of an inline code may be missing + | +LL | /// | table`( | )`body` | + | + +help: if you meant to use a literal backtick, escape it + | +LL | /// | table`( | )\`body | + | + + +error: aborting due to 64 previous errors + diff --git a/tests/rustdoc-ui/use_both_out_dir_and_output_options.rs b/tests/rustdoc-ui/use_both_out_dir_and_output_options.rs new file mode 100644 index 00000000000..42847203d48 --- /dev/null +++ b/tests/rustdoc-ui/use_both_out_dir_and_output_options.rs @@ -0,0 +1,3 @@ +//@ compile-flags: --output ./foo + +//~? ERROR cannot use both 'out-dir' and 'output' at once diff --git a/tests/rustdoc-ui/use_both_out_dir_and_output_options.stderr b/tests/rustdoc-ui/use_both_out_dir_and_output_options.stderr new file mode 100644 index 00000000000..96d2295ac3e --- /dev/null +++ b/tests/rustdoc-ui/use_both_out_dir_and_output_options.stderr @@ -0,0 +1,2 @@ +error: cannot use both 'out-dir' and 'output' at once + diff --git a/tests/rustdoc-ui/wasm-safe.rs b/tests/rustdoc-ui/wasm-safe.rs new file mode 100644 index 00000000000..6ee5e0b99ff --- /dev/null +++ b/tests/rustdoc-ui/wasm-safe.rs @@ -0,0 +1,5 @@ +//@ check-pass + +#[cfg(any(target_arch = "wasm32", doc))] +#[target_feature(enable = "simd128")] +pub fn foo() {} |
