Rollup merge of #147292 - Urgau:rustdoc-test-unstable_opts, r=fmease

Respect `-Z` unstable options in `rustdoc --test`

This PR makes rustdoc respect `-Z` unstable options when collecting doctests (`rustdoc --test`).

In the process I also realized that `--error-format` wasn't respected as well, making UI annotations impossible to write so I fixed that as well.

Best reviewed commit by commit.

Fixes https://github.com/rust-lang/rust/issues/147276
Fixes https://github.com/rust-lang/rust/issues/143930
r? fmease
This commit is contained in:
Matthias Krüger 2025-10-03 21:10:33 +02:00 committed by GitHub
commit dbc5e72ea2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 213 additions and 134 deletions

View file

@ -173,6 +173,8 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
target_triple: options.target.clone(),
crate_name: options.crate_name.clone(),
remap_path_prefix: options.remap_path_prefix.clone(),
unstable_opts: options.unstable_opts.clone(),
error_format: options.error_format.clone(),
..config::Options::default()
};

View file

@ -2,6 +2,9 @@
#![deny(rustdoc::invalid_codeblock_attributes)]
//~vvv ERROR unknown attribute `compile-fail`
//~| ERROR unknown attribute `compilefail`
//~| ERROR unknown attribute `comPile_fail`
/// foo
///
/// ```compile-fail,compilefail,comPile_fail
@ -9,6 +12,9 @@
/// ```
pub fn foo() {}
//~vvv ERROR unknown attribute `should-panic`
//~| ERROR unknown attribute `shouldpanic`
//~| ERROR unknown attribute `shOuld_panic`
/// bar
///
/// ```should-panic,shouldpanic,shOuld_panic
@ -16,6 +22,9 @@ pub fn foo() {}
/// ```
pub fn bar() {}
//~vvv ERROR unknown attribute `no-run`
//~| ERROR unknown attribute `norun`
//~| ERROR unknown attribute `nO_run`
/// foobar
///
/// ```no-run,norun,nO_run
@ -23,6 +32,9 @@ pub fn bar() {}
/// ```
pub fn foobar() {}
//~vvv ERROR unknown attribute `test-harness`
//~| ERROR unknown attribute `testharness`
//~| ERROR unknown attribute `tesT_harness`
/// b
///
/// ```test-harness,testharness,tesT_harness

View file

