about summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuietMisdreavus <grey@quietmisdreavus.net>2019-06-28 10:31:27 -0500
committerQuietMisdreavus <grey@quietmisdreavus.net>2019-07-06 21:37:17 -0500
commitbed54cf85457d76f479fcd406f07b39c5e8abb12 (patch)
tree6f57cc26d9d118bbe1b59afd1e08cebe9659c126
parentb0bd5f236d9bea38b8c9048f379fec179b09984c (diff)
downloadrust-bed54cf85457d76f479fcd406f07b39c5e8abb12.tar.gz
rust-bed54cf85457d76f479fcd406f07b39c5e8abb12.zip
rustdoc: set cfg(doctest) when collecting doctests
-rw-r--r--src/doc/rustdoc/src/unstable-features.md30
-rw-r--r--src/librustdoc/config.rs3
-rw-r--r--src/libsyntax/feature_gate.rs4
-rw-r--r--src/libsyntax_pos/symbol.rs2
-rw-r--r--src/test/rustdoc-ui/cfg-test.rs10
-rw-r--r--src/test/rustdoc-ui/cfg-test.stdout7
-rw-r--r--src/test/rustdoc/cfg-doctest.rs8
-rw-r--r--src/test/ui/feature-gate/feature-gate-cfg_doctest.rs4
-rw-r--r--src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr12
9 files changed, 77 insertions, 3 deletions
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 3938df1a682..1d9510c9aac 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -212,6 +212,36 @@ pub struct BigX;
 Then, when looking for it through the `rustdoc` search, if you enter "x" or
 "big", search will show the `BigX` struct first.
 
+### Include items only when collecting doctests
+
+Rustdoc's [documentation tests] can do some things that regular unit tests can't, so it can
+sometimes be useful to extend your doctests with samples that wouldn't otherwise need to be in
+documentation. To this end, Rustdoc allows you to have certain items only appear when it's
+collecting doctests, so you can utilize doctest functionality without forcing the test to appear in
+docs, or to find an arbitrary private item to include it on.
+
+If you add `#![feature(cfg_doctest)]` to your crate, Rustdoc will set `cfg(doctest)` when collecting
+doctests. Note that they will still link against only the public items of your crate; if you need to
+test private items, unit tests are still the way to go.
+
+In this example, we're adding doctests that we know won't compile, to verify that our struct can
+only take in valid data:
+
+```rust
+#![feature(cfg_doctest)]
+
+/// We have a struct here. Remember it doesn't accept negative numbers!
+pub struct MyStruct(usize);
+
+/// ```compile_fail
+/// let x = my_crate::MyStruct(-5);
+/// ```
+#[cfg(doctest)]
+pub struct MyStructOnlyTakesUsize;
+```
+
+[documentation tests]: documentation-tests.html
+
 ## Unstable command-line arguments
 
 These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 67ca7f407d8..9fae246155e 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -351,6 +351,9 @@ impl Options {
                             .unwrap_or_else(|| PathBuf::from("doc"));
         let mut cfgs = matches.opt_strs("cfg");
         cfgs.push("rustdoc".to_string());
+        if should_test {
+            cfgs.push("doctest".to_string());
+        }
 
         let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 2b242a71ad4..c1a794a0d00 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -577,6 +577,9 @@ declare_features! (
     // Allows `async || body` closures.
     (active, async_closure, "1.37.0", Some(62290), None),
 
+    // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
+    (active, cfg_doctest, "1.37.0", Some(62210), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
@@ -1592,6 +1595,7 @@ const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
     (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
     (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
     (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
+    (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
 ];
 
 #[derive(Debug)]
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 410f4b36b67..bfcb1857852 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -170,6 +170,7 @@ symbols! {
         cfg,
         cfg_attr,
         cfg_attr_multi,
+        cfg_doctest,
         cfg_target_feature,
         cfg_target_has_atomic,
         cfg_target_thread_local,
@@ -235,6 +236,7 @@ symbols! {
         doc_keyword,
         doc_masked,
         doc_spotlight,
+        doctest,
         document_private_items,
         dotdoteq_in_patterns,
         dotdot_in_tuple_patterns,
diff --git a/src/test/rustdoc-ui/cfg-test.rs b/src/test/rustdoc-ui/cfg-test.rs
index 4dcf512d286..5360354d77a 100644
--- a/src/test/rustdoc-ui/cfg-test.rs
+++ b/src/test/rustdoc-ui/cfg-test.rs
@@ -5,6 +5,8 @@
 // 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`.
 
+#![feature(cfg_doctest)]
+
 /// this doctest will be ignored:
 ///
 /// ```
@@ -20,3 +22,11 @@ pub struct Foo;
 /// ```
 #[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
index 67873870e89..de7e6097fb7 100644
--- a/src/test/rustdoc-ui/cfg-test.stdout
+++ b/src/test/rustdoc-ui/cfg-test.stdout
@@ -1,6 +1,7 @@
 
-running 1 test
-test $DIR/cfg-test.rs - Foo (line 18) ... ok
+running 2 tests
+test $DIR/cfg-test.rs - Foo (line 20) ... ok
+test $DIR/cfg-test.rs - Bar (line 28) ... ok
 
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
 
diff --git a/src/test/rustdoc/cfg-doctest.rs b/src/test/rustdoc/cfg-doctest.rs
new file mode 100644
index 00000000000..fca6d1029f9
--- /dev/null
+++ b/src/test/rustdoc/cfg-doctest.rs
@@ -0,0 +1,8 @@
+#![feature(cfg_doctest)]
+
+// @!has cfg_doctest/struct.SomeStruct.html
+// @!has cfg_doctest/index.html '//a/@href' 'struct.SomeStruct.html'
+
+/// Sneaky, this isn't actually part of docs.
+#[cfg(doctest)]
+pub struct SomeStruct;
diff --git a/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs b/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs
new file mode 100644
index 00000000000..308f68bd52a
--- /dev/null
+++ b/src/test/ui/feature-gate/feature-gate-cfg_doctest.rs
@@ -0,0 +1,4 @@
+#[cfg(doctest)] //~ ERROR
+pub struct SomeStruct;
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr b/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr
new file mode 100644
index 00000000000..aa1d18a6f75
--- /dev/null
+++ b/src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr
@@ -0,0 +1,12 @@
+error[E0658]: `cfg(doctest)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg_doctest.rs:1:7
+   |
+LL | #[cfg(doctest)]
+   |       ^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62210
+   = help: add #![feature(cfg_doctest)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.