diff options
Diffstat (limited to 'src/test/rustdoc-ui')
354 files changed, 7890 insertions, 0 deletions
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs new file mode 100644 index 000000000..e58bba640 --- /dev/null +++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs @@ -0,0 +1,16 @@ +// 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; + //~^ ERROR ambiguous associated type + //~| HELP use fully-qualified syntax + //~| ERROR ambiguous associated type + //~| HELP use fully-qualified syntax +} diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr new file mode 100644 index 000000000..b963b722f --- /dev/null +++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr @@ -0,0 +1,15 @@ +error[E0223]: ambiguous associated type + --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27 + | +LL | pub const AssocConst: Self::AssocTy = 42; + | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy` + +error[E0223]: ambiguous associated type + --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27 + | +LL | pub const AssocConst: Self::AssocTy = 42; + | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/rustdoc-ui/assoc-item-not-in-scope.rs b/src/test/rustdoc-ui/assoc-item-not-in-scope.rs new file mode 100644 index 000000000..0976515f4 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr b/src/test/rustdoc-ui/assoc-item-not-in-scope.stderr new file mode 100644 index 000000000..04594ad41 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/auxiliary/empty-fn.rs b/src/test/rustdoc-ui/auxiliary/empty-fn.rs new file mode 100644 index 000000000..877810f15 --- /dev/null +++ b/src/test/rustdoc-ui/auxiliary/empty-fn.rs @@ -0,0 +1,3 @@ +// no-prefer-dynamic +#![crate_type = "lib"] +pub fn empty() {} diff --git a/src/test/rustdoc-ui/auxiliary/extern_macros.rs b/src/test/rustdoc-ui/auxiliary/extern_macros.rs new file mode 100644 index 000000000..ee1fec4c5 --- /dev/null +++ b/src/test/rustdoc-ui/auxiliary/extern_macros.rs @@ -0,0 +1,7 @@ +#[macro_export] +macro_rules! attrs_on_struct { + ( $( #[$attr:meta] )* ) => { + $( #[$attr] )* + pub struct ExpandedStruct; + } +} diff --git a/src/test/rustdoc-ui/auxiliary/issue-61592.rs b/src/test/rustdoc-ui/auxiliary/issue-61592.rs new file mode 100644 index 000000000..57a365b3f --- /dev/null +++ b/src/test/rustdoc-ui/auxiliary/issue-61592.rs @@ -0,0 +1,3 @@ +#![crate_name = "foo"] + +pub trait Foo {} diff --git a/src/test/rustdoc-ui/auxiliary/module_macro_doc.rs b/src/test/rustdoc-ui/auxiliary/module_macro_doc.rs new file mode 100644 index 000000000..9d6b52b95 --- /dev/null +++ b/src/test/rustdoc-ui/auxiliary/module_macro_doc.rs @@ -0,0 +1 @@ +//! [`long_cat`] is really long diff --git a/src/test/rustdoc-ui/auxiliary/overflow.rs b/src/test/rustdoc-ui/auxiliary/overflow.rs new file mode 100644 index 000000000..ff65936be --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/auxiliary/panic-item.rs b/src/test/rustdoc-ui/auxiliary/panic-item.rs new file mode 100644 index 000000000..17b26850d --- /dev/null +++ b/src/test/rustdoc-ui/auxiliary/panic-item.rs @@ -0,0 +1,17 @@ +// no-prefer-dynamic +#![crate_type = "lib"] +#![no_std] +#![feature(lang_items)] + +use core::panic::PanicInfo; +use core::sync::atomic::{self, Ordering}; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop { + atomic::compiler_fence(Ordering::SeqCst); + } +} + +#[lang = "eh_personality"] +fn foo() {} diff --git a/src/test/rustdoc-ui/bare-urls.fixed b/src/test/rustdoc-ui/bare-urls.fixed new file mode 100644 index 000000000..23aa5c44c --- /dev/null +++ b/src/test/rustdoc-ui/bare-urls.fixed @@ -0,0 +1,60 @@ +// 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() {} + +/// <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/src/test/rustdoc-ui/bare-urls.rs b/src/test/rustdoc-ui/bare-urls.rs new file mode 100644 index 000000000..592f57343 --- /dev/null +++ b/src/test/rustdoc-ui/bare-urls.rs @@ -0,0 +1,60 @@ +// 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() {} + +/// <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/src/test/rustdoc-ui/bare-urls.stderr b/src/test/rustdoc-ui/bare-urls.stderr new file mode 100644 index 000000000..7097a8ddf --- /dev/null +++ b/src/test/rustdoc-ui/bare-urls.stderr @@ -0,0 +1,143 @@ +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:5:5 + | +LL | /// https://somewhere.com + | ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com>` + | +note: the lint level is defined here + --> $DIR/bare-urls.rs:3:9 + | +LL | #![deny(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:7:5 + | +LL | /// https://somewhere.com/a + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:9:5 + | +LL | /// https://www.somewhere.com + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:11:5 + | +LL | /// https://www.somewhere.com/a + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://www.somewhere.com/a>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:13:5 + | +LL | /// https://subdomain.example.com + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://subdomain.example.com>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:15:5 + | +LL | /// https://somewhere.com? + | ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:17:5 + | +LL | /// https://somewhere.com/a? + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:19:5 + | +LL | /// https://somewhere.com?hello=12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:21:5 + | +LL | /// https://somewhere.com/a?hello=12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:23:5 + | +LL | /// https://example.com?hello=12#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com?hello=12#xyz>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:25:5 + | +LL | /// https://example.com/a?hello=12#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a?hello=12#xyz>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:27:5 + | +LL | /// https://example.com#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com#xyz>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:29:5 + | +LL | /// https://example.com/a#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://example.com/a#xyz>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:31:5 + | +LL | /// https://somewhere.com?hello=12&bye=11 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:33:5 + | +LL | /// https://somewhere.com/a?hello=12&bye=11 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:35:5 + | +LL | /// https://somewhere.com?hello=12&bye=11#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com?hello=12&bye=11#xyz>` + | + = note: bare URLs are not automatically turned into clickable links + +error: this URL is not a hyperlink + --> $DIR/bare-urls.rs:37:10 + | +LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com/a?hello=12&bye=11#xyz>` + | + = note: bare URLs are not automatically turned into clickable links + +error: aborting due to 17 previous errors + diff --git a/src/test/rustdoc-ui/block-doc-comment.rs b/src/test/rustdoc-ui/block-doc-comment.rs new file mode 100644 index 000000000..ce529916e --- /dev/null +++ b/src/test/rustdoc-ui/block-doc-comment.rs @@ -0,0 +1,17 @@ +// check-pass +// compile-flags:--test +// normalize-stdout-test "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/src/test/rustdoc-ui/block-doc-comment.stdout b/src/test/rustdoc-ui/block-doc-comment.stdout new file mode 100644 index 000000000..7326c0a25 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/bounded-hr-lifetime.rs b/src/test/rustdoc-ui/bounded-hr-lifetime.rs new file mode 100644 index 000000000..b2e000b97 --- /dev/null +++ b/src/test/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 lifetime bounds cannot be used in this context +{ +} diff --git a/src/test/rustdoc-ui/bounded-hr-lifetime.stderr b/src/test/rustdoc-ui/bounded-hr-lifetime.stderr new file mode 100644 index 000000000..d8fcd6cb4 --- /dev/null +++ b/src/test/rustdoc-ui/bounded-hr-lifetime.stderr @@ -0,0 +1,10 @@ +error: lifetime bounds cannot be used in this context + --> $DIR/bounded-hr-lifetime.rs:6:13 + | +LL | for<'a: 'b + 'c> &'a (): std::fmt::Debug, + | ^^ ^^ + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + diff --git a/src/test/rustdoc-ui/c-help.rs b/src/test/rustdoc-ui/c-help.rs new file mode 100644 index 000000000..e166edf8b --- /dev/null +++ b/src/test/rustdoc-ui/c-help.rs @@ -0,0 +1,6 @@ +// check-pass +// compile-flags: -Chelp +// check-stdout +// regex-error-pattern: -C\s+incremental + +pub struct Foo; diff --git a/src/test/rustdoc-ui/c-help.stdout b/src/test/rustdoc-ui/c-help.stdout new file mode 100644 index 000000000..75b2e2a2a --- /dev/null +++ b/src/test/rustdoc-ui/c-help.stdout @@ -0,0 +1,51 @@ + -C ar=val -- this option is deprecated and does nothing + -C code-model=val -- choose the code model to use (`rustc --print code-models` for details) + -C codegen-units=val -- divide crate into N units to optimize in parallel + -C control-flow-guard=val -- use Windows Control Flow Guard (default: no) + -C debug-assertions=val -- explicitly enable the `cfg(debug_assertions)` directive + -C debuginfo=val -- debug info emission level (0 = no debug info, 1 = line tables only, 2 = full debug info with variable and type information; default: 0) + -C default-linker-libraries=val -- allow the linker to link its default libraries (default: no) + -C embed-bitcode=val -- emit bitcode in rlibs (default: yes) + -C extra-filename=val -- extra data to put in each output filename + -C force-frame-pointers=val -- force use of the frame pointers + -C force-unwind-tables=val -- force use of unwind tables + -C incremental=val -- enable incremental compilation + -C inline-threshold=val -- set the threshold for inlining a function + -C instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are: + `=all` (implicit value) + `=except-unused-generics` + `=except-unused-functions` + `=off` (default) + -C link-arg=val -- a single extra argument to append to the linker invocation (can be used several times) + -C link-args=val -- extra arguments to append to the linker invocation (space separated) + -C link-dead-code=val -- keep dead code at link time (useful for code coverage) (default: no) + -C link-self-contained=val -- control whether to link Rust provided C objects/libraries or rely + on C toolchain installed in the system + -C linker=val -- system linker to link outputs with + -C linker-flavor=val -- linker flavor + -C linker-plugin-lto=val -- generate build artifacts that are compatible with linker-based LTO + -C llvm-args=val -- a list of arguments to pass to LLVM (space separated) + -C lto=val -- perform LLVM link-time optimizations + -C metadata=val -- metadata to mangle symbol names with + -C no-prepopulate-passes=val -- give an empty list of passes to the pass manager + -C no-redzone=val -- disable the use of the redzone + -C no-stack-check=val -- this option is deprecated and does nothing + -C no-vectorize-loops=val -- disable loop vectorization optimization passes + -C no-vectorize-slp=val -- disable LLVM's SLP vectorization pass + -C opt-level=val -- optimization level (0-3, s, or z; default: 0) + -C overflow-checks=val -- use overflow checks for integer arithmetic + -C panic=val -- panic strategy to compile crate with + -C passes=val -- a list of extra LLVM passes to run (space separated) + -C prefer-dynamic=val -- prefer dynamic linking to static linking (default: no) + -C profile-generate=val -- compile the program with profiling instrumentation + -C profile-use=val -- use the given `.profdata` file for profile-guided optimization + -C relocation-model=val -- control generation of position-independent code (PIC) (`rustc --print relocation-models` for details) + -C remark=val -- print remarks for these optimization passes (space separated, or "all") + -C rpath=val -- set rpath values in libs/exes (default: no) + -C save-temps=val -- save all temporary output files during compilation (default: no) + -C soft-float=val -- use soft float ABI (*eabihf targets only) (default: no) + -C split-debuginfo=val -- how to handle split-debuginfo, a platform-specific option + -C strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`) + -C symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') + -C target-cpu=val -- select target processor (`rustc --print target-cpus` for details) + -C target-feature=val -- target specific attributes. (`rustc --print target-features` for details). This feature is unsafe. diff --git a/src/test/rustdoc-ui/cfg-test.rs b/src/test/rustdoc-ui/cfg-test.rs new file mode 100644 index 000000000..d4ca92585 --- /dev/null +++ b/src/test/rustdoc-ui/cfg-test.rs @@ -0,0 +1,31 @@ +// check-pass +// compile-flags:--test --test-args --test-threads=1 +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/cfg-test.stdout b/src/test/rustdoc-ui/cfg-test.stdout new file mode 100644 index 000000000..2960ff8d3 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/check-attr-test.rs b/src/test/rustdoc-ui/check-attr-test.rs new file mode 100644 index 000000000..e95547014 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr new file mode 100644 index 000000000..b1fa9edf0 --- /dev/null +++ b/src/test/rustdoc-ui/check-attr-test.stderr @@ -0,0 +1,151 @@ +error: unknown attribute `compile-fail`. Did you mean `compile_fail`? + --> $DIR/check-attr-test.rs:5:1 + | +5 | / /// foo +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo +9 | | /// ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/check-attr-test.rs:3:9 + | +3 | #![deny(rustdoc::invalid_codeblock_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully + +error: unknown attribute `compilefail`. Did you mean `compile_fail`? + --> $DIR/check-attr-test.rs:5:1 + | +5 | / /// foo +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo +9 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully + +error: unknown attribute `comPile_fail`. Did you mean `compile_fail`? + --> $DIR/check-attr-test.rs:5:1 + | +5 | / /// foo +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo +9 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully + +error: unknown attribute `should-panic`. Did you mean `should_panic`? + --> $DIR/check-attr-test.rs:12:1 + | +12 | / /// bar +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo +16 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: unknown attribute `shouldpanic`. Did you mean `should_panic`? + --> $DIR/check-attr-test.rs:12:1 + | +12 | / /// bar +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo +16 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: unknown attribute `shOuld_panic`. Did you mean `should_panic`? + --> $DIR/check-attr-test.rs:12:1 + | +12 | / /// bar +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo +16 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: unknown attribute `no-run`. Did you mean `no_run`? + --> $DIR/check-attr-test.rs:19:1 + | +19 | / /// foobar +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo +23 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) + +error: unknown attribute `norun`. Did you mean `no_run`? + --> $DIR/check-attr-test.rs:19:1 + | +19 | / /// foobar +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo +23 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) + +error: unknown attribute `nO_run`. Did you mean `no_run`? + --> $DIR/check-attr-test.rs:19:1 + | +19 | / /// foobar +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo +23 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) + +error: unknown attribute `test-harness`. Did you mean `test_harness`? + --> $DIR/check-attr-test.rs:26:1 + | +26 | / /// b +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo +30 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-attr-test.rs:26:1 + | +26 | / /// b +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo +30 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: unknown attribute `tesT_harness`. Did you mean `test_harness`? + --> $DIR/check-attr-test.rs:26:1 + | +26 | / /// b +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo +30 | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: aborting due to 12 previous errors + diff --git a/src/test/rustdoc-ui/check-attr.rs b/src/test/rustdoc-ui/check-attr.rs new file mode 100644 index 000000000..0b3f7bedd --- /dev/null +++ b/src/test/rustdoc-ui/check-attr.rs @@ -0,0 +1,41 @@ +#![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() {} diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr new file mode 100644 index 000000000..370b804c5 --- /dev/null +++ b/src/test/rustdoc-ui/check-attr.stderr @@ -0,0 +1,175 @@ +error: unknown attribute `compile-fail`. Did you mean `compile_fail`? + --> $DIR/check-attr.rs:3:1 + | +LL | / /// foo +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/check-attr.rs:1:9 + | +LL | #![deny(rustdoc::invalid_codeblock_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully + +error: unknown attribute `compilefail`. Did you mean `compile_fail`? + --> $DIR/check-attr.rs:3:1 + | +LL | / /// foo +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully + +error: unknown attribute `comPile_fail`. Did you mean `compile_fail`? + --> $DIR/check-attr.rs:3:1 + | +LL | / /// foo +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully + +error: unknown attribute `should-panic`. Did you mean `should_panic`? + --> $DIR/check-attr.rs:13:1 + | +LL | / /// bar +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: unknown attribute `shouldpanic`. Did you mean `should_panic`? + --> $DIR/check-attr.rs:13:1 + | +LL | / /// bar +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: unknown attribute `sHould_panic`. Did you mean `should_panic`? + --> $DIR/check-attr.rs:13:1 + | +LL | / /// bar +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it doesn't panic when running + +error: unknown attribute `no-run`. Did you mean `no_run`? + --> $DIR/check-attr.rs:23:1 + | +LL | / /// foobar +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) + +error: unknown attribute `norun`. Did you mean `no_run`? + --> $DIR/check-attr.rs:23:1 + | +LL | / /// foobar +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) + +error: unknown attribute `no_Run`. Did you mean `no_run`? + --> $DIR/check-attr.rs:23:1 + | +LL | / /// foobar +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want) + +error: unknown attribute `test-harness`. Did you mean `test_harness`? + --> $DIR/check-attr.rs:33:1 + | +LL | / /// b +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-attr.rs:33:1 + | +LL | / /// b +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: unknown attribute `teSt_harness`. Did you mean `test_harness`? + --> $DIR/check-attr.rs:33:1 + | +LL | / /// b +LL | | +LL | | +LL | | +... | +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: aborting due to 12 previous errors + diff --git a/src/test/rustdoc-ui/check-cfg-test.rs b/src/test/rustdoc-ui/check-cfg-test.rs new file mode 100644 index 000000000..626cc8387 --- /dev/null +++ b/src/test/rustdoc-ui/check-cfg-test.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: --test --nocapture --check-cfg=values(feature,"test") -Z unstable-options +// normalize-stderr-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/check-cfg-test.stderr b/src/test/rustdoc-ui/check-cfg-test.stderr new file mode 100644 index 000000000..dc25205da --- /dev/null +++ b/src/test/rustdoc-ui/check-cfg-test.stderr @@ -0,0 +1,11 @@ +warning: unexpected `cfg` condition value + --> $DIR/check-cfg-test.rs:9:7 + | +LL | #[cfg(feature = "invalid")] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unexpected_cfgs)]` on by default + = note: expected values for `feature` are: test + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/check-cfg-test.stdout b/src/test/rustdoc-ui/check-cfg-test.stdout new file mode 100644 index 000000000..b7db49bcf --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/check-cfg-unstable.rs b/src/test/rustdoc-ui/check-cfg-unstable.rs new file mode 100644 index 000000000..5c500ce6c --- /dev/null +++ b/src/test/rustdoc-ui/check-cfg-unstable.rs @@ -0,0 +1,2 @@ +// check-fail +// compile-flags: --check-cfg=names() diff --git a/src/test/rustdoc-ui/check-cfg-unstable.stderr b/src/test/rustdoc-ui/check-cfg-unstable.stderr new file mode 100644 index 000000000..9b27c2bc0 --- /dev/null +++ b/src/test/rustdoc-ui/check-cfg-unstable.stderr @@ -0,0 +1,2 @@ +error: the `-Z unstable-options` flag must also be passed to enable the flag `check-cfg` + diff --git a/src/test/rustdoc-ui/check-cfg.rs b/src/test/rustdoc-ui/check-cfg.rs new file mode 100644 index 000000000..fa8789ad3 --- /dev/null +++ b/src/test/rustdoc-ui/check-cfg.rs @@ -0,0 +1,7 @@ +// check-pass +// compile-flags: --check-cfg=names() -Z unstable-options + +/// 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/src/test/rustdoc-ui/check-cfg.stderr b/src/test/rustdoc-ui/check-cfg.stderr new file mode 100644 index 000000000..1db8e1d91 --- /dev/null +++ b/src/test/rustdoc-ui/check-cfg.stderr @@ -0,0 +1,10 @@ +warning: unexpected `cfg` condition name + --> $DIR/check-cfg.rs:5:7 + | +LL | #[cfg(uniz)] + | ^^^^ help: did you mean: `unix` + | + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.rs b/src/test/rustdoc-ui/check-doc-alias-attr-location.rs new file mode 100644 index 000000000..6de1960e2 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr new file mode 100644 index 000000000..85c951623 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/check-doc-alias-attr.rs b/src/test/rustdoc-ui/check-doc-alias-attr.rs new file mode 100644 index 000000000..719b98604 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/check-doc-alias-attr.stderr b/src/test/rustdoc-ui/check-doc-alias-attr.stderr new file mode 100644 index 000000000..250568be3 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs new file mode 100644 index 000000000..2355d6a3d --- /dev/null +++ b/src/test/rustdoc-ui/check-fail.rs @@ -0,0 +1,21 @@ +// compile-flags: -Z unstable-options --check + +#![deny(missing_docs)] +#![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/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr new file mode 100644 index 000000000..5d46dc720 --- /dev/null +++ b/src/test/rustdoc-ui/check-fail.stderr @@ -0,0 +1,52 @@ +error: missing documentation for a function + --> $DIR/check-fail.rs:11:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:3:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/check-fail.rs:11:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:4:9 + | +LL | #![deny(rustdoc::all)] + | ^^^^^^^^^^^^ + = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]` + +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-fail.rs:6:1 + | +LL | / //! ```rust,testharness +LL | | +LL | | //! let x = 12; +LL | | //! ``` + | |_______^ + | + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]` + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-fail.rs:15:1 + | +LL | / /// hello +LL | | +LL | | /// +LL | | /// ```rust,testharness +LL | | /// let x = 12; +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/check.rs b/src/test/rustdoc-ui/check.rs new file mode 100644 index 000000000..2b44ba24b --- /dev/null +++ b/src/test/rustdoc-ui/check.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: -Z unstable-options --check +// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" + +#![warn(missing_docs)] +//~^ WARN +//~^^ WARN +#![warn(rustdoc::all)] + +pub fn foo() {} +//~^ WARN +//~^^ WARN diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr new file mode 100644 index 000000000..06e607fbe --- /dev/null +++ b/src/test/rustdoc-ui/check.stderr @@ -0,0 +1,55 @@ +warning: missing documentation for the crate + --> $DIR/check.rs:5:1 + | +LL | / #![warn(missing_docs)] +LL | | +LL | | +LL | | #![warn(rustdoc::all)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check.rs:5:9 + | +LL | #![warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a function + --> $DIR/check.rs:10:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + +warning: no documentation found for this crate's top-level module + | +note: the lint level is defined here + --> $DIR/check.rs:8:9 + | +LL | #![warn(rustdoc::all)] + | ^^^^^^^^^^^^ + = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]` + = help: The following guide may be of use: + https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html + +warning: missing code example in this documentation + --> $DIR/check.rs:5:1 + | +LL | / #![warn(missing_docs)] +LL | | +LL | | +LL | | #![warn(rustdoc::all)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | + = note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]` + +warning: missing code example in this documentation + --> $DIR/check.rs:10:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + +warning: 5 warnings emitted + diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.args b/src/test/rustdoc-ui/commandline-argfile-badutf8.args new file mode 100644 index 000000000..c070b0c24 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-badutf8.args @@ -0,0 +1,2 @@ +--cfg +unbroken€
\ No newline at end of file diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.rs b/src/test/rustdoc-ui/commandline-argfile-badutf8.rs new file mode 100644 index 000000000..e2984e3ca --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-badutf8.rs @@ -0,0 +1,12 @@ +// Check to see if we can get parameters from an @argsfile file +// +// compile-flags: --cfg cmdline_set @{{src-base}}/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/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr b/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr new file mode 100644 index 000000000..9af6fc0a5 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr @@ -0,0 +1,2 @@ +error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.rs b/src/test/rustdoc-ui/commandline-argfile-missing.rs new file mode 100644 index 000000000..5a6465bd0 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-missing.rs @@ -0,0 +1,14 @@ +// Check to see if we can get parameters from an @argsfile file +// +// normalize-stderr-test: "os error \d+" -> "os error $$ERR" +// normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +// compile-flags: --cfg cmdline_set @{{src-base}}/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/src/test/rustdoc-ui/commandline-argfile-missing.stderr b/src/test/rustdoc-ui/commandline-argfile-missing.stderr new file mode 100644 index 000000000..179ad8310 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/commandline-argfile.args b/src/test/rustdoc-ui/commandline-argfile.args new file mode 100644 index 000000000..972938bf6 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile.args @@ -0,0 +1,2 @@ +--cfg +unbroken
\ No newline at end of file diff --git a/src/test/rustdoc-ui/commandline-argfile.rs b/src/test/rustdoc-ui/commandline-argfile.rs new file mode 100644 index 000000000..cc8c8722c --- /dev/null +++ b/src/test/rustdoc-ui/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 @{{src-base}}/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/src/test/rustdoc-ui/coverage/allow_missing_docs.rs b/src/test/rustdoc-ui/coverage/allow_missing_docs.rs new file mode 100644 index 000000000..c771c09da --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/allow_missing_docs.stderr b/src/test/rustdoc-ui/coverage/allow_missing_docs.stderr new file mode 100644 index 000000000..3d5b512d1 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout b/src/test/rustdoc-ui/coverage/allow_missing_docs.stdout new file mode 100644 index 000000000..17e8ee9e2 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/basic.rs b/src/test/rustdoc-ui/coverage/basic.rs new file mode 100644 index 000000000..6c26b751c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/basic.stdout b/src/test/rustdoc-ui/coverage/basic.stdout new file mode 100644 index 000000000..3c602b3da --- /dev/null +++ b/src/test/rustdoc-ui/coverage/basic.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...est/rustdoc-ui/coverage/basic.rs | 7 | 50.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 7 | 50.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/doc-examples-json.rs b/src/test/rustdoc-ui/coverage/doc-examples-json.rs new file mode 100644 index 000000000..1da181379 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/doc-examples-json.stdout b/src/test/rustdoc-ui/coverage/doc-examples-json.stdout new file mode 100644 index 000000000..92f585569 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/doc-examples-json.stdout @@ -0,0 +1 @@ +{"$DIR/doc-examples-json.rs":{"total":3,"with_docs":2,"total_examples":2,"with_examples":1}} diff --git a/src/test/rustdoc-ui/coverage/doc-examples.rs b/src/test/rustdoc-ui/coverage/doc-examples.rs new file mode 100644 index 000000000..cd718f8a3 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/doc-examples.stdout b/src/test/rustdoc-ui/coverage/doc-examples.stdout new file mode 100644 index 000000000..8188740f8 --- /dev/null +++ b/src/test/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 | 25.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 4 | 100.0% | 1 | 25.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/empty.rs b/src/test/rustdoc-ui/coverage/empty.rs new file mode 100644 index 000000000..55a87e9d9 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/empty.stdout b/src/test/rustdoc-ui/coverage/empty.stdout new file mode 100644 index 000000000..890a7d56e --- /dev/null +++ b/src/test/rustdoc-ui/coverage/empty.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...est/rustdoc-ui/coverage/empty.rs | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs b/src/test/rustdoc-ui/coverage/enum-tuple-documented.rs new file mode 100644 index 000000000..e9c165b19 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout b/src/test/rustdoc-ui/coverage/enum-tuple-documented.stdout new file mode 100644 index 000000000..82c98f43f --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/enum-tuple.rs b/src/test/rustdoc-ui/coverage/enum-tuple.rs new file mode 100644 index 000000000..5fb205450 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/enum-tuple.stdout b/src/test/rustdoc-ui/coverage/enum-tuple.stdout new file mode 100644 index 000000000..a3377d59c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/enums.rs b/src/test/rustdoc-ui/coverage/enums.rs new file mode 100644 index 000000000..a4ae36d68 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/enums.stdout b/src/test/rustdoc-ui/coverage/enums.stdout new file mode 100644 index 000000000..64c012c1f --- /dev/null +++ b/src/test/rustdoc-ui/coverage/enums.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...est/rustdoc-ui/coverage/enums.rs | 6 | 75.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 6 | 75.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/exotic.rs b/src/test/rustdoc-ui/coverage/exotic.rs new file mode 100644 index 000000000..72b70d698 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/exotic.rs @@ -0,0 +1,15 @@ +// compile-flags:-Z unstable-options --show-coverage +// check-pass + +#![feature(rustdoc_internals)] + +//! 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 +#[doc(primitive="unit")] +mod prim_unit {} + +/// keywords? sure, pile them on +#[doc(keyword="where")] +mod where_keyword {} diff --git a/src/test/rustdoc-ui/coverage/exotic.stdout b/src/test/rustdoc-ui/coverage/exotic.stdout new file mode 100644 index 000000000..27798b813 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/exotic.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...st/rustdoc-ui/coverage/exotic.rs | 3 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 3 | 100.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/html.rs b/src/test/rustdoc-ui/coverage/html.rs new file mode 100644 index 000000000..181cb4c50 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/html.rs @@ -0,0 +1,4 @@ +// compile-flags:-Z unstable-options --output-format html --show-coverage + +/// Foo +pub struct Xo; diff --git a/src/test/rustdoc-ui/coverage/html.stderr b/src/test/rustdoc-ui/coverage/html.stderr new file mode 100644 index 000000000..adca375d4 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/html.stderr @@ -0,0 +1,2 @@ +error: html output format isn't supported for the --show-coverage option + diff --git a/src/test/rustdoc-ui/coverage/json.rs b/src/test/rustdoc-ui/coverage/json.rs new file mode 100644 index 000000000..a591cd5db --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/json.stdout b/src/test/rustdoc-ui/coverage/json.stdout new file mode 100644 index 000000000..c2be73ce3 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/json.stdout @@ -0,0 +1 @@ +{"$DIR/json.rs":{"total":17,"with_docs":12,"total_examples":15,"with_examples":6}} diff --git a/src/test/rustdoc-ui/coverage/private.rs b/src/test/rustdoc-ui/coverage/private.rs new file mode 100644 index 000000000..2a0271727 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/private.stdout b/src/test/rustdoc-ui/coverage/private.stdout new file mode 100644 index 000000000..37a0f5187 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/private.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...t/rustdoc-ui/coverage/private.rs | 4 | 57.1% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 4 | 57.1% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/coverage/statics-consts.rs b/src/test/rustdoc-ui/coverage/statics-consts.rs new file mode 100644 index 000000000..5a35260fa --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/statics-consts.stdout b/src/test/rustdoc-ui/coverage/statics-consts.stdout new file mode 100644 index 000000000..dbea3a3ea --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/traits.rs b/src/test/rustdoc-ui/coverage/traits.rs new file mode 100644 index 000000000..daa08ec25 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/coverage/traits.stdout b/src/test/rustdoc-ui/coverage/traits.stdout new file mode 100644 index 000000000..5053d0209 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/traits.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...st/rustdoc-ui/coverage/traits.rs | 8 | 88.9% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 8 | 88.9% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs new file mode 100644 index 000000000..09da124b1 --- /dev/null +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs @@ -0,0 +1,4 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +/// [v2] //~ ERROR +pub fn foo() {} diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr new file mode 100644 index 000000000..67d9c3989 --- /dev/null +++ b/src/test/rustdoc-ui/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 + | +note: the lint level is defined here + --> $DIR/deny-intra-link-resolution-failure.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/deny-missing-docs-crate.rs b/src/test/rustdoc-ui/deny-missing-docs-crate.rs new file mode 100644 index 000000000..b74eba3f6 --- /dev/null +++ b/src/test/rustdoc-ui/deny-missing-docs-crate.rs @@ -0,0 +1,3 @@ +#![deny(missing_docs)] //~ ERROR + +pub struct Foo; //~ ERROR diff --git a/src/test/rustdoc-ui/deny-missing-docs-crate.stderr b/src/test/rustdoc-ui/deny-missing-docs-crate.stderr new file mode 100644 index 000000000..5025b0b0c --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/deny-missing-docs-macro.rs b/src/test/rustdoc-ui/deny-missing-docs-macro.rs new file mode 100644 index 000000000..b1c125317 --- /dev/null +++ b/src/test/rustdoc-ui/deny-missing-docs-macro.rs @@ -0,0 +1,8 @@ +//! foo + +#![deny(missing_docs)] + +#[macro_export] +macro_rules! foo { //~ ERROR + () => {} +} diff --git a/src/test/rustdoc-ui/deny-missing-docs-macro.stderr b/src/test/rustdoc-ui/deny-missing-docs-macro.stderr new file mode 100644 index 000000000..0867b0818 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/deprecated-attrs.rs b/src/test/rustdoc-ui/deprecated-attrs.rs new file mode 100644 index 000000000..4f6a14fc2 --- /dev/null +++ b/src/test/rustdoc-ui/deprecated-attrs.rs @@ -0,0 +1,16 @@ +// check-pass +// compile-flags: --passes unknown-pass +// error-pattern: the `passes` flag no longer functions + +#![doc(no_default_passes)] +//~^ WARNING attribute is deprecated +//~| NOTE see issue #44136 +//~| HELP no longer functions; you may want to use `#![doc(document_private_items)]` +#![doc(passes = "collapse-docs unindent-comments")] +//~^ WARNING attribute is deprecated +//~| NOTE see issue #44136 +//~| HELP no longer functions; you may want to use `#![doc(document_private_items)]` +#![doc(plugins = "xxx")] +//~^ WARNING attribute is deprecated +//~| NOTE see issue #44136 +//~| WARNING no longer functions; see CVE diff --git a/src/test/rustdoc-ui/deprecated-attrs.stderr b/src/test/rustdoc-ui/deprecated-attrs.stderr new file mode 100644 index 000000000..45b20ce70 --- /dev/null +++ b/src/test/rustdoc-ui/deprecated-attrs.stderr @@ -0,0 +1,34 @@ +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 + +warning: the `#![doc(no_default_passes)]` attribute is deprecated + --> $DIR/deprecated-attrs.rs:5:8 + | +LL | #![doc(no_default_passes)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information + = help: `#![doc(no_default_passes)]` no longer functions; you may want to use `#![doc(document_private_items)]` + +warning: the `#![doc(passes = "...")]` attribute is deprecated + --> $DIR/deprecated-attrs.rs:9:8 + | +LL | #![doc(passes = "collapse-docs unindent-comments")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information + = help: `#![doc(passes = "...")]` no longer functions; you may want to use `#![doc(document_private_items)]` + +warning: the `#![doc(plugins = "...")]` attribute is deprecated + --> $DIR/deprecated-attrs.rs:13:8 + | +LL | #![doc(plugins = "xxx")] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information + = warning: `#![doc(plugins = "...")]` no longer functions; see CVE-2018-1000622 <https://nvd.nist.gov/vuln/detail/CVE-2018-1000622> + +warning: 3 warnings emitted + diff --git a/src/test/rustdoc-ui/deref-generic.rs b/src/test/rustdoc-ui/deref-generic.rs new file mode 100644 index 000000000..bc64beb1b --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/diagnostic-width.rs b/src/test/rustdoc-ui/diagnostic-width.rs new file mode 100644 index 000000000..61961d5ec --- /dev/null +++ b/src/test/rustdoc-ui/diagnostic-width.rs @@ -0,0 +1,5 @@ +// compile-flags: -Zunstable-options --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/src/test/rustdoc-ui/diagnostic-width.stderr b/src/test/rustdoc-ui/diagnostic-width.stderr new file mode 100644 index 000000000..fed049d2b --- /dev/null +++ b/src/test/rustdoc-ui/diagnostic-width.stderr @@ -0,0 +1,15 @@ +error: this URL is not a hyperlink + --> $DIR/diagnostic-width.rs:4:41 + | +LL | ... a http://link.com + | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://link.com>` + | +note: the lint level is defined here + --> $DIR/diagnostic-width.rs:2:9 + | +LL | ...ny(rustdoc::bare_url... + | ^^^^^^^^^^^^^^^^^^ + = note: bare URLs are not automatically turned into clickable links + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/display-output.rs b/src/test/rustdoc-ui/display-output.rs new file mode 100644 index 000000000..ec27a9f6b --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/display-output.stdout b/src/test/rustdoc-ui/display-output.stdout new file mode 100644 index 000000000..ad25d1ce5 --- /dev/null +++ b/src/test/rustdoc-ui/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:11: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:13: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:13: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/src/test/rustdoc-ui/doc-alias-assoc-const.rs b/src/test/rustdoc-ui/doc-alias-assoc-const.rs new file mode 100644 index 000000000..d95324734 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/doc-alias-assoc-const.stderr b/src/test/rustdoc-ui/doc-alias-assoc-const.stderr new file mode 100644 index 000000000..cbca40e13 --- /dev/null +++ b/src/test/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 previous error + diff --git a/src/test/rustdoc-ui/doc-alias-crate-level.rs b/src/test/rustdoc-ui/doc-alias-crate-level.rs new file mode 100644 index 000000000..70618ac01 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/doc-alias-crate-level.stderr b/src/test/rustdoc-ui/doc-alias-crate-level.stderr new file mode 100644 index 000000000..fc8095e03 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/doc-alias-same-name.rs b/src/test/rustdoc-ui/doc-alias-same-name.rs new file mode 100644 index 000000000..da97c2676 --- /dev/null +++ b/src/test/rustdoc-ui/doc-alias-same-name.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +#[doc(alias = "Foo")] //~ ERROR +pub struct Foo; diff --git a/src/test/rustdoc-ui/doc-alias-same-name.stderr b/src/test/rustdoc-ui/doc-alias-same-name.stderr new file mode 100644 index 000000000..5ba09a2ea --- /dev/null +++ b/src/test/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 previous error + diff --git a/src/test/rustdoc-ui/doc-attr.rs b/src/test/rustdoc-ui/doc-attr.rs new file mode 100644 index 000000000..980d1c0e2 --- /dev/null +++ b/src/test/rustdoc-ui/doc-attr.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] +#![deny(warnings)] +#![doc(as_ptr)] +//~^ ERROR unknown `doc` attribute +//~^^ WARN + +#[doc(as_ptr)] +//~^ ERROR unknown `doc` attribute +//~^^ WARN +pub fn foo() {} + +#[doc(123)] +//~^ ERROR invalid `doc` attribute +//~| WARN +#[doc("hello", "bar")] +//~^ ERROR invalid `doc` attribute +//~| WARN +//~| ERROR invalid `doc` attribute +//~| WARN +#[doc(foo::bar, crate::bar::baz = "bye")] +//~^ ERROR unknown `doc` attribute +//~| WARN +//~| ERROR unknown `doc` attribute +//~| WARN +fn bar() {} diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr new file mode 100644 index 000000000..cc2494c92 --- /dev/null +++ b/src/test/rustdoc-ui/doc-attr.stderr @@ -0,0 +1,71 @@ +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:7:7 + | +LL | #[doc(as_ptr)] + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/doc-attr.rs:2:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: invalid `doc` attribute + --> $DIR/doc-attr.rs:12:7 + | +LL | #[doc(123)] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: invalid `doc` attribute + --> $DIR/doc-attr.rs:15:7 + | +LL | #[doc("hello", "bar")] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: invalid `doc` attribute + --> $DIR/doc-attr.rs:15:16 + | +LL | #[doc("hello", "bar")] + | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: unknown `doc` attribute `foo::bar` + --> $DIR/doc-attr.rs:20:7 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: unknown `doc` attribute `crate::bar::baz` + --> $DIR/doc-attr.rs:20:17 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:3:8 + | +LL | #![doc(as_ptr)] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: aborting due to 7 previous errors + diff --git a/src/test/rustdoc-ui/doc-cfg.rs b/src/test/rustdoc-ui/doc-cfg.rs new file mode 100644 index 000000000..354d76bc3 --- /dev/null +++ b/src/test/rustdoc-ui/doc-cfg.rs @@ -0,0 +1,9 @@ +#![feature(doc_cfg)] + +#[doc(cfg(), cfg(foo, bar))] +//~^ ERROR +//~^^ ERROR +#[doc(cfg(foo), cfg(bar))] // ok! +#[doc(cfg())] //~ ERROR +#[doc(cfg(foo, bar))] //~ ERROR +pub fn foo() {} diff --git a/src/test/rustdoc-ui/doc-cfg.stderr b/src/test/rustdoc-ui/doc-cfg.stderr new file mode 100644 index 000000000..b379f6feb --- /dev/null +++ b/src/test/rustdoc-ui/doc-cfg.stderr @@ -0,0 +1,26 @@ +error: `cfg` predicate is not specified + --> $DIR/doc-cfg.rs:3:7 + | +LL | #[doc(cfg(), cfg(foo, bar))] + | ^^^^^ + +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:7:7 + | +LL | #[doc(cfg())] + | ^^^^^ + +error: multiple `cfg` predicates are specified + --> $DIR/doc-cfg.rs:8:16 + | +LL | #[doc(cfg(foo, bar))] + | ^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/doc-comment-multi-line-attr.rs b/src/test/rustdoc-ui/doc-comment-multi-line-attr.rs new file mode 100644 index 000000000..97259f782 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// check-pass + +//! ```rust +//! #![deny( +//! unused_parens, +//! )] +//! ``` diff --git a/src/test/rustdoc-ui/doc-comment-multi-line-attr.stdout b/src/test/rustdoc-ui/doc-comment-multi-line-attr.stdout new file mode 100644 index 000000000..e47edbd2a --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doc-comment-multi-line-cfg-attr.rs b/src/test/rustdoc-ui/doc-comment-multi-line-cfg-attr.rs new file mode 100644 index 000000000..b2a8133c9 --- /dev/null +++ b/src/test/rustdoc-ui/doc-comment-multi-line-cfg-attr.rs @@ -0,0 +1,12 @@ +// compile-flags:--test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/doc-comment-multi-line-cfg-attr.stdout b/src/test/rustdoc-ui/doc-comment-multi-line-cfg-attr.stdout new file mode 100644 index 000000000..bf3521e4f --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doc-include-suggestion.rs b/src/test/rustdoc-ui/doc-include-suggestion.rs new file mode 100644 index 000000000..0c0100735 --- /dev/null +++ b/src/test/rustdoc-ui/doc-include-suggestion.rs @@ -0,0 +1,10 @@ +// check-pass + +#[doc(include = "external-cross-doc.md")] +//~^ WARNING 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 +//~| WARNING previously accepted +//~| NOTE see issue #82730 +pub struct NeedMoreDocs; diff --git a/src/test/rustdoc-ui/doc-include-suggestion.stderr b/src/test/rustdoc-ui/doc-include-suggestion.stderr new file mode 100644 index 000000000..870b7efa2 --- /dev/null +++ b/src/test/rustdoc-ui/doc-include-suggestion.stderr @@ -0,0 +1,12 @@ +warning: unknown `doc` attribute `include` + --> $DIR/doc-include-suggestion.rs:3:7 + | +LL | #[doc(include = "external-cross-doc.md")] + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` + | + = note: `#[warn(invalid_doc_attributes)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/doc-spotlight.fixed b/src/test/rustdoc-ui/doc-spotlight.fixed new file mode 100644 index 000000000..4b58778ea --- /dev/null +++ b/src/test/rustdoc-ui/doc-spotlight.fixed @@ -0,0 +1,8 @@ +// run-rustfix +#![deny(warnings)] +#![feature(doc_notable_trait)] + +#[doc(notable_trait)] +//~^ ERROR unknown `doc` attribute `spotlight` +//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +trait MyTrait {} diff --git a/src/test/rustdoc-ui/doc-spotlight.rs b/src/test/rustdoc-ui/doc-spotlight.rs new file mode 100644 index 000000000..16e387245 --- /dev/null +++ b/src/test/rustdoc-ui/doc-spotlight.rs @@ -0,0 +1,8 @@ +// run-rustfix +#![deny(warnings)] +#![feature(doc_notable_trait)] + +#[doc(spotlight)] +//~^ ERROR unknown `doc` attribute `spotlight` +//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +trait MyTrait {} diff --git a/src/test/rustdoc-ui/doc-spotlight.stderr b/src/test/rustdoc-ui/doc-spotlight.stderr new file mode 100644 index 000000000..8e7831139 --- /dev/null +++ b/src/test/rustdoc-ui/doc-spotlight.stderr @@ -0,0 +1,19 @@ +error: unknown `doc` attribute `spotlight` + --> $DIR/doc-spotlight.rs:5:7 + | +LL | #[doc(spotlight)] + | ^^^^^^^^^ help: use `notable_trait` instead + | +note: the lint level is defined here + --> $DIR/doc-spotlight.rs:2:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: `doc(spotlight)` was renamed to `doc(notable_trait)` + = note: `doc(spotlight)` is now a no-op + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/doc-test-attr-pass.rs b/src/test/rustdoc-ui/doc-test-attr-pass.rs new file mode 100644 index 000000000..12608f244 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doc-test-attr.rs b/src/test/rustdoc-ui/doc-test-attr.rs new file mode 100644 index 000000000..46178ad86 --- /dev/null +++ b/src/test/rustdoc-ui/doc-test-attr.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] +#![deny(invalid_doc_attributes)] + +#![doc(test)] +//~^ ERROR `#[doc(test(...)]` takes a list of attributes +//~^^ WARN this was previously accepted by the compiler +#![doc(test = "hello")] +//~^ ERROR `#[doc(test(...)]` takes a list of attributes +//~^^ WARN this was previously accepted by the compiler +#![doc(test(a))] +//~^ ERROR unknown `doc(test)` attribute `a` +//~^^ WARN this was previously accepted by the compiler + +pub fn foo() {} diff --git a/src/test/rustdoc-ui/doc-test-attr.stderr b/src/test/rustdoc-ui/doc-test-attr.stderr new file mode 100644 index 000000000..7f5e2d6bc --- /dev/null +++ b/src/test/rustdoc-ui/doc-test-attr.stderr @@ -0,0 +1,34 @@ +error: `#[doc(test(...)]` takes a list of attributes + --> $DIR/doc-test-attr.rs:4:8 + | +LL | #![doc(test)] + | ^^^^ + | +note: the lint level is defined here + --> $DIR/doc-test-attr.rs:2:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: `#[doc(test(...)]` takes a list of attributes + --> $DIR/doc-test-attr.rs:7:8 + | +LL | #![doc(test = "hello")] + | ^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: unknown `doc(test)` attribute `a` + --> $DIR/doc-test-attr.rs:10:13 + | +LL | #![doc(test(a))] + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + +error: aborting due to 3 previous errors + diff --git a/src/test/rustdoc-ui/doc-test-doctest-feature.rs b/src/test/rustdoc-ui/doc-test-doctest-feature.rs new file mode 100644 index 000000000..0b79aaece --- /dev/null +++ b/src/test/rustdoc-ui/doc-test-doctest-feature.rs @@ -0,0 +1,13 @@ +// check-pass +// compile-flags:--test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/doc-test-doctest-feature.stdout b/src/test/rustdoc-ui/doc-test-doctest-feature.stdout new file mode 100644 index 000000000..d7de1f105 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs b/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs new file mode 100644 index 000000000..bf334c67e --- /dev/null +++ b/src/test/rustdoc-ui/doc-test-rustdoc-feature.rs @@ -0,0 +1,15 @@ +// check-pass +// compile-flags:--test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/doc-test-rustdoc-feature.stdout b/src/test/rustdoc-ui/doc-test-rustdoc-feature.stdout new file mode 100644 index 000000000..5b07fc4c8 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doc-without-codeblock.rs b/src/test/rustdoc-ui/doc-without-codeblock.rs new file mode 100644 index 000000000..315fca195 --- /dev/null +++ b/src/test/rustdoc-ui/doc-without-codeblock.rs @@ -0,0 +1,22 @@ +#![deny(rustdoc::missing_doc_code_examples)] //~ ERROR missing code example in this documentation + +/// Some docs. +//~^ ERROR missing code example in this documentation +pub struct Foo; + +/// And then, the princess died. +//~^ ERROR missing code example in this documentation +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/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr new file mode 100644 index 000000000..1c1380441 --- /dev/null +++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr @@ -0,0 +1,38 @@ +error: missing code example in this documentation + --> $DIR/doc-without-codeblock.rs:1:1 + | +LL | / #![deny(rustdoc::missing_doc_code_examples)] +LL | | +LL | | /// Some docs. +LL | | +... | +LL | | } +LL | | } + | |_^ + | +note: the lint level is defined here + --> $DIR/doc-without-codeblock.rs:1:9 + | +LL | #![deny(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/doc-without-codeblock.rs:7:1 + | +LL | /// And then, the princess died. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/doc-without-codeblock.rs:10:5 + | +LL | /// Or maybe not because she saved herself! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/doc-without-codeblock.rs:3:1 + | +LL | /// Some docs. + | ^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/doctest-edition.rs b/src/test/rustdoc-ui/doctest-edition.rs new file mode 100644 index 000000000..b0787be97 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doctest-edition.stderr b/src/test/rustdoc-ui/doctest-edition.stderr new file mode 100644 index 000000000..1643d6053 --- /dev/null +++ b/src/test/rustdoc-ui/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: the lint level is defined here + --> $DIR/doctest-edition.rs:3:9 + | +LL | #![deny(rustdoc::invalid_rust_codeblocks)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: error from rustc: prefix `foo` is unknown +help: mark blocks that do not contain Rust code as text + | +LL | //! ```text + | ++++ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/doctest-multiline-crate-attribute.rs b/src/test/rustdoc-ui/doctest-multiline-crate-attribute.rs new file mode 100644 index 000000000..a30472ac5 --- /dev/null +++ b/src/test/rustdoc-ui/doctest-multiline-crate-attribute.rs @@ -0,0 +1,10 @@ +// compile-flags:--test --test-args=--test-threads=1 +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/doctest-multiline-crate-attribute.stdout b/src/test/rustdoc-ui/doctest-multiline-crate-attribute.stdout new file mode 100644 index 000000000..07a4f657d --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/doctest-output.rs b/src/test/rustdoc-ui/doctest-output.rs new file mode 100644 index 000000000..2670fa572 --- /dev/null +++ b/src/test/rustdoc-ui/doctest-output.rs @@ -0,0 +1,28 @@ +// edition:2018 +// aux-build:extern_macros.rs +// compile-flags:--test --test-args=--test-threads=1 +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/doctest-output.stdout b/src/test/rustdoc-ui/doctest-output.stdout new file mode 100644 index 000000000..35b0e366f --- /dev/null +++ b/src/test/rustdoc-ui/doctest-output.stdout @@ -0,0 +1,8 @@ + +running 3 tests +test $DIR/doctest-output.rs - (line 8) ... ok +test $DIR/doctest-output.rs - ExpandedStruct (line 24) ... ok +test $DIR/doctest-output.rs - foo::bar (line 18) ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/error-in-impl-trait/README.md b/src/test/rustdoc-ui/error-in-impl-trait/README.md new file mode 100644 index 000000000..1176a4a8c --- /dev/null +++ b/src/test/rustdoc-ui/error-in-impl-trait/README.md @@ -0,0 +1,7 @@ +Each of these needs to be in a separate file, +because the `delay_span_bug` ICE in rustdoc won't be triggerred +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/src/test/rustdoc-ui/error-in-impl-trait/async.rs b/src/test/rustdoc-ui/error-in-impl-trait/async.rs new file mode 100644 index 000000000..cda53bff0 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/closure.rs b/src/test/rustdoc-ui/error-in-impl-trait/closure.rs new file mode 100644 index 000000000..f1fd85bb2 --- /dev/null +++ b/src/test/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 generator) +pub fn a() -> impl Fn() -> u32 { + || content::doesnt::matter() +} diff --git a/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs b/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs new file mode 100644 index 000000000..ed62f0208 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs b/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs new file mode 100644 index 000000000..dcec379d4 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs new file mode 100644 index 000000000..b935b0832 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs new file mode 100644 index 000000000..701126f87 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs b/src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs new file mode 100644 index 000000000..248575d35 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs new file mode 100644 index 000000000..31dd786cb --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs new file mode 100644 index 000000000..c18a024af --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.rs b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.rs new file mode 100644 index 000000000..0901ac364 --- /dev/null +++ b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.rs @@ -0,0 +1,157 @@ +// check-pass +#![feature(lint_reasons)] + +//! 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(illegal_floating_point_literal_pattern)] + match x { + 5.0 => {} + 6.0 => {} + _ => {} + } + } +} + +mod rustc_warn { + //! See <https://doc.rust-lang.org/rustc/lints/index.html> + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42; + + #[expect(illegal_floating_point_literal_pattern)] + 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/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.stderr b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.stderr new file mode 100644 index 000000000..efc5f349f --- /dev/null +++ b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.stderr @@ -0,0 +1,28 @@ +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:16: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:71:14 + | +LL | #[expect(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:76:14 + | +LL | #[expect(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:81:14 + | +LL | #[expect(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted + diff --git a/src/test/rustdoc-ui/failed-doctest-compile-fail.rs b/src/test/rustdoc-ui/failed-doctest-compile-fail.rs new file mode 100644 index 000000000..6f2ff5d70 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// failure-status: 101 + +/// ```compile_fail +/// println!("Hello"); +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/failed-doctest-compile-fail.stdout b/src/test/rustdoc-ui/failed-doctest-compile-fail.stdout new file mode 100644 index 000000000..af3a90a74 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.rs b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.rs new file mode 100644 index 000000000..16d737106 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// failure-status: 101 + +/// <https://github.com/rust-lang/rust/issues/91014> +/// +/// ```rust +/// struct S {}; // unexpected semicolon after struct def +/// +/// fn main() { +/// assert_eq!(0, 1); +/// } +/// ``` +mod m {} diff --git a/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout new file mode 100644 index 000000000..61468b6c7 --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout @@ -0,0 +1,24 @@ + +running 1 test +test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... FAILED + +failures: + +---- $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) stdout ---- +error: expected item, found `;` + --> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12 + | +LL | struct S {}; // unexpected semicolon after struct def + | ^ help: remove this semicolon + | + = help: braced struct declarations are not followed by a semicolon + +error: aborting due to previous error + +Couldn't compile the test. + +failures: + $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/failed-doctest-missing-codes.rs b/src/test/rustdoc-ui/failed-doctest-missing-codes.rs new file mode 100644 index 000000000..57b70b478 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// failure-status: 101 + +/// ```compile_fail,E0004 +/// let x: () = 5i32; +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/failed-doctest-missing-codes.stdout b/src/test/rustdoc-ui/failed-doctest-missing-codes.stdout new file mode 100644 index 000000000..bacbb47b5 --- /dev/null +++ b/src/test/rustdoc-ui/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 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/src/test/rustdoc-ui/failed-doctest-output-windows.rs b/src/test/rustdoc-ui/failed-doctest-output-windows.rs new file mode 100644 index 000000000..4cd9993d8 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/failed-doctest-output-windows.stdout b/src/test/rustdoc-ui/failed-doctest-output-windows.stdout new file mode 100644 index 000000000..6c147054d --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-output-windows.stdout @@ -0,0 +1,39 @@ + +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 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 'oh no', $DIR/failed-doctest-output-windows.rs:7:1 +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/src/test/rustdoc-ui/failed-doctest-output.rs b/src/test/rustdoc-ui/failed-doctest-output.rs new file mode 100644 index 000000000..42de954d0 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout new file mode 100644 index 000000000..630198a56 --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -0,0 +1,39 @@ + +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 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 'oh no', $DIR/failed-doctest-output.rs:7:1 +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/src/test/rustdoc-ui/failed-doctest-should-panic.rs b/src/test/rustdoc-ui/failed-doctest-should-panic.rs new file mode 100644 index 000000000..2b8bb3168 --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-should-panic.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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// failure-status: 101 + +/// ```should_panic +/// println!("Hello, world!"); +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/failed-doctest-should-panic.stdout b/src/test/rustdoc-ui/failed-doctest-should-panic.stdout new file mode 100644 index 000000000..57a20092a --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-should-panic.stdout @@ -0,0 +1,14 @@ + +running 1 test +test $DIR/failed-doctest-should-panic.rs - Foo (line 9) ... FAILED + +failures: + +---- $DIR/failed-doctest-should-panic.rs - Foo (line 9) stdout ---- +Test executable succeeded, but it's marked `should_panic`. + +failures: + $DIR/failed-doctest-should-panic.rs - Foo (line 9) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/feature-gate-doc_cfg_hide.rs b/src/test/rustdoc-ui/feature-gate-doc_cfg_hide.rs new file mode 100644 index 000000000..17812018b --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/feature-gate-doc_cfg_hide.stderr b/src/test/rustdoc-ui/feature-gate-doc_cfg_hide.stderr new file mode 100644 index 000000000..ba42c7bbb --- /dev/null +++ b/src/test/rustdoc-ui/feature-gate-doc_cfg_hide.stderr @@ -0,0 +1,14 @@ +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 + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/rustdoc-ui/generate-link-to-definition-opt-unstable.rs b/src/test/rustdoc-ui/generate-link-to-definition-opt-unstable.rs new file mode 100644 index 000000000..87620d74e --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/generate-link-to-definition-opt-unstable.stderr b/src/test/rustdoc-ui/generate-link-to-definition-opt-unstable.stderr new file mode 100644 index 000000000..a8ddf91bc --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/generate-link-to-definition-opt.rs b/src/test/rustdoc-ui/generate-link-to-definition-opt.rs new file mode 100644 index 000000000..8f4f561b4 --- /dev/null +++ b/src/test/rustdoc-ui/generate-link-to-definition-opt.rs @@ -0,0 +1,6 @@ +// 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 + +pub fn f() {} diff --git a/src/test/rustdoc-ui/generate-link-to-definition-opt.stderr b/src/test/rustdoc-ui/generate-link-to-definition-opt.stderr new file mode 100644 index 000000000..4c8c607e7 --- /dev/null +++ b/src/test/rustdoc-ui/generate-link-to-definition-opt.stderr @@ -0,0 +1,2 @@ +error: --generate-link-to-definition option can only be used with HTML output format + diff --git a/src/test/rustdoc-ui/generate-link-to-definition-opt2.rs b/src/test/rustdoc-ui/generate-link-to-definition-opt2.rs new file mode 100644 index 000000000..da5142087 --- /dev/null +++ b/src/test/rustdoc-ui/generate-link-to-definition-opt2.rs @@ -0,0 +1,6 @@ +// 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 --show-coverage + +pub fn f() {} diff --git a/src/test/rustdoc-ui/generate-link-to-definition-opt2.stderr b/src/test/rustdoc-ui/generate-link-to-definition-opt2.stderr new file mode 100644 index 000000000..4c8c607e7 --- /dev/null +++ b/src/test/rustdoc-ui/generate-link-to-definition-opt2.stderr @@ -0,0 +1,2 @@ +error: --generate-link-to-definition option can only be used with HTML output format + diff --git a/src/test/rustdoc-ui/ignore-block-help.rs b/src/test/rustdoc-ui/ignore-block-help.rs new file mode 100644 index 000000000..86f6a2868 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/ignore-block-help.stderr b/src/test/rustdoc-ui/ignore-block-help.stderr new file mode 100644 index 000000000..9c02ff11d --- /dev/null +++ b/src/test/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 | | /// ``` + | |_______^ + | + = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default +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 + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/impl-fn-nesting.rs b/src/test/rustdoc-ui/impl-fn-nesting.rs new file mode 100644 index 000000000..a927f6bd7 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/impl-fn-nesting.stderr b/src/test/rustdoc-ui/impl-fn-nesting.stderr new file mode 100644 index 000000000..608749af8 --- /dev/null +++ b/src/test/rustdoc-ui/impl-fn-nesting.stderr @@ -0,0 +1,66 @@ +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: Compilation failed, aborting rustdoc + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0405, E0412. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs new file mode 100644 index 000000000..2319de556 --- /dev/null +++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs @@ -0,0 +1,15 @@ +// normalize-stderr-test: "`.*`" -> "`DEF_ID`" +// normalize-stdout-test: "`.*`" -> "`DEF_ID`" +// edition:2018 + +pub async fn f() -> impl std::fmt::Debug { + #[derive(Debug)] + enum E { + //~^ ERROR recursive type `f::{closure#0}::E` has infinite size + This(E), + Unit, + } + E::Unit +} + +fn main() {} diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr new file mode 100644 index 000000000..aa39d26fe --- /dev/null +++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `DEF_ID` has infinite size + --> $DIR/infinite-recursive-type-impl-trait-return.rs:7:5 + | +LL | enum E { + | ^^^^^^ recursive type has infinite size +LL | +LL | This(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `DEF_ID` representable + | +LL | This(Box<E>), + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `DEF_ID`. diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs new file mode 100644 index 000000000..b3a7ee563 --- /dev/null +++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs @@ -0,0 +1,7 @@ +fn f() -> impl Sized { + enum E { + //~^ ERROR recursive type `f::E` has infinite size + V(E), + } + unimplemented!() +} diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr new file mode 100644 index 000000000..009bedec5 --- /dev/null +++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `f::E` has infinite size + --> $DIR/infinite-recursive-type-impl-trait.rs:2:5 + | +LL | enum E { + | ^^^^^^ recursive type has infinite size +LL | +LL | V(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `f::E` representable + | +LL | V(Box<E>), + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/rustdoc-ui/infinite-recursive-type.rs b/src/test/rustdoc-ui/infinite-recursive-type.rs new file mode 100644 index 000000000..32793fc4f --- /dev/null +++ b/src/test/rustdoc-ui/infinite-recursive-type.rs @@ -0,0 +1,4 @@ +enum E { +//~^ ERROR recursive type `E` has infinite size + V(E), +} diff --git a/src/test/rustdoc-ui/infinite-recursive-type.stderr b/src/test/rustdoc-ui/infinite-recursive-type.stderr new file mode 100644 index 000000000..b33aba446 --- /dev/null +++ b/src/test/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 { + | ^^^^^^ recursive type has infinite size +LL | +LL | V(E), + | - recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `E` representable + | +LL | V(Box<E>), + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/rustdoc-ui/intra-doc/alias-ice.rs b/src/test/rustdoc-ui/intra-doc/alias-ice.rs new file mode 100644 index 000000000..51922caeb --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/alias-ice.stderr b/src/test/rustdoc-ui/intra-doc/alias-ice.stderr new file mode 100644 index 000000000..5e7ffeeb8 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/alias-ice.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `TypeAlias::hoge` + --> $DIR/alias-ice.rs:5:30 + | +LL | /// [broken cross-reference](TypeAlias::hoge) + | ^^^^^^^^^^^^^^^ the type alias `TypeAlias` has no associated item named `hoge` + | +note: the lint level is defined here + --> $DIR/alias-ice.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/ambiguity.rs b/src/test/rustdoc-ui/intra-doc/ambiguity.rs new file mode 100644 index 000000000..1f3dc722e --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/ambiguity.rs @@ -0,0 +1,40 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +pub fn ambiguous() {} + +pub struct ambiguous {} + +#[macro_export] +macro_rules! multi_conflict { () => {} } + +#[allow(non_camel_case_types)] +pub struct multi_conflict {} + +pub fn multi_conflict() {} + +pub mod type_and_value {} + +pub const type_and_value: i32 = 0; + +pub mod foo { + pub enum bar {} + + pub fn bar() {} +} + +/// [`ambiguous`] is ambiguous. //~ERROR `ambiguous` +/// +/// [ambiguous] is ambiguous. //~ERROR ambiguous +/// +/// [`multi_conflict`] is a three-way conflict. //~ERROR `multi_conflict` +/// +/// Ambiguous [type_and_value]. //~ERROR type_and_value +/// +/// Ambiguous non-implied shortcut link [`foo::bar`]. //~ERROR `foo::bar` +pub struct Docs {} + +/// [true] //~ ERROR `true` is both a module and a builtin type +/// [primitive@true] +pub mod r#true {} diff --git a/src/test/rustdoc-ui/intra-doc/ambiguity.stderr b/src/test/rustdoc-ui/intra-doc/ambiguity.stderr new file mode 100644 index 000000000..7974796e4 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/ambiguity.stderr @@ -0,0 +1,101 @@ +error: `true` is both a module and a builtin type + --> $DIR/ambiguity.rs:38:6 + | +LL | /// [true] + | ^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/ambiguity.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@true] + | ++++ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@true] + | +++++ + +error: `ambiguous` is both a struct and a function + --> $DIR/ambiguity.rs:27:7 + | +LL | /// [`ambiguous`] is ambiguous. + | ^^^^^^^^^ ambiguous link + | +help: to link to the struct, prefix with `struct@` + | +LL | /// [`struct@ambiguous`] is ambiguous. + | +++++++ +help: to link to the function, add parentheses + | +LL | /// [`ambiguous()`] is ambiguous. + | ++ + +error: `ambiguous` is both a struct and a function + --> $DIR/ambiguity.rs:29:6 + | +LL | /// [ambiguous] is ambiguous. + | ^^^^^^^^^ ambiguous link + | +help: to link to the struct, prefix with `struct@` + | +LL | /// [struct@ambiguous] is ambiguous. + | +++++++ +help: to link to the function, add parentheses + | +LL | /// [ambiguous()] is ambiguous. + | ++ + +error: `multi_conflict` is a struct, a function, and a macro + --> $DIR/ambiguity.rs:31:7 + | +LL | /// [`multi_conflict`] is a three-way conflict. + | ^^^^^^^^^^^^^^ ambiguous link + | +help: to link to the struct, prefix with `struct@` + | +LL | /// [`struct@multi_conflict`] is a three-way conflict. + | +++++++ +help: to link to the function, add parentheses + | +LL | /// [`multi_conflict()`] is a three-way conflict. + | ++ +help: to link to the macro, add an exclamation mark + | +LL | /// [`multi_conflict!`] is a three-way conflict. + | + + +error: `type_and_value` is both a module and a constant + --> $DIR/ambiguity.rs:33:16 + | +LL | /// Ambiguous [type_and_value]. + | ^^^^^^^^^^^^^^ ambiguous link + | +help: to link to the module, prefix with `mod@` + | +LL | /// Ambiguous [mod@type_and_value]. + | ++++ +help: to link to the constant, prefix with `const@` + | +LL | /// Ambiguous [const@type_and_value]. + | ++++++ + +error: `foo::bar` is both an enum and a function + --> $DIR/ambiguity.rs:35:43 + | +LL | /// Ambiguous non-implied shortcut link [`foo::bar`]. + | ^^^^^^^^ ambiguous link + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Ambiguous non-implied shortcut link [`enum@foo::bar`]. + | +++++ +help: to link to the function, add parentheses + | +LL | /// Ambiguous non-implied shortcut link [`foo::bar()`]. + | ++ + +error: aborting due to 6 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/anchors.rs b/src/test/rustdoc-ui/intra-doc/anchors.rs new file mode 100644 index 000000000..34e11c7c7 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/anchors.stderr b/src/test/rustdoc-ui/intra-doc/anchors.stderr new file mode 100644 index 000000000..0d226b277 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/assoc-field.rs b/src/test/rustdoc-ui/intra-doc/assoc-field.rs new file mode 100644 index 000000000..e18404e44 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs b/src/test/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs new file mode 100644 index 000000000..b4ce3443c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs new file mode 100644 index 000000000..cfb24fc2c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs new file mode 100644 index 000000000..7a11a1657 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/auxiliary/dep1.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/dep1.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/auxiliary/dep1.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/rustdoc-ui/intra-doc/auxiliary/dep2.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/dep2.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/auxiliary/dep2.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/rustdoc-ui/intra-doc/auxiliary/dep3.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/dep3.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/auxiliary/dep3.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/rustdoc-ui/intra-doc/auxiliary/dep4.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/dep4.rs new file mode 100644 index 000000000..d11c69f81 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/auxiliary/dep4.rs @@ -0,0 +1 @@ +// intentionally empty diff --git a/src/test/rustdoc-ui/intra-doc/auxiliary/intra-doc-broken.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/intra-doc-broken.rs new file mode 100644 index 000000000..31a8310d4 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/auxiliary/pointer-reexports-allowed.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/pointer-reexports-allowed.rs new file mode 100644 index 000000000..0a3dc57f1 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/auxiliary/through-proc-macro-aux.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/through-proc-macro-aux.rs new file mode 100644 index 000000000..5c4a01ee3 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/broken-reexport.rs b/src/test/rustdoc-ui/intra-doc/broken-reexport.rs new file mode 100644 index 000000000..862faa50b --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/crate-nonexistent.rs b/src/test/rustdoc-ui/intra-doc/crate-nonexistent.rs new file mode 100644 index 000000000..ceecfa681 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/crate-nonexistent.stderr b/src/test/rustdoc-ui/intra-doc/crate-nonexistent.stderr new file mode 100644 index 000000000..a69b1c52a --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/crate-nonexistent.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `crate::DoesNotExist` + --> $DIR/crate-nonexistent.rs:3:6 + | +LL | /// [crate::DoesNotExist] + | ^^^^^^^^^^^^^^^^^^^ no item named `DoesNotExist` in module `crate_nonexistent` + | +note: the lint level is defined here + --> $DIR/crate-nonexistent.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs new file mode 100644 index 000000000..2d6656611 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs @@ -0,0 +1,81 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined +pub enum S {} +fn S() {} + +#[macro_export] +macro_rules! m { + () => {}; +} + +static s: usize = 0; +const c: usize = 0; + +trait T {} + +/// Link to [struct@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [mod@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [union@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [trait@S] +//~^ ERROR incompatible link kind for `S` +//~| NOTE this link resolved +//~| HELP prefix with `enum@` + +/// Link to [struct@T] +//~^ ERROR incompatible link kind for `T` +//~| NOTE this link resolved +//~| HELP prefix with `trait@` + +/// Link to [derive@m] +//~^ ERROR incompatible link kind for `m` +//~| NOTE this link resolved +//~| HELP add an exclamation mark + +/// Link to [m()] +//~^ ERROR unresolved link to `m` +//~| NOTE this link resolves to the macro `m` +//~| HELP add an exclamation mark +/// and to [m!()] + +/// Link to [const@s] +//~^ ERROR incompatible link kind for `s` +//~| NOTE this link resolved +//~| HELP prefix with `static@` + +/// Link to [static@c] +//~^ ERROR incompatible link kind for `c` +//~| NOTE this link resolved +//~| HELP prefix with `const@` + +/// Link to [fn@c] +//~^ ERROR incompatible link kind for `c` +//~| NOTE this link resolved +//~| HELP prefix with `const@` + +/// Link to [c()] +//~^ ERROR incompatible link kind for `c` +//~| NOTE this link resolved +//~| HELP prefix with `const@` + +/// Link to [const@f] +//~^ ERROR incompatible link kind for `f` +//~| NOTE this link resolved +//~| HELP add parentheses + +/// Link to [fn@std] +//~^ ERROR unresolved link to `std` +//~| NOTE this link resolves to the crate `std` +//~| HELP to link to the crate, prefix with `mod@` +pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr new file mode 100644 index 000000000..ee35749ce --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr @@ -0,0 +1,153 @@ +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:16:14 + | +LL | /// Link to [struct@S] + | ^^^^^^^^ this link resolved to an enum, which is not a struct + | +note: the lint level is defined here + --> $DIR/disambiguator-mismatch.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:21:14 + | +LL | /// Link to [mod@S] + | ^^^^^ this link resolved to an enum, which is not a module + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:26:14 + | +LL | /// Link to [union@S] + | ^^^^^^^ this link resolved to an enum, which is not a union + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `S` + --> $DIR/disambiguator-mismatch.rs:31:14 + | +LL | /// Link to [trait@S] + | ^^^^^^^ this link resolved to an enum, which is not a trait + | +help: to link to the enum, prefix with `enum@` + | +LL | /// Link to [enum@S] + | ~~~~~ + +error: incompatible link kind for `T` + --> $DIR/disambiguator-mismatch.rs:36:14 + | +LL | /// Link to [struct@T] + | ^^^^^^^^ this link resolved to a trait, which is not a struct + | +help: to link to the trait, prefix with `trait@` + | +LL | /// Link to [trait@T] + | ~~~~~~ + +error: incompatible link kind for `m` + --> $DIR/disambiguator-mismatch.rs:41:14 + | +LL | /// Link to [derive@m] + | ^^^^^^^^ this link resolved to a macro, which is not a derive macro + | +help: to link to the macro, add an exclamation mark + | +LL - /// Link to [derive@m] +LL + /// Link to [m!] + | + +error: unresolved link to `m` + --> $DIR/disambiguator-mismatch.rs:46:14 + | +LL | /// Link to [m()] + | ^^^ this link resolves to the macro `m`, which is not in the value namespace + | +help: to link to the macro, add an exclamation mark + | +LL | /// Link to [m!()] + | + + +error: incompatible link kind for `s` + --> $DIR/disambiguator-mismatch.rs:52:14 + | +LL | /// Link to [const@s] + | ^^^^^^^ this link resolved to a static, which is not a constant + | +help: to link to the static, prefix with `static@` + | +LL | /// Link to [static@s] + | ~~~~~~~ + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:57:14 + | +LL | /// Link to [static@c] + | ^^^^^^^^ this link resolved to a constant, which is not a static + | +help: to link to the constant, prefix with `const@` + | +LL | /// Link to [const@c] + | ~~~~~~ + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:62:14 + | +LL | /// Link to [fn@c] + | ^^^^ this link resolved to a constant, which is not a function + | +help: to link to the constant, prefix with `const@` + | +LL | /// Link to [const@c] + | ~~~~~~ + +error: incompatible link kind for `c` + --> $DIR/disambiguator-mismatch.rs:67:14 + | +LL | /// Link to [c()] + | ^^^ this link resolved to a constant, which is not a function + | +help: to link to the constant, prefix with `const@` + | +LL - /// Link to [c()] +LL + /// Link to [const@c] + | + +error: incompatible link kind for `f` + --> $DIR/disambiguator-mismatch.rs:72:14 + | +LL | /// Link to [const@f] + | ^^^^^^^ this link resolved to a function, which is not a constant + | +help: to link to the function, add parentheses + | +LL - /// Link to [const@f] +LL + /// Link to [f()] + | + +error: unresolved link to `std` + --> $DIR/disambiguator-mismatch.rs:77:14 + | +LL | /// Link to [fn@std] + | ^^^^^^ this link resolves to the crate `std`, which is not in the value namespace + | +help: to link to the crate, prefix with `mod@` + | +LL | /// Link to [mod@std] + | ~~~~ + +error: aborting due to 13 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/double-anchor.rs b/src/test/rustdoc-ui/intra-doc/double-anchor.rs new file mode 100644 index 000000000..a01211c4f --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/double-anchor.stderr b/src/test/rustdoc-ui/intra-doc/double-anchor.stderr new file mode 100644 index 000000000..6addb010e --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs new file mode 100644 index 000000000..7a5156e81 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -0,0 +1,7 @@ +// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +// check-pass +#![deny(warnings)] + +//! Email me at <hello@localhost>. + +//! This should *not* warn: <hello@example.com>. diff --git a/src/test/rustdoc-ui/intra-doc/errors.rs b/src/test/rustdoc-ui/intra-doc/errors.rs new file mode 100644 index 000000000..b29f7c29b --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/errors.rs @@ -0,0 +1,105 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined + +// FIXME: this should say that it was skipped (maybe an allowed by default lint?) +/// [invalid intra-doc syntax!!] + +/// [path::to::nonexistent::module] +//~^ ERROR unresolved link +//~| NOTE no item named `path` in scope + +/// [path::to::nonexistent::macro!] +//~^ ERROR unresolved link +//~| NOTE no item named `path` in scope + +/// [type@path::to::nonexistent::type] +//~^ ERROR unresolved link +//~| NOTE no item named `path` in scope + +/// [std::io::not::here] +//~^ ERROR unresolved link +//~| NOTE no item named `not` in module `io` + +/// [type@std::io::not::here] +//~^ ERROR unresolved link +//~| NOTE no item named `not` in module `io` + +/// [std::io::Error::x] +//~^ ERROR unresolved link +//~| NOTE the struct `Error` has no field + +/// [std::io::ErrorKind::x] +//~^ ERROR unresolved link +//~| NOTE the enum `ErrorKind` has no variant + +/// [f::A] +//~^ ERROR unresolved link +//~| NOTE `f` is a function, not a module + +/// [f::A!] +//~^ ERROR unresolved link +//~| NOTE `f` is a function, not a module + +/// [S::A] +//~^ ERROR unresolved link +//~| NOTE struct `S` has no field or associated item + +/// [S::fmt] +//~^ ERROR unresolved link +//~| NOTE struct `S` has no field or associated item + +/// [E::D] +//~^ ERROR unresolved link +//~| NOTE enum `E` has no variant or associated item + +/// [u8::not_found] +//~^ ERROR unresolved link +//~| NOTE the builtin type `u8` has no associated item named `not_found` + +/// [std::primitive::u8::not_found] +//~^ ERROR unresolved link +//~| NOTE the builtin type `u8` has no associated item named `not_found` + +/// [type@Vec::into_iter] +//~^ ERROR unresolved link +//~| HELP to link to the associated function, add parentheses +//~| NOTE this link resolves to the associated function `into_iter` + +/// [S!] +//~^ ERROR unresolved link +//~| HELP to link to the struct, prefix with `struct@` +//~| NOTE this link resolves to the struct `S` +pub fn f() {} +#[derive(Debug)] +pub struct S; + +pub enum E { A, B, C } + +/// [type@S::h] +//~^ ERROR unresolved link +//~| HELP to link to the associated function +//~| NOTE not in the type namespace +impl S { + pub fn h() {} +} + +/// [type@T::g] +//~^ ERROR unresolved link +//~| HELP to link to the associated function +//~| NOTE not in the type namespace + +/// [T::h!] +//~^ ERROR unresolved link +//~| NOTE `T` has no macro named `h` +pub trait T { + fn g() {} +} + +/// [m()] +//~^ ERROR unresolved link +//~| HELP to link to the macro +//~| NOTE not in the value namespace +#[macro_export] +macro_rules! m { + () => {}; +} diff --git a/src/test/rustdoc-ui/intra-doc/errors.stderr b/src/test/rustdoc-ui/intra-doc/errors.stderr new file mode 100644 index 000000000..9a1896fb0 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/errors.stderr @@ -0,0 +1,157 @@ +error: unresolved link to `path::to::nonexistent::module` + --> $DIR/errors.rs:7:6 + | +LL | /// [path::to::nonexistent::module] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope + | +note: the lint level is defined here + --> $DIR/errors.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `path::to::nonexistent::macro` + --> $DIR/errors.rs:11:6 + | +LL | /// [path::to::nonexistent::macro!] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope + +error: unresolved link to `path::to::nonexistent::type` + --> $DIR/errors.rs:15:6 + | +LL | /// [type@path::to::nonexistent::type] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope + +error: unresolved link to `std::io::not::here` + --> $DIR/errors.rs:19:6 + | +LL | /// [std::io::not::here] + | ^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` + +error: unresolved link to `std::io::not::here` + --> $DIR/errors.rs:23:6 + | +LL | /// [type@std::io::not::here] + | ^^^^^^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` + +error: unresolved link to `std::io::Error::x` + --> $DIR/errors.rs:27:6 + | +LL | /// [std::io::Error::x] + | ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x` + +error: unresolved link to `std::io::ErrorKind::x` + --> $DIR/errors.rs:31:6 + | +LL | /// [std::io::ErrorKind::x] + | ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x` + +error: unresolved link to `f::A` + --> $DIR/errors.rs:35:6 + | +LL | /// [f::A] + | ^^^^ `f` is a function, not a module or type, and cannot have associated items + +error: unresolved link to `f::A` + --> $DIR/errors.rs:39:6 + | +LL | /// [f::A!] + | ^^^^^ `f` is a function, not a module or type, and cannot have associated items + +error: unresolved link to `S::A` + --> $DIR/errors.rs:43:6 + | +LL | /// [S::A] + | ^^^^ the struct `S` has no field or associated item named `A` + +error: unresolved link to `S::fmt` + --> $DIR/errors.rs:47:6 + | +LL | /// [S::fmt] + | ^^^^^^ the struct `S` has no field or associated item named `fmt` + +error: unresolved link to `E::D` + --> $DIR/errors.rs:51:6 + | +LL | /// [E::D] + | ^^^^ the enum `E` has no variant or associated item named `D` + +error: unresolved link to `u8::not_found` + --> $DIR/errors.rs:55:6 + | +LL | /// [u8::not_found] + | ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` + +error: unresolved link to `std::primitive::u8::not_found` + --> $DIR/errors.rs:59:6 + | +LL | /// [std::primitive::u8::not_found] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` + +error: unresolved link to `Vec::into_iter` + --> $DIR/errors.rs:63:6 + | +LL | /// [type@Vec::into_iter] + | ^^^^^^^^^^^^^^^^^^^ this link resolves to the associated function `into_iter`, which is not in the type namespace + | +help: to link to the associated function, add parentheses + | +LL - /// [type@Vec::into_iter] +LL + /// [Vec::into_iter()] + | + +error: unresolved link to `S` + --> $DIR/errors.rs:68:6 + | +LL | /// [S!] + | ^^ this link resolves to the struct `S`, which is not in the macro namespace + | +help: to link to the struct, prefix with `struct@` + | +LL - /// [S!] +LL + /// [struct@S] + | + +error: unresolved link to `S::h` + --> $DIR/errors.rs:78:6 + | +LL | /// [type@S::h] + | ^^^^^^^^^ this link resolves to the associated function `h`, which is not in the type namespace + | +help: to link to the associated function, add parentheses + | +LL - /// [type@S::h] +LL + /// [S::h()] + | + +error: unresolved link to `T::g` + --> $DIR/errors.rs:86:6 + | +LL | /// [type@T::g] + | ^^^^^^^^^ this link resolves to the associated function `g`, which is not in the type namespace + | +help: to link to the associated function, add parentheses + | +LL - /// [type@T::g] +LL + /// [T::g()] + | + +error: unresolved link to `T::h` + --> $DIR/errors.rs:91:6 + | +LL | /// [T::h!] + | ^^^^^ the trait `T` has no macro named `h` + +error: unresolved link to `m` + --> $DIR/errors.rs:98:6 + | +LL | /// [m()] + | ^^^ this link resolves to the macro `m`, which is not in the value namespace + | +help: to link to the macro, add an exclamation mark + | +LL | /// [m!()] + | + + +error: aborting due to 20 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/extern-crate-load.rs b/src/test/rustdoc-ui/intra-doc/extern-crate-load.rs new file mode 100644 index 000000000..438c56aa5 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.rs new file mode 100644 index 000000000..3cfac942c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr new file mode 100644 index 000000000..2c946ed48 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/feature-gate-intra-doc-pointers.stderr @@ -0,0 +1,23 @@ +error[E0658]: linking to associated items of raw pointers is experimental + --> $DIR/feature-gate-intra-doc-pointers.rs:1:6 + | +LL | //! [pointer::add] + | ^^^^^^^^^^^^ + | + = note: see issue #80896 <https://github.com/rust-lang/rust/issues/80896> for more information + = help: add `#![feature(intra_doc_pointers)]` to the crate attributes to enable + = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does + +error[E0658]: linking to associated items of raw pointers is experimental + --> $DIR/feature-gate-intra-doc-pointers.rs:3:6 + | +LL | //! [pointer::wrapping_add] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #80896 <https://github.com/rust-lang/rust/issues/80896> for more information + = help: add `#![feature(intra_doc_pointers)]` to the crate attributes to enable + = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/rustdoc-ui/intra-doc/field-ice.rs b/src/test/rustdoc-ui/intra-doc/field-ice.rs new file mode 100644 index 000000000..c5d501e38 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/field-ice.rs @@ -0,0 +1,11 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^NOTE the lint level is defined here + +/// [`Foo::bar`] +/// [`Foo::bar()`] +//~^ERROR incompatible link kind for `Foo::bar` +//~|HELP to link to the field, remove the disambiguator +//~|NOTE this link resolved to a field, which is not a function +pub struct Foo { + pub bar: u8 +} diff --git a/src/test/rustdoc-ui/intra-doc/field-ice.stderr b/src/test/rustdoc-ui/intra-doc/field-ice.stderr new file mode 100644 index 000000000..f45a3ca61 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/field-ice.stderr @@ -0,0 +1,18 @@ +error: incompatible link kind for `Foo::bar` + --> $DIR/field-ice.rs:5:7 + | +LL | /// [`Foo::bar()`] + | ^^^^^^^^^^ this link resolved to a field, which is not a function + | +note: the lint level is defined here + --> $DIR/field-ice.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the field, remove the disambiguator + | +LL | /// [`Foo::bar`] + | ~~~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/global-path.rs b/src/test/rustdoc-ui/intra-doc/global-path.rs new file mode 100644 index 000000000..cc7a5fa1c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/global-path.stderr b/src/test/rustdoc-ui/intra-doc/global-path.stderr new file mode 100644 index 000000000..02379cd6c --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.rs b/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.rs new file mode 100644 index 000000000..b5470c859 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr b/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr new file mode 100644 index 000000000..00fe229da --- /dev/null +++ b/src/test/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 + | +note: the lint level is defined here + --> $DIR/html-as-generics-intra-doc.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +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/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.rs new file mode 100644 index 000000000..3088bcd46 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr new file mode 100644 index 000000000..c43cda3eb --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/incompatible-primitive-disambiguator.stderr @@ -0,0 +1,18 @@ +error: incompatible link kind for `u8::MIN` + --> $DIR/incompatible-primitive-disambiguator.rs:2:6 + | +LL | //! [static@u8::MIN] + | ^^^^^^^^^^^^^^ this link resolved to an associated constant, which is not a static + | +note: the lint level is defined here + --> $DIR/incompatible-primitive-disambiguator.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the associated constant, prefix with `const@` + | +LL | //! [const@u8::MIN] + | ~~~~~~ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules-error.rs b/src/test/rustdoc-ui/intra-doc/macro-rules-error.rs new file mode 100644 index 000000000..8490584c1 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr new file mode 100644 index 000000000..8e17323fd --- /dev/null +++ b/src/test/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: the lint level is defined here + --> $DIR/macro-rules-error.rs:5:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `macro_rules` named `before_but_limited_to_module` exists in this crate, but it is not in scope at this link's location + +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/src/test/rustdoc-ui/intra-doc/macro-rules.rs b/src/test/rustdoc-ui/intra-doc/macro-rules.rs new file mode 100644 index 000000000..3aeb370ef --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/malformed-generics.rs b/src/test/rustdoc-ui/intra-doc/malformed-generics.rs new file mode 100644 index 000000000..15e02925e --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/malformed-generics.rs @@ -0,0 +1,19 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +//! [Vec<] //~ ERROR +//! [Vec<Box<T] //~ ERROR +//! [Vec<Box<T>] //~ ERROR +//! [Vec<Box<T>>>] //~ ERROR +//! [Vec<T>>>] //~ ERROR +//! [<Vec] //~ ERROR +//! [Vec::<] //~ ERROR +//! [<T>] //~ ERROR +//! [<invalid syntax>] //~ ERROR +//! [Vec:<T>:new()] //~ ERROR +//! [Vec<<T>>] //~ ERROR +//! [Vec<>] //~ ERROR +//! [Vec<<>>] //~ ERROR + +// FIXME(#74563) support UFCS +//! [<Vec as IntoIterator>::into_iter] //~ ERROR +//! [<Vec<T> as IntoIterator>::iter] //~ ERROR diff --git a/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr b/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr new file mode 100644 index 000000000..5bc0f84e2 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/malformed-generics.stderr @@ -0,0 +1,102 @@ +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:6:6 + | +LL | //! [Vec<Box<T>>>] + | ^^^^^^^^^^^^ unbalanced angle brackets + +error: unresolved link to `Vec<T>>>` + --> $DIR/malformed-generics.rs:7:6 + | +LL | //! [Vec<T>>>] + | ^^^^^^^^ unbalanced angle brackets + +error: unresolved link to `<Vec` + --> $DIR/malformed-generics.rs:8:6 + | +LL | //! [<Vec] + | ^^^^ unbalanced angle brackets + +error: unresolved link to `Vec::<` + --> $DIR/malformed-generics.rs:9:6 + | +LL | //! [Vec::<] + | ^^^^^^ unbalanced angle brackets + +error: unresolved link to `<T>` + --> $DIR/malformed-generics.rs:10:6 + | +LL | //! [<T>] + | ^^^ missing type for generic parameters + +error: unresolved link to `<invalid syntax>` + --> $DIR/malformed-generics.rs:11:6 + | +LL | //! [<invalid syntax>] + | ^^^^^^^^^^^^^^^^ missing type for generic parameters + +error: unresolved link to `Vec:<T>:new` + --> $DIR/malformed-generics.rs:12:6 + | +LL | //! [Vec:<T>:new()] + | ^^^^^^^^^^^^^ has invalid path separator + +error: unresolved link to `Vec<<T>>` + --> $DIR/malformed-generics.rs:13:6 + | +LL | //! [Vec<<T>>] + | ^^^^^^^^ too many angle brackets + +error: unresolved link to `Vec<>` + --> $DIR/malformed-generics.rs:14:6 + | +LL | //! [Vec<>] + | ^^^^^ empty angle brackets + +error: unresolved link to `Vec<<>>` + --> $DIR/malformed-generics.rs:15:6 + | +LL | //! [Vec<<>>] + | ^^^^^^^ too many angle brackets + +error: unresolved link to `<Vec as IntoIterator>::into_iter` + --> $DIR/malformed-generics.rs:18: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:19: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 + +error: aborting due to 15 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs new file mode 100644 index 000000000..587cbad68 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs @@ -0,0 +1,34 @@ +#![deny(rustdoc::broken_intra_doc_links)] +#![feature(intra_doc_pointers)] +// These are links that could reasonably expected to work, but don't. + +// `[]` isn't supported because it had too many false positives. +//! [X]([T]::not_here) +//! [Y](&[]::not_here) +//! [X]([]::not_here) +//! [Y]([T;N]::not_here) + +// These don't work because markdown syntax doesn't allow it. +//! [[T]::rotate_left] //~ ERROR unresolved link to `T` +//! [&[]::not_here] +//![Z]([T; N]::map) //~ ERROR unresolved link to `Z` +//! [`[T; N]::map`] +//! [[]::map] +//! [Z][] //~ ERROR unresolved link to `Z` +//! +//! [Z]: [T; N]::map //~ ERROR unresolved link to `Z` + +// `()` isn't supported because it had too many false positives. +//! [()::not_here] +//! [X]((,)::not_here) +//! [(,)::not_here] + +// FIXME: Associated items on some primitives aren't working, because the impls +// are part of the compiler instead of being part of the source code. +//! [unit::eq] //~ ERROR unresolved +//! [tuple::eq] //~ ERROR unresolved +//! [fn::eq] //~ ERROR unresolved + +// FIXME(#78800): This breaks because it's a blanket impl +// (I think? Might break for other reasons too.) +//! [reference::deref] //~ ERROR unresolved diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr new file mode 100644 index 000000000..4828a3044 --- /dev/null +++ b/src/test/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 + | +note: the lint level is defined here + --> $DIR/non-path-primitives.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:14:5 + | +LL | //![Z]([T; N]::map) + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:17:6 + | +LL | //! [Z][] + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `Z` + --> $DIR/non-path-primitives.rs:19:6 + | +LL | //! [Z]: [T; N]::map + | ^ no item named `Z` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unresolved link to `unit::eq` + --> $DIR/non-path-primitives.rs:28:6 + | +LL | //! [unit::eq] + | ^^^^^^^^ the builtin type `unit` has no associated item named `eq` + +error: unresolved link to `tuple::eq` + --> $DIR/non-path-primitives.rs:29:6 + | +LL | //! [tuple::eq] + | ^^^^^^^^^ the builtin type `tuple` has no associated item named `eq` + +error: unresolved link to `fn::eq` + --> $DIR/non-path-primitives.rs:30:6 + | +LL | //! [fn::eq] + | ^^^^^^ the builtin type `fn` has no associated item named `eq` + +error: unresolved link to `reference::deref` + --> $DIR/non-path-primitives.rs:34:6 + | +LL | //! [reference::deref] + | ^^^^^^^^^^^^^^^^ the builtin type `reference` has no associated item named `deref` + +error: aborting due to 8 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/pointer-reexports-allowed.rs b/src/test/rustdoc-ui/intra-doc/pointer-reexports-allowed.rs new file mode 100644 index 000000000..8654a8e1b --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/prim-conflict.rs b/src/test/rustdoc-ui/intra-doc/prim-conflict.rs new file mode 100644 index 000000000..2c1a8b535 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/prim-conflict.rs @@ -0,0 +1,30 @@ +#![deny(rustdoc::broken_intra_doc_links)] +//~^ NOTE lint level is defined + +/// [char] +//~^ ERROR both a module and a builtin type +//~| NOTE ambiguous link +//~| HELP to link to the module +//~| HELP to link to the builtin type + +/// [type@char] +//~^ ERROR both a module and a builtin type +//~| NOTE ambiguous link +//~| HELP to link to the module +//~| HELP to link to the builtin type + +/// [mod@char] // ok +/// [prim@char] // ok + +/// [struct@char] +//~^ ERROR incompatible link +//~| HELP prefix with `mod@` +//~| NOTE resolved to a module +pub mod char {} + +pub mod inner { + //! [struct@char] + //~^ ERROR incompatible link + //~| HELP prefix with `prim@` + //~| NOTE resolved to a builtin type +} diff --git a/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr b/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr new file mode 100644 index 000000000..6ef3b7eab --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/prim-conflict.stderr @@ -0,0 +1,59 @@ +error: `char` is both a module and a builtin type + --> $DIR/prim-conflict.rs:4:6 + | +LL | /// [char] + | ^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/prim-conflict.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@char] + | ++++ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@char] + | +++++ + +error: `char` is both a module and a builtin type + --> $DIR/prim-conflict.rs:10:6 + | +LL | /// [type@char] + | ^^^^^^^^^ ambiguous link + | +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@char] + | ~~~~ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@char] + | ~~~~~ + +error: incompatible link kind for `char` + --> $DIR/prim-conflict.rs:19:6 + | +LL | /// [struct@char] + | ^^^^^^^^^^^ this link resolved to a module, which is not a struct + | +help: to link to the module, prefix with `mod@` + | +LL | /// [mod@char] + | ~~~~ + +error: incompatible link kind for `char` + --> $DIR/prim-conflict.rs:26:10 + | +LL | //! [struct@char] + | ^^^^^^^^^^^ this link resolved to a builtin type, which is not a struct + | +help: to link to the builtin type, prefix with `prim@` + | +LL | //! [prim@char] + | ~~~~~ + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/private-from-crate-level.rs b/src/test/rustdoc-ui/intra-doc/private-from-crate-level.rs new file mode 100644 index 000000000..e429e75b2 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr b/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr new file mode 100644 index 000000000..6172cd2e3 --- /dev/null +++ b/src/test/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: `#[warn(rustdoc::private_intra_doc_links)]` on by default + = note: this link will resolve properly if you pass `--document-private-items` + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/intra-doc/private.private.stderr b/src/test/rustdoc-ui/intra-doc/private.private.stderr new file mode 100644 index 000000000..392321f9c --- /dev/null +++ b/src/test/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: `#[warn(rustdoc::private_intra_doc_links)]` on by default + = 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::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/src/test/rustdoc-ui/intra-doc/private.public.stderr b/src/test/rustdoc-ui/intra-doc/private.public.stderr new file mode 100644 index 000000000..5d1c34b91 --- /dev/null +++ b/src/test/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: `#[warn(rustdoc::private_intra_doc_links)]` on by default + = note: this link will resolve properly if you pass `--document-private-items` + +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/src/test/rustdoc-ui/intra-doc/private.rs b/src/test/rustdoc-ui/intra-doc/private.rs new file mode 100644 index 000000000..525332dda --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/span-ice-55723.rs b/src/test/rustdoc-ui/intra-doc/span-ice-55723.rs new file mode 100644 index 000000000..041ec2932 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr new file mode 100644 index 000000000..bf4ab9fdd --- /dev/null +++ b/src/test/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 + | +note: the lint level is defined here + --> $DIR/span-ice-55723.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/through-proc-macro.rs b/src/test/rustdoc-ui/intra-doc/through-proc-macro.rs new file mode 100644 index 000000000..7628c3928 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr b/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr new file mode 100644 index 000000000..f0a7ed178 --- /dev/null +++ b/src/test/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 + | +note: the lint level is defined here + --> $DIR/through-proc-macro.rs:7:9 + | +LL | #![warn(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs new file mode 100644 index 000000000..0aa1e5a41 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -0,0 +1,14 @@ +// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +#![deny(warnings)] + +//! Linking to [foo@banana] and [`bar@banana!()`]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `bar` +//! And to [no disambiguator](@nectarine) and [another](@apricot!()). +//~^ ERROR unknown disambiguator `` +//~| ERROR unknown disambiguator `` +//! And with weird backticks: [``foo@hello``] [foo`@`hello]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `foo` + +fn main() {} diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr new file mode 100644 index 000000000..d280e6497 --- /dev/null +++ b/src/test/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: 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)]` + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +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/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/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/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/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/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + +error: aborting due to 6 previous errors + diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs new file mode 100644 index 000000000..c71e5bee1 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr new file mode 100644 index 000000000..b54f82006 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -0,0 +1,13 @@ +error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`? + --> $DIR/unresolved-import-recovery.rs:3:5 + | +LL | use unresolved_crate::module::Name; + | ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`? + | + = help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.rs b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.rs new file mode 100644 index 000000000..956583093 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr new file mode 100644 index 000000000..5c0df1d1b --- /dev/null +++ b/src/test/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 + | +note: the lint level is defined here + --> $DIR/unused-extern-crate.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/warning-crlf.rs b/src/test/rustdoc-ui/intra-doc/warning-crlf.rs new file mode 100644 index 000000000..ceb62f6d1 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr new file mode 100644 index 000000000..d46df9264 --- /dev/null +++ b/src/test/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 + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +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/src/test/rustdoc-ui/intra-doc/warning.rs b/src/test/rustdoc-ui/intra-doc/warning.rs new file mode 100644 index 000000000..eab1f0348 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/warning.rs @@ -0,0 +1,84 @@ +// check-pass + + //! Test with [Foo::baz], [Bar::foo], ... +//~^ WARNING `Foo::baz` +//~| WARNING `Bar::foo` + //! , [Uniooon::X] and [Qux::Z]. +//~^ WARNING `Uniooon::X` +//~| WARNING `Qux::Z` + //! + //! , [Uniooon::X] and [Qux::Z]. +//~^ WARNING `Uniooon::X` +//~| WARNING `Qux::Z` + + /// [Qux:Y] +//~^ WARNING `Qux:Y` +pub struct Foo { + pub bar: usize, +} + +/// Foo +/// bar [BarA] bar //~ WARNING `BarA` +/// baz +pub fn a() {} + +/** + * Foo + * bar [BarB] bar //~ WARNING `BarB` + * baz + */ +pub fn b() {} + +/** Foo + +bar [BarC] bar //~ WARNING `BarC` +baz + + let bar_c_1 = 0; + let bar_c_2 = 0; + let g = [bar_c_1]; + let h = g[bar_c_2]; + +*/ +pub fn c() {} + +#[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `BarD` +pub fn d() {} + +macro_rules! f { + ($f:expr) => { + #[doc = $f] //~ WARNING `BarF` + pub fn f() {} + } +} +f!("Foo\nbar [BarF] bar\nbaz"); + +/** # for example, + * + * time to introduce a link [error]*/ //~ WARNING `error` +pub struct A; + +/** + * # for example, + * + * time to introduce a link [error] //~ WARNING `error` + */ +pub struct B; + +#[doc = "single line [error]"] //~ WARNING `error` +pub struct C; + +#[doc = "single line with \"escaping\" [error]"] //~ WARNING `error` +pub struct D; + +/// Item docs. //~ WARNING `error` +#[doc="Hello there!"] +/// [error] +pub struct E; + +/// +/// docs [error1] //~ WARNING `error1` + +/// docs [error2] //~ WARNING `error2` +/// +pub struct F; diff --git a/src/test/rustdoc-ui/intra-doc/warning.stderr b/src/test/rustdoc-ui/intra-doc/warning.stderr new file mode 100644 index 000000000..19399a0df --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/warning.stderr @@ -0,0 +1,175 @@ +warning: unresolved link to `Foo::baz` + --> $DIR/warning.rs:3:23 + | +LL | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ the struct `Foo` has no field or associated item named `baz` + | + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: unresolved link to `Bar::foo` + --> $DIR/warning.rs:3:35 + | +LL | //! Test with [Foo::baz], [Bar::foo], ... + | ^^^^^^^^ no item named `Bar` in scope + +warning: unresolved link to `Uniooon::X` + --> $DIR/warning.rs:6:13 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ no item named `Uniooon` in scope + +warning: unresolved link to `Qux::Z` + --> $DIR/warning.rs:6:30 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ no item named `Qux` in scope + +warning: unresolved link to `Uniooon::X` + --> $DIR/warning.rs:10:14 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^^^^^ no item named `Uniooon` in scope + +warning: unresolved link to `Qux::Z` + --> $DIR/warning.rs:10:31 + | +LL | //! , [Uniooon::X] and [Qux::Z]. + | ^^^^^^ no item named `Qux` in scope + +warning: unresolved link to `Qux:Y` + --> $DIR/warning.rs:14:13 + | +LL | /// [Qux:Y] + | ^^^^^ no item named `Qux:Y` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarA` + --> $DIR/warning.rs:21:10 + | +LL | /// bar [BarA] bar + | ^^^^ no item named `BarA` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarB` + --> $DIR/warning.rs:27:9 + | +LL | * bar [BarB] bar + | ^^^^ no item named `BarB` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarC` + --> $DIR/warning.rs:34:6 + | +LL | bar [BarC] bar + | ^^^^ no item named `BarC` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarD` + --> $DIR/warning.rs:45:1 + | +LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + bar [BarD] bar + ^^^^ + = note: no item named `BarD` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `BarF` + --> $DIR/warning.rs:50:9 + | +LL | #[doc = $f] + | ^^^^^^^^^^^ +... +LL | f!("Foo\nbar [BarF] bar\nbaz"); + | ------------------------------ in this macro invocation + | + = note: the link appears in this line: + + bar [BarF] bar + ^^^^ + = note: no item named `BarF` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: unresolved link to `error` + --> $DIR/warning.rs:58:30 + | +LL | * time to introduce a link [error]*/ + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:64:30 + | +LL | * time to introduce a link [error] + | ^^^^^ no item named `error` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:68:1 + | +LL | #[doc = "single line [error]"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + single line [error] + ^^^^^ + = note: no item named `error` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:71:1 + | +LL | #[doc = "single line with \"escaping\" [error]"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + single line with "escaping" [error] + ^^^^^ + = note: no item named `error` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error` + --> $DIR/warning.rs:74:1 + | +LL | / /// Item docs. +LL | | #[doc="Hello there!"] +LL | | /// [error] + | |___________^ + | + = note: the link appears in this line: + + [error] + ^^^^^ + = note: no item named `error` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error1` + --> $DIR/warning.rs:80:11 + | +LL | /// docs [error1] + | ^^^^^^ no item named `error1` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `error2` + --> $DIR/warning.rs:82:11 + | +LL | /// docs [error2] + | ^^^^^^ no item named `error2` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: 19 warnings emitted + diff --git a/src/test/rustdoc-ui/invalid-cfg.rs b/src/test/rustdoc-ui/invalid-cfg.rs new file mode 100644 index 000000000..d237b8605 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/invalid-cfg.stderr b/src/test/rustdoc-ui/invalid-cfg.stderr new file mode 100644 index 000000000..dae238b05 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/invalid-doc-attr.rs b/src/test/rustdoc-ui/invalid-doc-attr.rs new file mode 100644 index 000000000..de004b41e --- /dev/null +++ b/src/test/rustdoc-ui/invalid-doc-attr.rs @@ -0,0 +1,32 @@ +#![crate_type = "lib"] +#![deny(warnings)] + +#[doc(test(no_crate_inject))] +//~^ ERROR can only be applied at the crate level +//~| WARN is being phased out +//~| HELP to apply to the crate, use an inner attribute +//~| SUGGESTION #![doc(test(no_crate_inject))] +#[doc(inline)] +//~^ ERROR can only be applied to a `use` item +//~| WARN is being phased out +pub fn foo() {} + +pub mod bar { + #![doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + //~| WARN is being phased out + + #[doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + //~| WARN is being phased out + #[doc(inline)] + //~^ ERROR can only be applied to a `use` item + //~| WARN is being phased out + pub fn baz() {} +} + +#[doc(inline)] +#[doc(no_inline)] +//~^^ ERROR conflicting doc inlining attributes +//~| HELP remove one of the conflicting attributes +pub use bar::baz; diff --git a/src/test/rustdoc-ui/invalid-doc-attr.stderr b/src/test/rustdoc-ui/invalid-doc-attr.stderr new file mode 100644 index 000000000..a4fa38179 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-doc-attr.stderr @@ -0,0 +1,78 @@ +error: this attribute can only be applied at the crate level + --> $DIR/invalid-doc-attr.rs:4:7 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/invalid-doc-attr.rs:2:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information +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:9:7 + | +LL | #[doc(inline)] + | ^^^^^^ only applicable on `use` items +... +LL | pub fn foo() {} + | ------------ not a `use` item + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = 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:15:12 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = 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:28: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 at the crate level + --> $DIR/invalid-doc-attr.rs:19:11 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = 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:22:11 + | +LL | #[doc(inline)] + | ^^^^^^ only applicable on `use` items +... +LL | pub fn baz() {} + | ------------ not a `use` item + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information + +error: aborting due to 6 previous errors + diff --git a/src/test/rustdoc-ui/invalid-html-tags.rs b/src/test/rustdoc-ui/invalid-html-tags.rs new file mode 100644 index 000000000..0f9d2e4b3 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-html-tags.rs @@ -0,0 +1,116 @@ +#![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() {} diff --git a/src/test/rustdoc-ui/invalid-html-tags.stderr b/src/test/rustdoc-ui/invalid-html-tags.stderr new file mode 100644 index 000000000..24a455576 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-html-tags.stderr @@ -0,0 +1,98 @@ +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: aborting due to 15 previous errors + diff --git a/src/test/rustdoc-ui/invalid-keyword.rs b/src/test/rustdoc-ui/invalid-keyword.rs new file mode 100644 index 000000000..2d70471c8 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-keyword.rs @@ -0,0 +1,4 @@ +#![feature(rustdoc_internals)] + +#[doc(keyword = "foo df")] //~ ERROR +mod foo {} diff --git a/src/test/rustdoc-ui/invalid-keyword.stderr b/src/test/rustdoc-ui/invalid-keyword.stderr new file mode 100644 index 000000000..8658e3825 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-keyword.stderr @@ -0,0 +1,8 @@ +error: `foo df` is not a valid identifier + --> $DIR/invalid-keyword.rs:3:17 + | +LL | #[doc(keyword = "foo df")] + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs new file mode 100644 index 000000000..b503d1093 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-syntax.rs @@ -0,0 +1,101 @@ +// 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() {} +//~^^^^^ 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 diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr new file mode 100644 index 000000000..4c6249cc6 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-syntax.stderr @@ -0,0 +1,154 @@ +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: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default + = note: error from rustc: unknown start of token: \ + = 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: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: ` + = note: error from rustc: unknown start of token: ` + = 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:1 + | +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: 12 warnings emitted + diff --git a/src/test/rustdoc-ui/invalid-theme-name.rs b/src/test/rustdoc-ui/invalid-theme-name.rs new file mode 100644 index 000000000..c22ebf027 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-theme-name.rs @@ -0,0 +1,3 @@ +// compile-flags:--theme {{src-base}}/invalid-theme-name.rs +// error-pattern: invalid argument +// error-pattern: must have a .css extension diff --git a/src/test/rustdoc-ui/invalid-theme-name.stderr b/src/test/rustdoc-ui/invalid-theme-name.stderr new file mode 100644 index 000000000..80204442d --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/issue-58473-2.rs b/src/test/rustdoc-ui/issue-58473-2.rs new file mode 100644 index 000000000..000b6a329 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-58473.rs b/src/test/rustdoc-ui/issue-58473.rs new file mode 100644 index 000000000..44e1f58d0 --- /dev/null +++ b/src/test/rustdoc-ui/issue-58473.rs @@ -0,0 +1,10 @@ +// check-pass + +pub trait Foo { + /** + Does nothing, returns `()` + + yadda-yadda-yadda + */ + fn foo() {} +} diff --git a/src/test/rustdoc-ui/issue-61592-2.rs b/src/test/rustdoc-ui/issue-61592-2.rs new file mode 100644 index 000000000..5b4fc5ee7 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-61592-2.stderr b/src/test/rustdoc-ui/issue-61592-2.stderr new file mode 100644 index 000000000..1b7f8bb55 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + +For more information about this error, try `rustc --explain E0780`. diff --git a/src/test/rustdoc-ui/issue-61592.rs b/src/test/rustdoc-ui/issue-61592.rs new file mode 100644 index 000000000..66772557f --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-61592.stderr b/src/test/rustdoc-ui/issue-61592.stderr new file mode 100644 index 000000000..9c9c9106f --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + +For more information about this error, try `rustc --explain E0780`. diff --git a/src/test/rustdoc-ui/issue-61732.rs b/src/test/rustdoc-ui/issue-61732.rs new file mode 100644 index 000000000..4bd8efeaa --- /dev/null +++ b/src/test/rustdoc-ui/issue-61732.rs @@ -0,0 +1,4 @@ +// This previously triggered an ICE. + +pub(in crate::r#mod) fn main() {} +//~^ ERROR failed to resolve: maybe a missing crate `r#mod` diff --git a/src/test/rustdoc-ui/issue-61732.stderr b/src/test/rustdoc-ui/issue-61732.stderr new file mode 100644 index 000000000..38fadaa44 --- /dev/null +++ b/src/test/rustdoc-ui/issue-61732.stderr @@ -0,0 +1,13 @@ +error[E0433]: failed to resolve: maybe a missing crate `r#mod`? + --> $DIR/issue-61732.rs:3:15 + | +LL | pub(in crate::r#mod) fn main() {} + | ^^^^^ maybe a missing crate `r#mod`? + | + = help: consider adding `extern crate r#mod` to use the `r#mod` crate + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/rustdoc-ui/issue-74134.private.stderr b/src/test/rustdoc-ui/issue-74134.private.stderr new file mode 100644 index 000000000..31d2dbe96 --- /dev/null +++ b/src/test/rustdoc-ui/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: `#[warn(rustdoc::private_intra_doc_links)]` on by default + = note: this link resolves only because you passed `--document-private-items`, but will break without + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/issue-74134.public.stderr b/src/test/rustdoc-ui/issue-74134.public.stderr new file mode 100644 index 000000000..6a3173e3e --- /dev/null +++ b/src/test/rustdoc-ui/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: `#[warn(rustdoc::private_intra_doc_links)]` on by default + = note: this link will resolve properly if you pass `--document-private-items` + +warning: 1 warning emitted + diff --git a/src/test/rustdoc-ui/issue-74134.rs b/src/test/rustdoc-ui/issue-74134.rs new file mode 100644 index 000000000..b1be9123a --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-79465.rs b/src/test/rustdoc-ui/issue-79465.rs new file mode 100644 index 000000000..f1a77982f --- /dev/null +++ b/src/test/rustdoc-ui/issue-79465.rs @@ -0,0 +1,3 @@ +pub fn f1<T>(x: T::A) {} +//~^ ERROR +//~^^ ERROR diff --git a/src/test/rustdoc-ui/issue-79465.stderr b/src/test/rustdoc-ui/issue-79465.stderr new file mode 100644 index 000000000..489cc1442 --- /dev/null +++ b/src/test/rustdoc-ui/issue-79465.stderr @@ -0,0 +1,15 @@ +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[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 2 previous errors + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/rustdoc-ui/issue-79467.rs b/src/test/rustdoc-ui/issue-79467.rs new file mode 100644 index 000000000..eb0b9b380 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-79467.stderr b/src/test/rustdoc-ui/issue-79467.stderr new file mode 100644 index 000000000..561513a43 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/rustdoc-ui/issue-79494.rs b/src/test/rustdoc-ui/issue-79494.rs new file mode 100644 index 000000000..fc39424b7 --- /dev/null +++ b/src/test/rustdoc-ui/issue-79494.rs @@ -0,0 +1,5 @@ +// only-x86_64-unknown-linux-gnu + +#![feature(const_transmute)] + +const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types diff --git a/src/test/rustdoc-ui/issue-79494.stderr b/src/test/rustdoc-ui/issue-79494.stderr new file mode 100644 index 000000000..7ed5ed382 --- /dev/null +++ b/src/test/rustdoc-ui/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:29 + | +LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `usize` (64 bits) + = note: target type: `&[u8]` (128 bits) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/rustdoc-ui/issue-80992.rs b/src/test/rustdoc-ui/issue-80992.rs new file mode 100644 index 000000000..8983439bb --- /dev/null +++ b/src/test/rustdoc-ui/issue-80992.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags:--test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +pub fn test() -> Result<(), ()> { + //! ```compile_fail + //! fn test() -> Result< {} + //! ``` + Ok(()) +} diff --git a/src/test/rustdoc-ui/issue-80992.stdout b/src/test/rustdoc-ui/issue-80992.stdout new file mode 100644 index 000000000..d2b1cd1d5 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-81662-shortness.rs b/src/test/rustdoc-ui/issue-81662-shortness.rs new file mode 100644 index 000000000..27a21a313 --- /dev/null +++ b/src/test/rustdoc-ui/issue-81662-shortness.rs @@ -0,0 +1,12 @@ +// compile-flags:--test --error-format=short +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// failure-status: 101 + +/// ```rust +/// foo(); +/// ``` +//~^^ ERROR cannot find function `foo` in this scope +fn foo() { + println!("Hello, world!"); +} diff --git a/src/test/rustdoc-ui/issue-81662-shortness.stdout b/src/test/rustdoc-ui/issue-81662-shortness.stdout new file mode 100644 index 000000000..748113be3 --- /dev/null +++ b/src/test/rustdoc-ui/issue-81662-shortness.stdout @@ -0,0 +1,16 @@ + +running 1 test +test $DIR/issue-81662-shortness.rs - foo (line 6) ... FAILED + +failures: + +---- $DIR/issue-81662-shortness.rs - foo (line 6) stdout ---- +$DIR/issue-81662-shortness.rs:7:1: error[E0425]: cannot find function `foo` in this scope +error: aborting due to previous error +Couldn't compile the test. + +failures: + $DIR/issue-81662-shortness.rs - foo (line 6) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/issue-83883-describe-lints.rs b/src/test/rustdoc-ui/issue-83883-describe-lints.rs new file mode 100644 index 000000000..0474d6c14 --- /dev/null +++ b/src/test/rustdoc-ui/issue-83883-describe-lints.rs @@ -0,0 +1,10 @@ +// compile-flags: -W help +// check-pass +// check-stdout +// error-pattern:Lint checks provided +// error-pattern:rustdoc::broken-intra-doc-links +// +// ignore-tidy-linelength +// +// normalize-stdout-test: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" +// normalize-stdout-test: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" diff --git a/src/test/rustdoc-ui/issue-83883-describe-lints.stdout b/src/test/rustdoc-ui/issue-83883-describe-lints.stdout new file mode 100644 index 000000000..bbf66a315 --- /dev/null +++ b/src/test/rustdoc-ui/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 provided by plugins loaded by this crate: + + $NAMES $LEVELS $MEANINGS + +Lint groups provided by plugins loaded by this crate: + + $NAMES $SUB_LINTS + diff --git a/src/test/rustdoc-ui/issue-91134.rs b/src/test/rustdoc-ui/issue-91134.rs new file mode 100644 index 000000000..d2ff3a252 --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/issue-91134.stdout b/src/test/rustdoc-ui/issue-91134.stdout new file mode 100644 index 000000000..084062743 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-91713.rs b/src/test/rustdoc-ui/issue-91713.rs new file mode 100644 index 000000000..610bbf11d --- /dev/null +++ b/src/test/rustdoc-ui/issue-91713.rs @@ -0,0 +1,3 @@ +// check-pass +// compile-flags: --passes list +// error-pattern: the `passes` flag no longer functions diff --git a/src/test/rustdoc-ui/issue-91713.stderr b/src/test/rustdoc-ui/issue-91713.stderr new file mode 100644 index 000000000..44ead7a1d --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-91713.stdout b/src/test/rustdoc-ui/issue-91713.stdout new file mode 100644 index 000000000..a19e452b4 --- /dev/null +++ b/src/test/rustdoc-ui/issue-91713.stdout @@ -0,0 +1,29 @@ +Available passes for running rustdoc: +check_doc_test_visibility - run various visibility-related lints on doctests + 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 +collect-intra-doc-links - resolves intra-doc links +check-code-block-syntax - validates syntax inside Rust code blocks + collect-trait-impls - retrieves trait impls for items in the crate +calculate-doc-coverage - counts the number of items with and without documentation +check-invalid-html-tags - detects invalid HTML tags in doc comments + check-bare-urls - detects URLs that are not hyperlinks + +Default passes for rustdoc: + collect-trait-impls +check_doc_test_visibility + 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 +check-code-block-syntax +check-invalid-html-tags + propagate-doc-cfg + check-bare-urls + +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/src/test/rustdoc-ui/issue-98690.rs b/src/test/rustdoc-ui/issue-98690.rs new file mode 100644 index 000000000..fe9bd87ab --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/issue-98690.stderr b/src/test/rustdoc-ui/issue-98690.stderr new file mode 100644 index 000000000..47d94f99a --- /dev/null +++ b/src/test/rustdoc-ui/issue-98690.stderr @@ -0,0 +1 @@ +Couldn't create directory for doctest executables: Permission denied (os error 13) diff --git a/src/test/rustdoc-ui/lint-group.rs b/src/test/rustdoc-ui/lint-group.rs new file mode 100644 index 000000000..61555a6e6 --- /dev/null +++ b/src/test/rustdoc-ui/lint-group.rs @@ -0,0 +1,29 @@ +//! Documenting the kinds of lints emitted by rustdoc. +//! +//! ``` +//! println!("sup"); +//! ``` + +#![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/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr new file mode 100644 index 000000000..e28600160 --- /dev/null +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -0,0 +1,50 @@ +error: missing code example in this documentation + --> $DIR/lint-group.rs:16:1 + | +LL | /// wait, this doesn't have a doctest? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-group.rs:7:9 + | +LL | #![deny(rustdoc::all)] + | ^^^^^^^^^^^^ + = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]` + +error: documentation test in private item + --> $DIR/lint-group.rs:19:1 + | +LL | / /// wait, this *does* have a doctest? +LL | | /// +LL | | /// ``` +LL | | /// println!("sup"); +LL | | /// ``` + | |_______^ + | + = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]` + +error: missing code example in this documentation + --> $DIR/lint-group.rs:26:1 + | +LL | /// <unknown> + | ^^^^^^^^^^^^^ + +error: unresolved link to `error` + --> $DIR/lint-group.rs:9:29 + | +LL | /// what up, let's make an [error] + | ^^^^^ no item named `error` in scope + | + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]` + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: unclosed HTML tag `unknown` + --> $DIR/lint-group.rs:26:5 + | +LL | /// <unknown> + | ^^^^^^^^^ + | + = note: `#[deny(rustdoc::invalid_html_tags)]` implied by `#[deny(rustdoc::all)]` + +error: aborting due to 5 previous errors + diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs new file mode 100644 index 000000000..fac6342cd --- /dev/null +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs @@ -0,0 +1,100 @@ +#![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 { //~ ERROR +} + +#[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/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr new file mode 100644 index 000000000..9e51ecd2b --- /dev/null +++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr @@ -0,0 +1,38 @@ +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:19:1 + | +LL | pub mod module1 { + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/lint-missing-doc-code-example.rs:2:9 + | +LL | #![deny(rustdoc::missing_doc_code_examples)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:37:3 + | +LL | /// doc + | ^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:49:1 + | +LL | /// Doc + | ^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:56:1 + | +LL | /// Doc + | ^^^^^^^ + +error: missing code example in this documentation + --> $DIR/lint-missing-doc-code-example.rs:63:1 + | +LL | /// Doc + | ^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/rustdoc-ui/macro-docs.rs b/src/test/rustdoc-ui/macro-docs.rs new file mode 100644 index 000000000..0e8472eb2 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/macro-docs.stderr b/src/test/rustdoc-ui/macro-docs.stderr new file mode 100644 index 000000000..e3cc17311 --- /dev/null +++ b/src/test/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: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + = 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: 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/src/test/rustdoc-ui/macro-docs.stdout b/src/test/rustdoc-ui/macro-docs.stdout new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/test/rustdoc-ui/macro-docs.stdout diff --git a/src/test/rustdoc-ui/no-crate-level-doc-lint.rs b/src/test/rustdoc-ui/no-crate-level-doc-lint.rs new file mode 100644 index 000000000..a186410ac --- /dev/null +++ b/src/test/rustdoc-ui/no-crate-level-doc-lint.rs @@ -0,0 +1,6 @@ +// error-pattern: no documentation found +// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +#![deny(rustdoc::missing_crate_level_docs)] +//^~ NOTE defined here + +pub fn foo() {} diff --git a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr new file mode 100644 index 000000000..1a1f8085a --- /dev/null +++ b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr @@ -0,0 +1,12 @@ +error: no documentation found for this crate's top-level module + | +note: the lint level is defined here + --> $DIR/no-crate-level-doc-lint.rs:3:9 + | +LL | #![deny(rustdoc::missing_crate_level_docs)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: The following guide may be of use: + https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/no-run-flag-error.rs b/src/test/rustdoc-ui/no-run-flag-error.rs new file mode 100644 index 000000000..4ead62148 --- /dev/null +++ b/src/test/rustdoc-ui/no-run-flag-error.rs @@ -0,0 +1,6 @@ +// test the behavior of the --no-run flag without the --test flag + +// compile-flags:-Z unstable-options --no-run --test-args=--test-threads=1 +// error-pattern: the `--test` flag must be passed + +pub fn f() {} diff --git a/src/test/rustdoc-ui/no-run-flag-error.stderr b/src/test/rustdoc-ui/no-run-flag-error.stderr new file mode 100644 index 000000000..d032646c3 --- /dev/null +++ b/src/test/rustdoc-ui/no-run-flag-error.stderr @@ -0,0 +1,2 @@ +error: the `--test` flag must be passed to enable `--no-run` + diff --git a/src/test/rustdoc-ui/no-run-flag.rs b/src/test/rustdoc-ui/no-run-flag.rs new file mode 100644 index 000000000..da1672c4a --- /dev/null +++ b/src/test/rustdoc-ui/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-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/no-run-flag.stdout b/src/test/rustdoc-ui/no-run-flag.stdout new file mode 100644 index 000000000..02f28aaf6 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/nocapture-fail.rs b/src/test/rustdoc-ui/nocapture-fail.rs new file mode 100644 index 000000000..7706bd1f3 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture-fail.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags:--test -Zunstable-options --nocapture +// normalize-stderr-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ```compile_fail +/// fn foo() { +/// Input: 123 +/// } +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/nocapture-fail.stderr b/src/test/rustdoc-ui/nocapture-fail.stderr new file mode 100644 index 000000000..b65b622c1 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/nocapture-fail.stdout b/src/test/rustdoc-ui/nocapture-fail.stdout new file mode 100644 index 000000000..754f77db5 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/nocapture.rs b/src/test/rustdoc-ui/nocapture.rs new file mode 100644 index 000000000..321f5ca08 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture.rs @@ -0,0 +1,10 @@ +// check-pass +// compile-flags:--test -Zunstable-options --nocapture +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// println!("hello!"); +/// eprintln!("stderr"); +/// ``` +pub struct Foo; diff --git a/src/test/rustdoc-ui/nocapture.stderr b/src/test/rustdoc-ui/nocapture.stderr new file mode 100644 index 000000000..af6415db3 --- /dev/null +++ b/src/test/rustdoc-ui/nocapture.stderr @@ -0,0 +1 @@ +stderr diff --git a/src/test/rustdoc-ui/nocapture.stdout b/src/test/rustdoc-ui/nocapture.stdout new file mode 100644 index 000000000..4880e75da --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/normalize-cycle.rs b/src/test/rustdoc-ui/normalize-cycle.rs new file mode 100644 index 000000000..f48cad373 --- /dev/null +++ b/src/test/rustdoc-ui/normalize-cycle.rs @@ -0,0 +1,25 @@ +// check-pass +// Regresion 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/src/test/rustdoc-ui/normalize-overflow.rs b/src/test/rustdoc-ui/normalize-overflow.rs new file mode 100644 index 000000000..0cdcc88e3 --- /dev/null +++ b/src/test/rustdoc-ui/normalize-overflow.rs @@ -0,0 +1,3 @@ +// aux-crate:overflow=overflow.rs +// check-pass +// Regression test for <https://github.com/rust-lang/rust/issues/79506>. diff --git a/src/test/rustdoc-ui/output-format-html-stable.rs b/src/test/rustdoc-ui/output-format-html-stable.rs new file mode 100644 index 000000000..fa0362640 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/private-doc-test.rs b/src/test/rustdoc-ui/private-doc-test.rs new file mode 100644 index 000000000..a1f9f8dca --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/private-item-doc-test.rs b/src/test/rustdoc-ui/private-item-doc-test.rs new file mode 100644 index 000000000..1a3d6cc63 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/private-item-doc-test.stderr b/src/test/rustdoc-ui/private-item-doc-test.stderr new file mode 100644 index 000000000..5df613298 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/private-public-item-doc-test.rs b/src/test/rustdoc-ui/private-public-item-doc-test.rs new file mode 100644 index 000000000..7cc62b38c --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/private-public-item-doc-test.stderr b/src/test/rustdoc-ui/private-public-item-doc-test.stderr new file mode 100644 index 000000000..f50dbd184 --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/pub-export-lint.rs b/src/test/rustdoc-ui/pub-export-lint.rs new file mode 100644 index 000000000..f2e66b77b --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/pub-export-lint.stderr b/src/test/rustdoc-ui/pub-export-lint.stderr new file mode 100644 index 000000000..c6be9c6a9 --- /dev/null +++ b/src/test/rustdoc-ui/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 + | +note: the lint level is defined here + --> $DIR/pub-export-lint.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/public-reexported-item-doc-test.rs b/src/test/rustdoc-ui/public-reexported-item-doc-test.rs new file mode 100644 index 000000000..b86a53305 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/range-pattern.rs b/src/test/rustdoc-ui/range-pattern.rs new file mode 100644 index 000000000..fd255d02f --- /dev/null +++ b/src/test/rustdoc-ui/range-pattern.rs @@ -0,0 +1,3 @@ +// check-pass + +fn func(0u8..=255: u8) {} diff --git a/src/test/rustdoc-ui/recursive-deref-ice.rs b/src/test/rustdoc-ui/recursive-deref-ice.rs new file mode 100644 index 000000000..c44fd27f4 --- /dev/null +++ b/src/test/rustdoc-ui/recursive-deref-ice.rs @@ -0,0 +1,19 @@ +// check-pass + +// ICE found in https://github.com/rust-lang/rust/issues/83123 + +pub struct Attribute; + +pub struct Map<'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/src/test/rustdoc-ui/reference-link-reports-error-once.rs b/src/test/rustdoc-ui/reference-link-reports-error-once.rs new file mode 100644 index 000000000..71bd2c522 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/reference-link-reports-error-once.stderr b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr new file mode 100644 index 000000000..b46a51e93 --- /dev/null +++ b/src/test/rustdoc-ui/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 + | +note: the lint level is defined here + --> $DIR/reference-link-reports-error-once.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +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/src/test/rustdoc-ui/reference-links.rs b/src/test/rustdoc-ui/reference-links.rs new file mode 100644 index 000000000..e81e03446 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/reference-links.stderr b/src/test/rustdoc-ui/reference-links.stderr new file mode 100644 index 000000000..c98a2fd7c --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.rs b/src/test/rustdoc-ui/renamed-lint-still-applies.rs new file mode 100644 index 000000000..a4d3a4b49 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/renamed-lint-still-applies.stderr b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr new file mode 100644 index 000000000..8e2a2cdd7 --- /dev/null +++ b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr @@ -0,0 +1,42 @@ +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 + | +note: the lint level is defined here + --> $DIR/renamed-lint-still-applies.rs:2:9 + | +LL | #![deny(broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +error: this URL is not a hyperlink + --> $DIR/renamed-lint-still-applies.rs:9:5 + | +LL | //! http://example.com + | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.com>` + | +note: the lint level is defined here + --> $DIR/renamed-lint-still-applies.rs:7:9 + | +LL | #![deny(rustdoc::non_autolinks)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: bare URLs are not automatically turned into clickable links + +error: aborting due to 2 previous errors; 2 warnings emitted + diff --git a/src/test/rustdoc-ui/run-directory.correct.stdout b/src/test/rustdoc-ui/run-directory.correct.stdout new file mode 100644 index 000000000..e9b275479 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/run-directory.incorrect.stdout b/src/test/rustdoc-ui/run-directory.incorrect.stdout new file mode 100644 index 000000000..97a5dbc5c --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/run-directory.rs b/src/test/rustdoc-ui/run-directory.rs new file mode 100644 index 000000000..0d432c1e6 --- /dev/null +++ b/src/test/rustdoc-ui/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}} -Zunstable-options +// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage -Zunstable-options +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// assert_eq!( +/// std::fs::read_to_string("run-directory.rs").unwrap(), +/// include_str!("run-directory.rs"), +/// ); +/// ``` +#[cfg(correct)] +pub fn foo() {} + +/// ``` +/// assert!(std::fs::read_to_string("run-directory.rs").is_err()); +/// ``` +#[cfg(incorrect)] +pub fn foo() {} diff --git a/src/test/rustdoc-ui/rustc-check-passes.rs b/src/test/rustdoc-ui/rustc-check-passes.rs new file mode 100644 index 000000000..731cc8ba6 --- /dev/null +++ b/src/test/rustdoc-ui/rustc-check-passes.rs @@ -0,0 +1,4 @@ +#![feature(box_syntax)] +#![feature(box_syntax)] //~ ERROR + +pub fn foo() {} diff --git a/src/test/rustdoc-ui/rustc-check-passes.stderr b/src/test/rustdoc-ui/rustc-check-passes.stderr new file mode 100644 index 000000000..9707895ff --- /dev/null +++ b/src/test/rustdoc-ui/rustc-check-passes.stderr @@ -0,0 +1,9 @@ +error[E0636]: the feature `box_syntax` has already been declared + --> $DIR/rustc-check-passes.rs:2:12 + | +LL | #![feature(box_syntax)] + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0636`. diff --git a/src/test/rustdoc-ui/scrape-examples-fail-if-type-error.rs b/src/test/rustdoc-ui/scrape-examples-fail-if-type-error.rs new file mode 100644 index 000000000..8f4fde96d --- /dev/null +++ b/src/test/rustdoc-ui/scrape-examples-fail-if-type-error.rs @@ -0,0 +1,7 @@ +// 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 +} diff --git a/src/test/rustdoc-ui/scrape-examples-fail-if-type-error.stderr b/src/test/rustdoc-ui/scrape-examples-fail-if-type-error.stderr new file mode 100644 index 000000000..750aa3207 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/scrape-examples-ice.rs b/src/test/rustdoc-ui/scrape-examples-ice.rs new file mode 100644 index 000000000..d629b62a7 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/scrape-examples-wrong-options-1.rs b/src/test/rustdoc-ui/scrape-examples-wrong-options-1.rs new file mode 100644 index 000000000..a1f005c32 --- /dev/null +++ b/src/test/rustdoc-ui/scrape-examples-wrong-options-1.rs @@ -0,0 +1 @@ +// compile-flags: -Z unstable-options --scrape-examples-target-crate foobar diff --git a/src/test/rustdoc-ui/scrape-examples-wrong-options-1.stderr b/src/test/rustdoc-ui/scrape-examples-wrong-options-1.stderr new file mode 100644 index 000000000..eb8e9f799 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/scrape-examples-wrong-options-2.rs b/src/test/rustdoc-ui/scrape-examples-wrong-options-2.rs new file mode 100644 index 000000000..4aacec7f0 --- /dev/null +++ b/src/test/rustdoc-ui/scrape-examples-wrong-options-2.rs @@ -0,0 +1 @@ +// compile-flags: -Z unstable-options --scrape-examples-output-path ex.calls diff --git a/src/test/rustdoc-ui/scrape-examples-wrong-options-2.stderr b/src/test/rustdoc-ui/scrape-examples-wrong-options-2.stderr new file mode 100644 index 000000000..eb8e9f799 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/search-index-generics-recursion-bug-issue-59502.rs b/src/test/rustdoc-ui/search-index-generics-recursion-bug-issue-59502.rs new file mode 100644 index 000000000..ce51556dd --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs new file mode 100644 index 000000000..744b3071f --- /dev/null +++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs @@ -0,0 +1,38 @@ +#![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 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/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr new file mode 100644 index 000000000..832b8b2ca --- /dev/null +++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr @@ -0,0 +1,38 @@ +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:11:13 + | +LL | /// This Vec<i32 class="test"> thing! + | ^^^^ + | +note: the lint level is defined here + --> $DIR/html-as-generics-no-suggestions.rs:1:9 + | +LL | #![deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unopened HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:20:13 + | +LL | /// This Vec</i32> thing! + | ^^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:25:13 + | +LL | /// This 123<i32> thing! + | ^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:30:14 + | +LL | /// This Vec:<i32> thing! + | ^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:35:39 + | +LL | /// This [link](https://rust-lang.org)<i32> thing! + | ^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed new file mode 100644 index 000000000..c0a0de24c --- /dev/null +++ b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed @@ -0,0 +1,32 @@ +// 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; diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.rs b/src/test/rustdoc-ui/suggestions/html-as-generics.rs new file mode 100644 index 000000000..0b6009b0e --- /dev/null +++ b/src/test/rustdoc-ui/suggestions/html-as-generics.rs @@ -0,0 +1,32 @@ +// 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; diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr new file mode 100644 index 000000000..df54b7126 --- /dev/null +++ b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr @@ -0,0 +1,73 @@ +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: aborting due to 6 previous errors + diff --git a/src/test/rustdoc-ui/test-compile-fail1.rs b/src/test/rustdoc-ui/test-compile-fail1.rs new file mode 100644 index 000000000..a05390238 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail1.rs @@ -0,0 +1,8 @@ +// compile-flags:--test + +/// ``` +/// assert!(true) +/// ``` +pub fn f() {} + +pub fn f() {} diff --git a/src/test/rustdoc-ui/test-compile-fail1.stderr b/src/test/rustdoc-ui/test-compile-fail1.stderr new file mode 100644 index 000000000..72915e46b --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/rustdoc-ui/test-compile-fail2.rs b/src/test/rustdoc-ui/test-compile-fail2.rs new file mode 100644 index 000000000..651ded0a0 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail2.rs @@ -0,0 +1,3 @@ +// compile-flags:--test + +fail diff --git a/src/test/rustdoc-ui/test-compile-fail2.stderr b/src/test/rustdoc-ui/test-compile-fail2.stderr new file mode 100644 index 000000000..cee5b63cf --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + diff --git a/src/test/rustdoc-ui/test-compile-fail3.rs b/src/test/rustdoc-ui/test-compile-fail3.rs new file mode 100644 index 000000000..faa30ad83 --- /dev/null +++ b/src/test/rustdoc-ui/test-compile-fail3.rs @@ -0,0 +1,3 @@ +// compile-flags:--test + +"fail diff --git a/src/test/rustdoc-ui/test-compile-fail3.stderr b/src/test/rustdoc-ui/test-compile-fail3.stderr new file mode 100644 index 000000000..fab801b3b --- /dev/null +++ b/src/test/rustdoc-ui/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 previous error + +For more information about this error, try `rustc --explain E0765`. diff --git a/src/test/rustdoc-ui/test-no_std.rs b/src/test/rustdoc-ui/test-no_std.rs new file mode 100644 index 000000000..ee919985e --- /dev/null +++ b/src/test/rustdoc-ui/test-no_std.rs @@ -0,0 +1,13 @@ +// compile-flags:--test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +// check-pass + +#![no_std] + +extern crate alloc; + +/// ``` +/// assert!(true) +/// ``` +pub fn f() {} diff --git a/src/test/rustdoc-ui/test-no_std.stdout b/src/test/rustdoc-ui/test-no_std.stdout new file mode 100644 index 000000000..8d5a30804 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/test-type.rs b/src/test/rustdoc-ui/test-type.rs new file mode 100644 index 000000000..882da5c25 --- /dev/null +++ b/src/test/rustdoc-ui/test-type.rs @@ -0,0 +1,26 @@ +// compile-flags: --test --test-args=--test-threads=1 +// check-pass +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/test-type.stdout b/src/test/rustdoc-ui/test-type.stdout new file mode 100644 index 000000000..a66fd240d --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/tuple-variadic-check.rs b/src/test/rustdoc-ui/tuple-variadic-check.rs new file mode 100644 index 000000000..505de5348 --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/tuple-variadic-check.stderr b/src/test/rustdoc-ui/tuple-variadic-check.stderr new file mode 100644 index 000000000..d127fb858 --- /dev/null +++ b/src/test/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 previous error + diff --git a/src/test/rustdoc-ui/unknown-renamed-lints.rs b/src/test/rustdoc-ui/unknown-renamed-lints.rs new file mode 100644 index 000000000..ddf03dd07 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/unknown-renamed-lints.stderr b/src/test/rustdoc-ui/unknown-renamed-lints.stderr new file mode 100644 index 000000000..b105f47d7 --- /dev/null +++ b/src/test/rustdoc-ui/unknown-renamed-lints.stderr @@ -0,0 +1,64 @@ +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: Compilation failed, aborting rustdoc + +error: aborting due to 9 previous errors + diff --git a/src/test/rustdoc-ui/unparseable-doc-test.rs b/src/test/rustdoc-ui/unparseable-doc-test.rs new file mode 100644 index 000000000..0cff8cd9a --- /dev/null +++ b/src/test/rustdoc-ui/unparseable-doc-test.rs @@ -0,0 +1,11 @@ +// compile-flags: --test +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "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/src/test/rustdoc-ui/unparseable-doc-test.stdout b/src/test/rustdoc-ui/unparseable-doc-test.stdout new file mode 100644 index 000000000..2641c66f2 --- /dev/null +++ b/src/test/rustdoc-ui/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 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/src/test/rustdoc-ui/unused-braces-lint.rs b/src/test/rustdoc-ui/unused-braces-lint.rs new file mode 100644 index 000000000..be0e31e4b --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/unused-extern-crate.rs b/src/test/rustdoc-ui/unused-extern-crate.rs new file mode 100644 index 000000000..f703a1837 --- /dev/null +++ b/src/test/rustdoc-ui/unused-extern-crate.rs @@ -0,0 +1,3 @@ +// check-pass +// aux-crate:panic_item=panic-item.rs +// @has unused_extern_crate/index.html diff --git a/src/test/rustdoc-ui/unused.rs b/src/test/rustdoc-ui/unused.rs new file mode 100644 index 000000000..702b24c36 --- /dev/null +++ b/src/test/rustdoc-ui/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/src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs new file mode 100644 index 000000000..5037043f1 --- /dev/null +++ b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.rs @@ -0,0 +1 @@ +// compile-flags: --output ./foo diff --git a/src/test/rustdoc-ui/use_both_out_dir_and_output_options.stderr b/src/test/rustdoc-ui/use_both_out_dir_and_output_options.stderr new file mode 100644 index 000000000..96d2295ac --- /dev/null +++ b/src/test/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/src/test/rustdoc-ui/wasm-safe.rs b/src/test/rustdoc-ui/wasm-safe.rs new file mode 100644 index 000000000..ba971342b --- /dev/null +++ b/src/test/rustdoc-ui/wasm-safe.rs @@ -0,0 +1,5 @@ +// check-pass + +#[cfg(any(target_arch = "wasm32", doc))] +#[target_feature(enable = "simd128")] +pub fn foo() {} diff --git a/src/test/rustdoc-ui/z-help.rs b/src/test/rustdoc-ui/z-help.rs new file mode 100644 index 000000000..c7cf841b9 --- /dev/null +++ b/src/test/rustdoc-ui/z-help.rs @@ -0,0 +1,6 @@ +// check-pass +// compile-flags: -Zhelp +// check-stdout +// regex-error-pattern: -Z\s+self-profile + +pub struct Foo; diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout new file mode 100644 index 000000000..6dc412315 --- /dev/null +++ b/src/test/rustdoc-ui/z-help.stdout @@ -0,0 +1,200 @@ + -Z allow-features=val -- only allow the listed language features to be enabled in code (space separated) + -Z always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no) + -Z assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no) + -Z asm-comments=val -- generate comments into the assembly (may change behavior) (default: no) + -Z assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`. + -Z binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no) + -Z box-noalias=val -- emit noalias metadata for box (default: yes) + -Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64 + -Z cf-protection=val -- instrument control-flow architecture protection + -Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use + -Z chalk=val -- enable the experimental Chalk-based trait solving engine + -Z codegen-backend=val -- the backend to use + -Z combine-cgu=val -- combine CGUs into a single one + -Z crate-attr=val -- inject the given attribute in the crate + -Z debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO + -Z debug-macros=val -- emit line numbers debug info inside macros (default: no) + -Z deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes) + -Z dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no) + -Z dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no) + -Z dlltool=val -- import library generation tool (windows-gnu only) + -Z dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no) + -Z drop-tracking=val -- enables drop tracking in generators (default: no) + -Z dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no) + -Z dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no) + -Z dump-drop-tracking-cfg=val -- dump drop-tracking control-flow graph as a `.dot` file (default: no) + -Z dump-mir=val -- dump MIR state to file. + `val` is used to select which passes and functions to dump. For example: + `all` matches all passes and functions, + `foo` matches all passes for functions whose name contains 'foo', + `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo', + `foo | bar` all passes for function names containing 'foo' or 'bar'. + -Z dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no) + -Z dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`) + -Z dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no) + -Z dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no) + -Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans. + -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) + -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) + -Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes) + -Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries + -Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no) + -Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no) + -Z fuel=val -- set the optimization fuel quota for a crate + -Z function-sections=val -- whether each function should go in its own section + -Z future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no) + -Z gcc-ld=val -- implementation of ld used by cc + -Z graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no) + -Z graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`) + -Z hir-stats=val -- print some statistics about AST and HIR (default: no) + -Z human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no) + -Z identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no) + -Z incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no) + -Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no) + -Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no) + -Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no) + -Z inline-mir=val -- enable MIR inlining (default: no) + -Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50) + -Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100) + -Z inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs + -Z input-stats=val -- gather statistics about the input (default: no) + -Z instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are: + `=all` (implicit value) + `=except-unused-generics` + `=except-unused-functions` + `=off` (default) + -Z instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no) + -Z keep-hygiene-data=val -- keep hygiene data after analysis (default: no) + -Z link-native-libraries=val -- link native libraries in the linker invocation (default: yes) + -Z link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no) + -Z llvm-plugins=val -- a list LLVM plugins to enable (space separated) + -Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no) + -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) + -Z ls=val -- list the symbols defined by a library crate (default: no) + -Z macro-backtrace=val -- show macro backtraces (default: no) + -Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name + -Z meta-stats=val -- gather metadata statistics (default: no) + -Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no) + -Z mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual. + -Z mir-pretty-relative-line-numbers=val -- use line numbers relative to the function in mir pretty printing + -Z mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds) + -Z move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted + -Z mutable-noalias=val -- emit noalias metadata for mutable references (default: yes) + -Z new-llvm-pass-manager=val -- use new LLVM pass manager (default: no) + -Z nll-facts=val -- dump facts from NLL analysis into side files (default: no) + -Z nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`) + -Z no-analysis=val -- parse and expand the source, but run no analysis + -Z no-codegen=val -- run all passes except codegen; no output + -Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups + -Z no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints + -Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests + -Z no-link=val -- compile without linking + -Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO) + -Z no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used + -Z no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate + -Z normalize-docs=val -- normalize associated items in rustdoc when generating documentation + -Z oom=val -- panic strategy for out-of-memory handling + -Z osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no) + -Z diagnostic-width=val -- set the current output width for diagnostic truncation + -Z panic-abort-tests=val -- support compiling tests with panic=abort (default: no) + -Z panic-in-drop=val -- panic strategy for panics in drops + -Z parse-only=val -- parse only; do not compile, assemble, or link (default: no) + -Z perf-stats=val -- print some performance-related statistics (default: no) + -Z pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes) + -Z plt=val -- whether to use the PLT when calling into shared libraries; + only has effect for PIC code on systems with ELF binaries + (default: PLT is disabled if full relro is enabled) + -Z polonius=val -- enable polonius-based borrow-checker (default: no) + -Z polymorphize=val -- perform polymorphization analysis + -Z pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times) + -Z pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated) + -Z precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551. + -Z print-fuel=val -- make rustc print the total optimization fuel used by a crate + -Z print-llvm-passes=val -- print the LLVM optimization passes being run (default: no) + -Z print-mono-items=val -- print the result of the monomorphization collection pass + -Z print-type-sizes=val -- print layout information for each type encountered (default: no) + -Z proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no) + -Z proc-macro-execution-strategy=val -- how to run proc-macro code (default: same-thread) + -Z profile=val -- insert profiling code (default: no) + -Z profile-closures=val -- profile size of closures + -Z profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path) + -Z profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`) + -Z profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO) + -Z query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no) + -Z randomize-layout=val -- randomize the layout of types (default: no) + -Z layout-seed=val -- seed layout randomization + -Z relax-elf-relocations=val -- whether ELF relocations can be relaxed + -Z relro-level=val -- choose which RELRO level to use + -Z remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix + -Z simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes + -Z report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no) + -Z sanitizer=val -- use a sanitizer + -Z sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer + -Z sanitizer-recover=val -- enable recovery for selected sanitizers + -Z saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes) + -Z save-analysis=val -- write syntax and type analysis (in JSON format) information, in addition to normal output (default: no) + -Z self-profile=val -- run the self profiler and output the raw event data + -Z self-profile-events=val -- specify the events recorded by the self profiler; + for example: `-Z self-profile-events=default,query-keys` + all options: none, all, default, generic-activity, query-provider, query-cache-hit + query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes + -Z self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of: + `wall-time` (monotonic clock, i.e. `std::time::Instant`) + `instructions:u` (retired instructions, userspace-only) + `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy) + -Z share-generics=val -- make the current crate share its generic instantiations + -Z show-span=val -- show spans for compiler debugging (expr|pat|ty) + -Z span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span` + -Z span-free-formats=val -- exclude spans when debug-printing compiler state (default: no) + -Z src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`) + -Z stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details) + -Z strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB + -Z strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`) + -Z split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform) + (default: `split`) + + `split`: sections which do not require relocation are written into a DWARF object (`.dwo`) + file which is ignored by the linker + `single`: sections which do not require relocation are written into object file but ignored + by the linker + -Z split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF + -Z symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') + -Z teach=val -- show extended diagnostic help (default: no) + -Z temps-dir=val -- the directory the intermediate files are written to + -Z translate-lang=val -- language identifier for diagnostic output + -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) + -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics + -Z tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details) + -Z thinlto=val -- enable ThinLTO when possible + -Z thir-unsafeck=val -- use the THIR unsafety checker (default: no) + -Z threads=val -- use a thread pool with N threads + -Z time=val -- measure time of rustc processes (default: no) + -Z time-llvm-passes=val -- measure time of each LLVM pass (default: no) + -Z time-passes=val -- measure time of each rustc pass (default: no) + -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) + -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) + -Z translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes) + -Z trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes) + -Z treat-err-as-bug=val -- treat error number `val` that occurs as bug + -Z trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items + -Z ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no) + -Z uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16) + -Z unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no) + -Z unpretty=val -- present the input source, unstable (and less-pretty) variants; + `normal`, `identified`, + `expanded`, `expanded,identified`, + `expanded,hygiene` (with internal representations), + `ast-tree` (raw AST before expansion), + `ast-tree,expanded` (raw AST after expansion), + `hir` (the HIR), `hir,identified`, + `hir,typed` (HIR with types for each node), + `hir-tree` (dump the raw HIR), + `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR) + -Z unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no) + -Z unstable-options=val -- adds unstable command line options to rustc interface (default: no) + -Z use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array + -Z validate-mir=val -- validate MIR after each transformation + -Z verbose=val -- in general, enable more debug printouts (default: no) + -Z verify-llvm-ir=val -- verify LLVM IR (default: no) + -Z virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]` + -Z wasi-exec-model=val -- whether to build a wasi command or reactor |