@ -1,159 +1,159 @@
error: unknown attribute `compile-fail`
--> $DIR/check-attr-test.rs:5:1
|
5 | / /// foo
6 | | ///
7 | | /// ```compile-fail,compilefail,comPile_fail
8 | | /// boo
9 | | /// ```
| |_______^
|
= help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
--> $DIR/check-attr-test.rs:8:1
|
LL | / /// foo
LL | | ///
LL | | /// ```compile-fail,compilefail,comPile_fail
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
note: the lint level is defined here
--> $DIR/check-attr-test.rs:3:9
|
3 | #![deny(rustdoc::invalid_codeblock_attributes)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--> $DIR/check-attr-test.rs:3:9
|
LL | #![deny(rustdoc::invalid_codeblock_attributes)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unknown attribute `compilefail`
--> $DIR/check-attr-test.rs:5:1
|
5 | / /// foo
6 | | ///
7 | | /// ```compile-fail,compilefail,comPile_fail
8 | | /// boo
9 | | /// ```
| |_______^
|
= help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
--> $DIR/check-attr-test.rs:8:1
|
LL | / /// foo
LL | | ///
LL | | /// ```compile-fail,compilefail,comPile_fail
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `comPile_fail`
--> $DIR/check-attr-test.rs:5:1
|
5 | / /// foo
6 | | ///
7 | | /// ```compile-fail,compilefail,comPile_fail
8 | | /// boo
9 | | /// ```
| |_______^
|
= help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
--> $DIR/check-attr-test.rs:8:1
|
LL | / /// foo
LL | | ///
LL | | /// ```compile-fail,compilefail,comPile_fail
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `should-panic`
--> $DIR/check-attr-test.rs:12:1
--> $DIR/check-attr-test.rs:18:1
|
12 | / /// bar
13 | | ///
14 | | /// ```should-panic,shouldpanic,shOuld_panic
15 | | /// boo
16 | | /// ```
LL | / /// bar
LL | | ///
LL | | /// ```should-panic,shouldpanic,shOuld_panic
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `shouldpanic`
--> $DIR/check-attr-test.rs:12:1
--> $DIR/check-attr-test.rs:18:1
|
12 | / /// bar
13 | | ///
14 | | /// ```should-panic,shouldpanic,shOuld_panic
15 | | /// boo
16 | | /// ```
LL | / /// bar
LL | | ///
LL | | /// ```should-panic,shouldpanic,shOuld_panic
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `shOuld_panic`
--> $DIR/check-attr-test.rs:12:1
--> $DIR/check-attr-test.rs:18:1
|
12 | / /// bar
13 | | ///
14 | | /// ```should-panic,shouldpanic,shOuld_panic
15 | | /// boo
16 | | /// ```
LL | / /// bar
LL | | ///
LL | | /// ```should-panic,shouldpanic,shOuld_panic
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `no-run`
--> $DIR/check-attr-test.rs:19:1
--> $DIR/check-attr-test.rs:28:1
|
19 | / /// foobar
20 | | ///
21 | | /// ```no-run,norun,nO_run
22 | | /// boo
23 | | /// ```
LL | / /// foobar
LL | | ///
LL | | /// ```no-run,norun,nO_run
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `no_run` to compile, but not run, the code sample during testing
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `norun`
--> $DIR/check-attr-test.rs:19:1
--> $DIR/check-attr-test.rs:28:1
|
19 | / /// foobar
20 | | ///
21 | | /// ```no-run,norun,nO_run
22 | | /// boo
23 | | /// ```
LL | / /// foobar
LL | | ///
LL | | /// ```no-run,norun,nO_run
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `no_run` to compile, but not run, the code sample during testing
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `nO_run`
--> $DIR/check-attr-test.rs:19:1
--> $DIR/check-attr-test.rs:28:1
|
19 | / /// foobar
20 | | ///
21 | | /// ```no-run,norun,nO_run
22 | | /// boo
23 | | /// ```
LL | / /// foobar
LL | | ///
LL | | /// ```no-run,norun,nO_run
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `no_run` to compile, but not run, the code sample during testing
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `test-harness`
--> $DIR/check-attr-test.rs:26:1
--> $DIR/check-attr-test.rs:38:1
|
26 | / /// b
27 | | ///
28 | | /// ```test-harness,testharness,tesT_harness
29 | | /// boo
30 | | /// ```
LL | / /// b
LL | | ///
LL | | /// ```test-harness,testharness,tesT_harness
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `testharness`
--> $DIR/check-attr-test.rs:26:1
--> $DIR/check-attr-test.rs:38:1
|
26 | / /// b
27 | | ///
28 | | /// ```test-harness,testharness,tesT_harness
29 | | /// boo
30 | | /// ```
LL | / /// b
LL | | ///
LL | | /// ```test-harness,testharness,tesT_harness
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function
= help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust`
error: unknown attribute `tesT_harness`
--> $DIR/check-attr-test.rs:26:1
--> $DIR/check-attr-test.rs:38:1
|
26 | / /// b
27 | | ///
28 | | /// ```test-harness,testharness,tesT_harness
29 | | /// boo
30 | | /// ```
LL | / /// b
LL | | ///
LL | | /// ```test-harness,testharness,tesT_harness
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function

View file

@ -9,6 +9,7 @@
/// <https://github.com/rust-lang/rust/issues/91014>
///
/// ```rust
//~^ WARN the `main` function of this doctest won't be run
/// struct S {};
///
/// fn main() {

View file

@ -1,7 +1,7 @@
warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function
--> $DIR/failed-doctest-extra-semicolon-on-item.rs:11:1
|
11 | /// ```rust
LL | /// ```rust
| ^^^^^^^^^^^
warning: 1 warning emitted

View file

@ -14,6 +14,7 @@
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
//@ check-pass
//~v WARN the `main` function of this doctest won't be run
//! ```
//! # if cfg!(miri) { return; }
//! use std::ops::Deref;
@ -22,6 +23,7 @@
//! assert!(false);
//! }
//! ```
//~v WARN the `main` function of this doctest won't be run
//!
//! ```
//! let x = 2;

View file

@ -1,14 +1,14 @@
warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function
--> $DIR/main-alongside-stmts.rs:17:1
--> $DIR/main-alongside-stmts.rs:18:1
|
17 | //! ```
LL | //! ```
| ^^^^^^^
warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function
--> $DIR/main-alongside-stmts.rs:26:1
--> $DIR/main-alongside-stmts.rs:27:1
|
26 | //! ```
| ^^^^^^^
LL | //!
| ^^^
warning: 2 warnings emitted

View file

@ -1,7 +1,7 @@
running 2 tests
test $DIR/main-alongside-stmts.rs - (line 17) ... ok
test $DIR/main-alongside-stmts.rs - (line 26) ... ok
test $DIR/main-alongside-stmts.rs - (line 18) ... ok
test $DIR/main-alongside-stmts.rs - (line 27) ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

View file

@ -9,6 +9,8 @@
#![deny(warnings)]
//! ```standalone
//~^ ERROR unknown attribute `standalone`
//~| ERROR unknown attribute `standalone-crate`
//! bla
//! ```
//!

View file

