Skip to content

Commit b92f26c

Browse files
committed
rustdoc: Add an attribute to avoid collecting tests in nested items.
This allows to ignore tests in modules we know they have uneffective tests, or tests not under our control, like for example in: rust-lang/rust-bindgen#378 Signed-off-by: Emilio Cobos Álvarez <[email protected]>
1 parent 9c0e373 commit b92f26c

File tree

4 files changed

+96
-9
lines changed

4 files changed

+96
-9
lines changed

src/doc/book/documentation.md

+10
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,16 @@ through the `#![doc(test(..))]` attribute.
651651
This allows unused variables within the examples, but will fail the test for any
652652
other lint warning thrown.
653653

654+
You can also ignore tests for a given item and all the nested items under it
655+
with:
656+
657+
```rust
658+
#![doc(test(ignore))]
659+
```
660+
661+
Tests for documentation examples for that item or nested items won't be
662+
generated.
663+
654664
## Generation options
655665

656666
`rustdoc` also contains a few other options on the command line, for further customization:

src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#![feature(box_patterns)]
2222
#![feature(box_syntax)]
23+
#![feature(conservative_impl_trait)]
2324
#![feature(libc)]
2425
#![feature(rustc_private)]
2526
#![feature(set_stdio)]

src/librustdoc/test.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_metadata::cstore::CStore;
3535
use rustc_resolve::MakeGlobMap;
3636
use rustc_trans::back::link;
3737
use syntax::ast;
38-
use syntax::codemap::CodeMap;
38+
use syntax::codemap::{CodeMap, Spanned};
3939
use syntax::feature_gate::UnstableFeatures;
4040
use errors;
4141
use errors::emitter::ColorConfig;
@@ -124,6 +124,21 @@ pub fn run(input: &str,
124124
0
125125
}
126126

127+
// Returns the inner attributes of an attribute like
128+
//
129+
// #[doc(test(..))]
130+
fn doc_test_attr_list<'a, I>(attrs: I) -> impl Iterator<Item = &'a Spanned<ast::NestedMetaItemKind>>
131+
where I: IntoIterator<Item = &'a ast::Attribute>,
132+
{
133+
attrs.into_iter()
134+
.filter(|a| a.check_name("doc"))
135+
.filter_map(|a| a.meta_item_list())
136+
.flat_map(|l| l)
137+
.filter(|a| a.check_name("test"))
138+
.filter_map(|a| a.meta_item_list())
139+
.flat_map(|l| l)
140+
}
141+
127142
// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
128143
fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
129144
use syntax::print::pprust;
@@ -133,14 +148,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
133148
attrs: Vec::new(),
134149
};
135150

136-
let attrs = krate.attrs.iter()
137-
.filter(|a| a.check_name("doc"))
138-
.filter_map(|a| a.meta_item_list())
139-
.flat_map(|l| l)
140-
.filter(|a| a.check_name("test"))
141-
.filter_map(|a| a.meta_item_list())
142-
.flat_map(|l| l);
143-
for attr in attrs {
151+
for attr in doc_test_attr_list(&krate.attrs) {
144152
if attr.check_name("no_crate_inject") {
145153
opts.no_crate_inject = true;
146154
}
@@ -474,6 +482,15 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
474482
name: String,
475483
attrs: &[ast::Attribute],
476484
nested: F) {
485+
// Find a #[doc(test(ignore))] attribute, and don't collect tests if
486+
// present.
487+
let ignore_tests =
488+
doc_test_attr_list(attrs).any(|attr| attr.check_name("ignore"));
489+
490+
if ignore_tests {
491+
return;
492+
}
493+
477494
let has_name = !name.is_empty();
478495
if has_name {
479496
self.collector.names.push(name);

src/test/rustdoc/ignore.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags:--test
12+
13+
#[doc(test(ignore))]
14+
pub mod foo {
15+
/**
16+
* This doc example should be ignored.
17+
*
18+
* ```
19+
* this is invalid rust, and thus would fail the test.
20+
* ```
21+
*/
22+
pub fn bar() { }
23+
24+
/// Just like this.
25+
///
26+
/// ```
27+
/// moar invalid code
28+
/// ```
29+
pub struct Foo(());
30+
31+
impl Foo {
32+
/// And this too.
33+
///
34+
/// ```rust
35+
/// void* foo = bar();
36+
/// foo->do_baz();
37+
/// ```
38+
pub fn baz(&self) -> i32 {
39+
unreachable!();
40+
}
41+
}
42+
}
43+
44+
pub mod boo {
45+
/// This one should run though.
46+
///
47+
/// ```
48+
/// let foo = 0xbadc0de;
49+
/// ```
50+
pub fn bar() {}
51+
52+
/// But this should be ignored.
53+
///
54+
/// ```rust
55+
/// moar code that wouldn't compile in ages.
56+
/// ```
57+
#[doc(test(ignore))]
58+
pub struct Bar;
59+
}

0 commit comments

Comments
 (0)