about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-18 23:23:05 +0100
committerGitHub <noreply@github.com>2022-02-18 23:23:05 +0100
commite3a1e192960c41acc196b59f0cb1b28f78e712f8 (patch)
tree86a2d2d437d5a4939771c463b0275b0c7f552a82
parent5c08c391211ca4d67e1908fccad45d73c6c76124 (diff)
parentfbbcb089c52e6dce88600be36a1cc97884294d4f (diff)
downloadrust-e3a1e192960c41acc196b59f0cb1b28f78e712f8.tar.gz
rust-e3a1e192960c41acc196b59f0cb1b28f78e712f8.zip
Rollup merge of #93497 - willcrichton:rustdoc-scrape-test, r=GuillaumeGomez
Pass `--test` flag through rustdoc to rustc so `#[test]` functions can be scraped

As a part of stabilizing the scrape examples extension in Cargo, I uncovered a bug where examples cannot be scraped from tests. See this test: https://github.com/rust-lang/cargo/pull/10343/files#diff-27aa4f012ebfebaaee61498d91d2370de460628405d136b05e77efe61e044679R2496

The issue is that when rustdoc is run on a test file, because `--test` is not passed as a rustc option, then functions annotated with `#[test]` are ignored by the compiler. So this PR changes rustdoc so when `--test` is passed in conjunction with a `--scrape-example-<suffix>` flag, then the `test` field of `rustc_interface::Config` is true.

r? `@camelid`
-rw-r--r--src/doc/rustdoc/src/unstable-features.md3
-rw-r--r--src/librustdoc/core.rs3
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/scrape_examples.rs15
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk3
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/Makefile6
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs6
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs3
8 files changed, 37 insertions, 5 deletions
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index d60be193bda..c7fd5ed6fcb 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -509,3 +509,6 @@ reverse-dependency like `examples/ex.rs` is given to rustdoc with the target
 crate being documented (`foobar`) and a path to output the calls
 (`output.calls`). Then, the generated calls file can be passed via
 `--with-examples` to the subsequent documentation of `foobar`.
+
+To scrape examples from test code, e.g. functions marked `#[test]`, then
+add the `--scrape-tests` flag.
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 893e126283b..ca5e7758119 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -200,6 +200,7 @@ crate fn create_config(
         lint_opts,
         describe_lints,
         lint_cap,
+        scrape_examples_options,
         ..
     }: RustdocOptions,
 ) -> rustc_interface::Config {
@@ -227,6 +228,7 @@ crate fn create_config(
 
     let crate_types =
         if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
+    let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
     // plays with error output here!
     let sessopts = config::Options {
         maybe_sysroot,
@@ -244,6 +246,7 @@ crate fn create_config(
         edition,
         describe_lints,
         crate_name,
+        test,
         ..Options::default()
     };
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 170f166db50..7eff725989c 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -596,6 +596,9 @@ fn opts() -> Vec<RustcOptGroup> {
                 "collect function call information for functions from the target crate",
             )
         }),
+        unstable("scrape-tests", |o| {
+            o.optflag("", "scrape-tests", "Include test code when scraping examples")
+        }),
         unstable("with-examples", |o| {
             o.optmulti(
                 "",
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index f9e91c299ea..7cf0ea9e84e 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -34,6 +34,7 @@ use std::path::PathBuf;
 crate struct ScrapeExamplesOptions {
     output_path: PathBuf,
     target_crates: Vec<String>,
+    crate scrape_tests: bool,
 }
 
 impl ScrapeExamplesOptions {
@@ -43,16 +44,22 @@ impl ScrapeExamplesOptions {
     ) -> Result<Option<Self>, i32> {
         let output_path = matches.opt_str("scrape-examples-output-path");
         let target_crates = matches.opt_strs("scrape-examples-target-crate");
-        match (output_path, !target_crates.is_empty()) {
-            (Some(output_path), true) => Ok(Some(ScrapeExamplesOptions {
+        let scrape_tests = matches.opt_present("scrape-tests");
+        match (output_path, !target_crates.is_empty(), scrape_tests) {
+            (Some(output_path), true, _) => Ok(Some(ScrapeExamplesOptions {
                 output_path: PathBuf::from(output_path),
                 target_crates,
+                scrape_tests,
             })),
-            (Some(_), false) | (None, true) => {
+            (Some(_), false, _) | (None, true, _) => {
                 diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
                 Err(1)
             }
-            (None, false) => Ok(None),
+            (None, false, true) => {
+                diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests");
+                Err(1)
+            }
+            (None, false, false) => Ok(None),
         }
     }
 }
diff --git a/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk b/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
index 1fa1fae1a0b..d49b6c1f290 100644
--- a/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
+++ b/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
@@ -7,7 +7,8 @@ $(TMPDIR)/%.calls: $(TMPDIR)/libfoobar.rmeta
 	  --extern foobar=$(TMPDIR)/libfoobar.rmeta \
 		-Z unstable-options \
 		--scrape-examples-output-path $@ \
-		--scrape-examples-target-crate foobar
+		--scrape-examples-target-crate foobar \
+		$(extra_flags)
 
 $(TMPDIR)/lib%.rmeta: src/lib.rs
 	$(RUSTC) src/lib.rs --crate-name $* --crate-type lib --emit=metadata
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/Makefile b/src/test/run-make/rustdoc-scrape-examples-test/Makefile
new file mode 100644
index 00000000000..9f80a8d9602
--- /dev/null
+++ b/src/test/run-make/rustdoc-scrape-examples-test/Makefile
@@ -0,0 +1,6 @@
+extra_flags := --scrape-tests
+deps := ex
+
+-include ../rustdoc-scrape-examples-multiple/scrape.mk
+
+all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs b/src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs
new file mode 100644
index 00000000000..d1a9a74e782
--- /dev/null
+++ b/src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs
@@ -0,0 +1,6 @@
+fn main() {}
+
+#[test]
+fn a_test() {
+  foobar::ok();
+}
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs b/src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs
new file mode 100644
index 00000000000..22be1ad4101
--- /dev/null
+++ b/src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs
@@ -0,0 +1,3 @@
+// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' ''
+
+pub fn ok() {}