@ -1,13 +1,13 @@
error: unknown attribute `standalone`
--> $DIR/standalone-warning-2024.rs:11:1
|
11 | / //! ```standalone
12 | | //! bla
13 | | //! ```
14 | | //!
15 | | //! ```standalone-crate
16 | | //! bla
17 | | //! ```
LL | / //! ```standalone
LL | |
LL | |
LL | | //! bla
... |
LL | | //! bla
LL | | //! ```
| |_______^
|
= help: use `standalone_crate` to compile this code block separately
@ -15,20 +15,20 @@ error: unknown attribute `standalone`
note: the lint level is defined here
--> $DIR/standalone-warning-2024.rs:9:9
|
9 | #![deny(warnings)]
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]`
error: unknown attribute `standalone-crate`
--> $DIR/standalone-warning-2024.rs:11:1
|
11 | / //! ```standalone
12 | | //! bla
13 | | //! ```
14 | | //!
15 | | //! ```standalone-crate
16 | | //! bla
17 | | //! ```
LL | / //! ```standalone
LL | |
LL | |
LL | | //! bla
... |
LL | | //! bla
LL | | //! ```
| |_______^
|
= help: use `standalone_crate` to compile this code block separately

View file

@ -6,3 +6,4 @@
pub fn f() {}
pub fn f() {}
//~^ ERROR the name `f` is defined multiple times

View file

@ -1,13 +1,13 @@
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
--> $DIR/test-compile-fail1.rs:8:1
|
LL | pub fn f() {}
| ---------- previous definition of the value `f` here
LL |
LL | pub fn f() {}
| ^^^^^^^^^^ `f` redefined here
|
= note: `f` must be defined only once in the value namespace of this module
error: aborting due to 1 previous error

View file

@ -1,3 +1,4 @@
//@ compile-flags:--test
fail
//~^ ERROR

View file

@ -1,8 +1,8 @@
error: expected one of `!` or `::`, found `<eof>`
--> $DIR/test-compile-fail2.rs:3:1
|
3 | fail
| ^^^^ expected one of `!` or `::`
--> $DIR/test-compile-fail2.rs:3:1
|
LL | fail
| ^^^^ expected one of `!` or `::`
error: aborting due to 1 previous error

View file

@ -1,3 +1,4 @@
//@ compile-flags:--test
"fail
//~^ ERROR

View file

@ -1,8 +1,9 @@
error[E0765]: unterminated double quote string
--> $DIR/test-compile-fail3.rs:3:1
|
3 | "fail
| ^^^^^
--> $DIR/test-compile-fail3.rs:3:1
|
LL | / "fail
LL | |
| |___________^
error: aborting due to 1 previous error

View file

@ -0,0 +1,14 @@
// This test verifies that unstable options like `-Zcrate-attr` are respected when `--test` is
// passed.
//
// <https://github.com/rust-lang/rust/issues/143930>
//
// NOTE: If any of these command line arguments or features get stabilized, please replace with
// another unstable one.
//@ check-pass
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
//@ compile-flags: --test -Zcrate-attr=feature(register_tool) -Zcrate-attr=register_tool(rapx)
#[rapx::tag]
fn f() {}

View file

@ -0,0 +1,5 @@
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

View file

@ -0,0 +1,5 @@
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

View file

@ -0,0 +1,13 @@
error[E0658]: `#[used(linker)]` is currently unstable
--> $DIR/unstable-opts-147276.rs:15:1
|
LL | #[used(linker)]
| ^^^^^^^^^^^^^^^
|
= note: see issue #93798 <https://github.com/rust-lang/rust/issues/93798> for more information
= help: add `#![feature(used_with_arg)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -0,0 +1,17 @@
// This test verifies that unstable options like `-Zcrate-attr` are respected when `--test` is
// passed.
//
// <https://github.com/rust-lang/rust/issues/147276>
//
// NOTE: If any of these command line arguments or features get stabilized, please replace with
// another unstable one.
//@ revisions: normal crate_attr
//@ compile-flags: --test
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
//@[crate_attr] check-pass
//@[crate_attr] compile-flags: -Zcrate-attr=feature(used_with_arg)
#[used(linker)]
//[normal]~^ ERROR `#[used(linker)]` is currently unstable
static REPRO: isize = 1;

View file

@ -8,6 +8,7 @@
// won't be called.
//! ```
//~^ WARN the `main` function of this doctest won't be run
//! macro_rules! bla {
//! ($($x:tt)*) => {}
//! }
@ -17,6 +18,7 @@
//! ```
//!
//! ```
//~^^ WARN the `main` function of this doctest won't be run
//! let x = 12;
//! fn main() {}
//! ```

View file

@ -1,14 +1,14 @@
warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function
--> $DIR/warn-main-not-called.rs:10:1
|
10 | //! ```
LL | //! ```
| ^^^^^^^
warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function
--> $DIR/warn-main-not-called.rs:19:1
|
19 | //! ```
| ^^^^^^^
LL | //!
| ^^^
warning: 2 warnings emitted