From 05731afff2e7fb21eab3bc3c0c62c3d61a6d1d0a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Aug 2024 14:44:21 +0200 Subject: [PATCH 1/8] Add `--doctest-compilation-args` option to allow passing arguments to doctest compilation --- src/librustdoc/config.rs | 5 +++++ src/librustdoc/doctest.rs | 11 +++++++++++ src/librustdoc/lib.rs | 10 +++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 34c91e33db700..af3c7cc7be345 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -172,6 +172,9 @@ pub(crate) struct Options { /// This is mainly useful for other tools that reads that debuginfo to figure out /// how to call the compiler with the same arguments. pub(crate) expanded_args: Vec, + + /// Arguments to be used when compiling doctests. + pub(crate) doctest_compilation_args: Vec, } impl fmt::Debug for Options { @@ -774,6 +777,7 @@ impl Options { let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx); let with_examples = matches.opt_strs("with-examples"); let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx); + let doctest_compilation_args = matches.opt_strs("doctest-compilation-args"); let unstable_features = rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); @@ -819,6 +823,7 @@ impl Options { scrape_examples_options, unstable_features, expanded_args: args, + doctest_compilation_args, }; let render_options = RenderOptions { output, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index ce44cb1c319aa..a53316dc6c15f 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -78,6 +78,17 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> content.push(format!("-Z{unstable_option_str}")); } + for compilation_args in &options.doctest_compilation_args { + for flag in compilation_args + .split_whitespace() + .map(|flag| flag.trim()) + .filter(|flag| !flag.is_empty()) + { + // Very simple parsing implementation. Might be a good idea to correctly handle strings. + content.push(flag.to_string()); + } + } + let content = content.join("\n"); file.write_all(content.as_bytes()) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 7655c2e0e15e1..ff1c9c61720fa 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -642,6 +642,15 @@ fn opts() -> Vec { "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize", "path/to/doc.parts/", ), + opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), + opt( + Unstable, + Multi, + "", + "doctest-compilation-args", + "", + "add arguments to be used when compiling doctests", + ), // deprecated / removed options opt(Unstable, FlagMulti, "", "disable-minification", "removed", ""), opt( @@ -684,7 +693,6 @@ fn opts() -> Vec { "removed, see issue #44136 for more information", "[rust]", ), - opt(Unstable, Flag, "", "html-no-source", "Disable HTML source code pages generation", ""), ] } From 2bd869082bdf4fb950febbf5a6f7b64a81dfe2d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Aug 2024 14:50:50 +0200 Subject: [PATCH 2/8] Add regression test for `--doctest-compilation-args` --- tests/rustdoc-ui/doctest/rustflags.rs | 12 ++++++++++++ tests/rustdoc-ui/doctest/rustflags.stdout | 6 ++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/rustdoc-ui/doctest/rustflags.rs create mode 100644 tests/rustdoc-ui/doctest/rustflags.stdout diff --git a/tests/rustdoc-ui/doctest/rustflags.rs b/tests/rustdoc-ui/doctest/rustflags.rs new file mode 100644 index 0000000000000..fa460e355472a --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #[cfg(testcase_must_be_present)] +/// fn must_be_present() {} +/// +/// fn main() { must_be_present() } +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/rustflags.stdout b/tests/rustdoc-ui/doctest/rustflags.stdout new file mode 100644 index 0000000000000..b9da6637745bc --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/rustflags.rs - Bar (line 6) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From d3c970a1986d960ee92d3a12ded89b3a8293d82f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Aug 2024 14:55:47 +0200 Subject: [PATCH 3/8] Add explanations about `--doctest-compilation-args` in rustdoc book --- src/doc/rustdoc/src/unstable-features.md | 94 +++++++++++++++++++----- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index f19c3a51f619b..f1aa8a53422dc 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -315,7 +315,7 @@ Markdown file, the URL given to `--markdown-playground-url` will take precedence `--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, the attribute will take precedence. -### `--sort-modules-by-appearance`: control how items on module pages are sorted +## `--sort-modules-by-appearance`: control how items on module pages are sorted Using this flag looks like this: @@ -328,7 +328,7 @@ some consideration for their stability, and names that end in a number). Giving `rustdoc` will disable this sorting and instead make it print the items in the order they appear in the source. -### `--show-type-layout`: add a section to each type's docs describing its memory layout +## `--show-type-layout`: add a section to each type's docs describing its memory layout * Tracking issue: [#113248](https://github.com/rust-lang/rust/issues/113248) @@ -346,7 +346,7 @@ of that type will take in memory. Note that most layout information is **completely unstable** and may even differ between compilations. -### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs +## `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs * Tracking issue: [#54765](https://github.com/rust-lang/rust/issues/54765) @@ -361,7 +361,7 @@ all these files are linked from every page, changing where they are can be cumbe specially cache them. This flag will rename all these files in the output to include the suffix in the filename. For example, `light.css` would become `light-suf.css` with the above command. -### `--extern-html-root-url`: control how rustdoc links to non-local crates +## `--extern-html-root-url`: control how rustdoc links to non-local crates Using this flag looks like this: @@ -376,7 +376,7 @@ flags to control that behavior. When the `--extern-html-root-url` flag is given one of your dependencies, rustdoc use that URL for those docs. Keep in mind that if those docs exist in the output directory, those local docs will still override this flag. -### `-Z force-unstable-if-unmarked` +## `-Z force-unstable-if-unmarked` Using this flag looks like this: @@ -389,7 +389,7 @@ This is an internal flag intended for the standard library and compiler that app allows `rustdoc` to be able to generate documentation for the compiler crates and the standard library, as an equivalent command-line argument is provided to `rustc` when building those crates. -### `--index-page`: provide a top-level landing page for docs +## `--index-page`: provide a top-level landing page for docs This feature allows you to generate an index-page with a given markdown file. A good example of it is the [rust documentation index](https://doc.rust-lang.org/nightly/index.html). @@ -398,18 +398,18 @@ With this, you'll have a page which you can customize as much as you want at the Using `index-page` option enables `enable-index-page` option as well. -### `--enable-index-page`: generate a default index page for docs +## `--enable-index-page`: generate a default index page for docs This feature allows the generation of a default index-page which lists the generated crates. -### `--nocapture`: disable output capture for test +## `--nocapture`: disable output capture for test When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be captured by rustdoc. Instead, the output will be directed to your terminal, as if you had run the test executable manually. This is especially useful for debugging your tests! -### `--check`: only checks the documentation +## `--check`: only checks the documentation When this flag is supplied, rustdoc will type check and lint your code, but will not generate any documentation or run your doctests. @@ -420,7 +420,7 @@ Using this flag looks like: rustdoc -Z unstable-options --check src/lib.rs ``` -### `--static-root-path`: control how static files are loaded in HTML output +## `--static-root-path`: control how static files are loaded in HTML output Using this flag looks like this: @@ -435,7 +435,7 @@ JavaScript, and font files in a single location, rather than duplicating it once files like the search index will still load from the documentation root, but anything that gets renamed with `--resource-suffix` will load from the given path. -### `--persist-doctests`: persist doctest executables after running +## `--persist-doctests`: persist doctest executables after running * Tracking issue: [#56925](https://github.com/rust-lang/rust/issues/56925) @@ -449,7 +449,7 @@ This flag allows you to keep doctest executables around after they're compiled o Usually, rustdoc will immediately discard a compiled doctest after it's been tested, but with this option, you can keep those binaries around for farther testing. -### `--show-coverage`: calculate the percentage of items with documentation +## `--show-coverage`: calculate the percentage of items with documentation * Tracking issue: [#58154](https://github.com/rust-lang/rust/issues/58154) @@ -500,7 +500,7 @@ Calculating code examples follows these rules: * typedef 2. If one of the previously listed items has a code example, then it'll be counted. -#### JSON output +### JSON output When using `--output-format json` with this option, it will display the coverage information in JSON format. For example, here is the JSON for a file with one documented item and one @@ -522,7 +522,7 @@ Note that the third item is the crate root, which in this case is undocumented. If you want the JSON output to be displayed on `stdout` instead of having a file generated, you can use `-o -`. -### `-w`/`--output-format`: output format +## `-w`/`--output-format`: output format `--output-format json` emits documentation in the experimental [JSON format](https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/). `--output-format html` has no effect, @@ -542,7 +542,7 @@ It can also be used with `--show-coverage`. Take a look at its [documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more information. -### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests +## `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) @@ -577,7 +577,7 @@ struct Foo; In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will override `ignore`. -### `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it +## `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it * Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245) @@ -596,7 +596,7 @@ $ rustdoc src/lib.rs -Z unstable-options --runtool valgrind Another use case would be to run a test inside an emulator, or through a Virtual Machine. -### `--with-examples`: include examples of uses of items as documentation +## `--with-examples`: include examples of uses of items as documentation * Tracking issue: [#88791](https://github.com/rust-lang/rust/issues/88791) @@ -625,7 +625,7 @@ crate being documented (`foobar`) and a path to output the calls To scrape examples from test code, e.g. functions marked `#[test]`, then add the `--scrape-tests` flag. -### `--generate-link-to-definition`: Generate links on types in source code +## `--generate-link-to-definition`: Generate links on types in source code * Tracking issue: [#89095](https://github.com/rust-lang/rust/issues/89095) @@ -664,3 +664,61 @@ Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper The first argument to the program will be the test builder program. This flag can be passed multiple times to nest wrappers. + +## Passing arguments to rustc when compiling doctests + +You can use the `--doctest-compilation-args` option if you want to add options when compiling the +doctest. For example if you have: + +```rust,no_run +/// ``` +/// #![deny(warnings)] +/// #![feature(async_await)] +/// +/// let x = 12; +/// ``` +pub struct Bar; +``` + +And you run `rustdoc --test` on it, you will get: + +```console +running 1 test +test foo.rs - Bar (line 1) ... FAILED + +failures: + +---- foo.rs - Bar (line 1) stdout ---- +error: the feature `async_await` has been stable since 1.39.0 and no longer requires an attribute to enable + --> foo.rs:2:12 + | +3 | #![feature(async_await)] + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> foo.rs:1:9 + | +2 | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(stable_features)]` implied by `#[deny(warnings)]` + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + foo.rs - Bar (line 1) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s +``` + +But if you can limit the lint level to warning by using `--doctest_compilation_args=--cap-lints=warn`: + +```console +$ rustdoc --test --doctest_compilation_args=--cap-lints=warn file.rs + +running 1 test +test tests/rustdoc-ui/doctest/rustflags.rs - Bar (line 5) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s +``` From 24fafe7d14303643de24cc31bb6d1acc0568bcb5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Aug 2024 17:52:21 +0200 Subject: [PATCH 4/8] Update `run-make/rustdoc-default-output` test --- tests/run-make/rustdoc-default-output/output-default.stdout | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 125443ce61964..c2d9309ba2e6d 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -189,6 +189,10 @@ Options: --include-parts-dir path/to/doc.parts/ Includes trait implementations and other crate info from provided path. Only use with --merge=finalize + --html-no-source + Disable HTML source code pages generation + --doctest-compilation-args add arguments to be used when compiling doctests + --disable-minification removed --plugin-path DIR @@ -209,8 +213,6 @@ Options: removed, see issue #44136 for more information - --html-no-source - Disable HTML source code pages generation @path Read newline separated options from `path` From cbb3df41fb48d0a5ebcdd0f4b44cc3ad6a5a837a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Aug 2024 16:19:52 +0200 Subject: [PATCH 5/8] Split arguments from `--doctest-compilation-args` like a shell would --- src/librustdoc/doctest.rs | 72 ++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a53316dc6c15f..a93e2f927182e 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -50,6 +50,46 @@ pub(crate) struct GlobalTestOptions { pub(crate) args_file: PathBuf, } +/// Function used to split command line arguments just like a shell would. +fn split_args(args: &str) -> Vec { + let mut out = Vec::new(); + let mut iter = args.chars(); + let mut current = String::new(); + + while let Some(c) = iter.next() { + if c == '\\' { + if let Some(c) = iter.next() { + // If it's escaped, even a quote or a whitespace will be ignored. + current.push(c); + } + } else if c == '"' || c == '\'' { + while let Some(new_c) = iter.next() { + if new_c == c { + break; + } else if new_c == '\\' { + if let Some(c) = iter.next() { + // If it's escaped, even a quote will be ignored. + current.push(c); + } + } else { + current.push(new_c); + } + } + } else if " \n\t\r".contains(c) { + if !current.is_empty() { + out.push(current.clone()); + current.clear(); + } + } else { + current.push(c); + } + } + if !current.is_empty() { + out.push(current); + } + out +} + pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Result<(), String> { let mut file = File::create(file_path) .map_err(|error| format!("failed to create args file: {error:?}"))?; @@ -79,14 +119,7 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> } for compilation_args in &options.doctest_compilation_args { - for flag in compilation_args - .split_whitespace() - .map(|flag| flag.trim()) - .filter(|flag| !flag.is_empty()) - { - // Very simple parsing implementation. Might be a good idea to correctly handle strings. - content.push(flag.to_string()); - } + content.extend(split_args(compilation_args)); } let content = content.join("\n"); @@ -1003,6 +1036,29 @@ fn doctest_run_fn( Ok(()) } +#[cfg(test)] +#[test] +fn check_split_args() { + fn compare(input: &str, expected: &[&str]) { + let output = split_args(input); + let expected = expected.iter().map(|s| s.to_string()).collect::>(); + assert_eq!(expected, output, "test failed for {input:?}"); + } + + compare("'a' \"b\"c", &["a", "bc"]); + compare("'a' \"b \"c d", &["a", "b c", "d"]); + compare("'a' \"b\\\"c\"", &["a", "b\"c"]); + compare("'a\"'", &["a\""]); + compare("\"a'\"", &["a'"]); + compare("\\ a", &[" a"]); + compare("\\\\", &["\\"]); + compare("a'", &["a"]); + compare("a ", &["a"]); + compare("a b", &["a", "b"]); + compare("a\n\t \rb", &["a", "b"]); + compare("a\n\t1 \rb", &["a", "1", "b"]); +} + #[cfg(test)] // used in tests impl DocTestVisitor for Vec { fn visit_test(&mut self, _test: String, _config: LangString, rel_line: MdRelLine) { From 55653a5178c07a0a854066e79062de4c585561a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Dec 2024 12:35:57 +0100 Subject: [PATCH 6/8] Add explanations on how arguments are split --- src/doc/rustdoc/src/unstable-features.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index f1aa8a53422dc..667f07cf95630 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -722,3 +722,22 @@ test tests/rustdoc-ui/doctest/rustflags.rs - Bar (line 5) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s ``` + +The parsing of arguments works as follows: if it encounters a `"` or a `'`, it will continue +until it finds the character unescaped (without a prepending `\`). If not inside a string, a +whitespace character will also split arguments. Example: + +```text +"hello 'a'\" ok" how are 'you today?' +``` + +will be split as follows: + +```text +[ + "hello 'a'\" ok", + "how", + "are", + "you today?", +] +``` From bc03e40a29574c18ebfc04bd179065815ebe83f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Dec 2024 15:14:08 +0100 Subject: [PATCH 7/8] Move test into the `tests.rs` file --- src/librustdoc/doctest.rs | 23 ----------------------- src/librustdoc/doctest/tests.rs | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a93e2f927182e..e6e5123d0bba0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1036,29 +1036,6 @@ fn doctest_run_fn( Ok(()) } -#[cfg(test)] -#[test] -fn check_split_args() { - fn compare(input: &str, expected: &[&str]) { - let output = split_args(input); - let expected = expected.iter().map(|s| s.to_string()).collect::>(); - assert_eq!(expected, output, "test failed for {input:?}"); - } - - compare("'a' \"b\"c", &["a", "bc"]); - compare("'a' \"b \"c d", &["a", "b c", "d"]); - compare("'a' \"b\\\"c\"", &["a", "b\"c"]); - compare("'a\"'", &["a\""]); - compare("\"a'\"", &["a'"]); - compare("\\ a", &[" a"]); - compare("\\\\", &["\\"]); - compare("a'", &["a"]); - compare("a ", &["a"]); - compare("a b", &["a", "b"]); - compare("a\n\t \rb", &["a", "b"]); - compare("a\n\t1 \rb", &["a", "1", "b"]); -} - #[cfg(test)] // used in tests impl DocTestVisitor for Vec { fn visit_test(&mut self, _test: String, _config: LangString, rel_line: MdRelLine) { diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 160d0f222b4e0..fa6cca3681be5 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -379,3 +379,25 @@ fn main() { let (output, len) = make_test(input, None, false, &opts, None); assert_eq!((output, len), (expected, 1)); } + +#[test] +fn check_split_args() { + fn compare(input: &str, expected: &[&str]) { + let output = super::split_args(input); + let expected = expected.iter().map(|s| s.to_string()).collect::>(); + assert_eq!(expected, output, "test failed for {input:?}"); + } + + compare("'a' \"b\"c", &["a", "bc"]); + compare("'a' \"b \"c d", &["a", "b c", "d"]); + compare("'a' \"b\\\"c\"", &["a", "b\"c"]); + compare("'a\"'", &["a\""]); + compare("\"a'\"", &["a'"]); + compare("\\ a", &[" a"]); + compare("\\\\", &["\\"]); + compare("a'", &["a"]); + compare("a ", &["a"]); + compare("a b", &["a", "b"]); + compare("a\n\t \rb", &["a", "b"]); + compare("a\n\t1 \rb", &["a", "1", "b"]); +} From 2d914bed2dea1316fdbb55010f3bb2c5412942cb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 20 Dec 2024 15:39:26 +0100 Subject: [PATCH 8/8] Add test to ensure passing `--doctest_compilation_args` multiple times work --- src/doc/rustdoc/src/unstable-features.md | 2 +- .../doctest/rustflags-multiple-args.rs | 17 +++++++++++++++++ .../doctest/rustflags-multiple-args.stdout | 6 ++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc-ui/doctest/rustflags-multiple-args.rs create mode 100644 tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 667f07cf95630..d1d42e4732258 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -667,7 +667,7 @@ This flag can be passed multiple times to nest wrappers. ## Passing arguments to rustc when compiling doctests -You can use the `--doctest-compilation-args` option if you want to add options when compiling the +You can use the `--doctest-compilation-args` flag if you want to add options when compiling the doctest. For example if you have: ```rust,no_run diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs new file mode 100644 index 0000000000000..8519920e53bef --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs @@ -0,0 +1,17 @@ +// This test checks that the test behave when `--doctest-compilation-args` is passed +// multiple times. + +//@ check-pass +//@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present +//@ compile-flags: --doctest-compilation-args=--cfg=another +//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// #[cfg(testcase_must_be_present)] +/// #[cfg(another)] +/// fn must_be_present() {} +/// +/// fn main() { must_be_present() } +/// ``` +pub struct Bar; diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout new file mode 100644 index 0000000000000..0e8a9e1efcf6f --- /dev/null +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/rustflags-multiple-args.rs - Bar (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +