Skip to content

rustdoc: Add an attribute to ignore collecting tests per-item. #38825

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

Closed
wants to merge 1 commit into from
Closed
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
10 changes: 10 additions & 0 deletions src/doc/book/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,16 @@ through the `#![doc(test(..))]` attribute.
This allows unused variables within the examples, but will fail the test for any
other lint warning thrown.

You can also ignore tests for a given item and all the nested items under it
with:

```rust
#![doc(test(ignore))]
```

Tests for documentation examples for that item or nested items won't be
generated.

## Generation options

`rustdoc` also contains a few other options on the command line, for further customization:
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
#![feature(libc)]
#![feature(rustc_private)]
#![feature(set_stdio)]
Expand Down
35 changes: 26 additions & 9 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use rustc_metadata::cstore::CStore;
use rustc_resolve::MakeGlobMap;
use rustc_trans::back::link;
use syntax::ast;
use syntax::codemap::CodeMap;
use syntax::codemap::{CodeMap, Spanned};
use syntax::feature_gate::UnstableFeatures;
use errors;
use errors::emitter::ColorConfig;
Expand Down Expand Up @@ -124,6 +124,21 @@ pub fn run(input: &str,
0
}

// Returns the inner attributes of an attribute like
//
// #[doc(test(..))]
fn doc_test_attr_list<'a, I>(attrs: I) -> impl Iterator<Item = &'a Spanned<ast::NestedMetaItemKind>>
where I: IntoIterator<Item = &'a ast::Attribute>,
{
attrs.into_iter()
.filter(|a| a.check_name("doc"))
.filter_map(|a| a.meta_item_list())
.flat_map(|l| l)
.filter(|a| a.check_name("test"))
.filter_map(|a| a.meta_item_list())
.flat_map(|l| l)
}

// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
use syntax::print::pprust;
Expand All @@ -133,14 +148,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
attrs: Vec::new(),
};

let attrs = krate.attrs.iter()
.filter(|a| a.check_name("doc"))
.filter_map(|a| a.meta_item_list())
.flat_map(|l| l)
.filter(|a| a.check_name("test"))
.filter_map(|a| a.meta_item_list())
.flat_map(|l| l);
for attr in attrs {
for attr in doc_test_attr_list(&krate.attrs) {
if attr.check_name("no_crate_inject") {
opts.no_crate_inject = true;
}
Expand Down Expand Up @@ -474,6 +482,15 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
name: String,
attrs: &[ast::Attribute],
nested: F) {
// Find a #[doc(test(ignore))] attribute, and don't collect tests if
// present.
let ignore_tests =
doc_test_attr_list(attrs).any(|attr| attr.check_name("ignore"));

if ignore_tests {
return;
}

let has_name = !name.is_empty();
if has_name {
self.collector.names.push(name);
Expand Down
59 changes: 59 additions & 0 deletions src/test/rustdoc/ignore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags:--test

#[doc(test(ignore))]
pub mod foo {
/**
* This doc example should be ignored.
*
* ```
* this is invalid rust, and thus would fail the test.
* ```
*/
pub fn bar() { }

/// Just like this.
///
/// ```
/// moar invalid code
/// ```
pub struct Foo(());

impl Foo {
/// And this too.
///
/// ```rust
/// void* foo = bar();
/// foo->do_baz();
/// ```
pub fn baz(&self) -> i32 {
unreachable!();
}
}
}

pub mod boo {
/// This one should run though.
///
/// ```
/// let foo = 0xbadc0de;
/// ```
pub fn bar() {}

/// But this should be ignored.
///
/// ```rust
/// moar code that wouldn't compile in ages.
/// ```
#[doc(test(ignore))]
pub struct Bar;
}