Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: set cfg(doctest) when collecting doctests #62213

Merged
merged 2 commits into from
Jul 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/doc/rustdoc/src/unstable-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// -------------------------------------------------------------------------
Expand Down Expand Up @@ -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)]
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ symbols! {
cfg,
cfg_attr,
cfg_attr_multi,
cfg_doctest,
cfg_target_feature,
cfg_target_has_atomic,
cfg_target_thread_local,
Expand Down Expand Up @@ -235,6 +236,7 @@ symbols! {
doc_keyword,
doc_masked,
doc_spotlight,
doctest,
document_private_items,
dotdoteq_in_patterns,
dotdot_in_tuple_patterns,
Expand Down
12 changes: 11 additions & 1 deletion src/test/rustdoc-ui/cfg-test.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// build-pass (FIXME(62277): could be check-pass?)
// compile-flags:--test
// compile-flags:--test --test-args --test-threads=1
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"

// 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:
///
/// ```
Expand All @@ -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;
7 changes: 4 additions & 3 deletions src/test/rustdoc-ui/cfg-test.stdout
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

running 1 test
test $DIR/cfg-test.rs - Foo (line 18) ... ok
running 2 tests
test $DIR/cfg-test.rs - Bar (line 28) ... ok
test $DIR/cfg-test.rs - Foo (line 20) ... 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

8 changes: 8 additions & 0 deletions src/test/rustdoc/cfg-doctest.rs
Original file line number Diff line number Diff line change
@@ -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;
4 changes: 4 additions & 0 deletions src/test/ui/feature-gate/feature-gate-cfg_doctest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[cfg(doctest)] //~ ERROR
pub struct SomeStruct;

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/feature-gate/feature-gate-cfg_doctest.stderr
Original file line number Diff line number Diff line change
@@ -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`.