Skip to content

Commit 9a2aeff

Browse files
don't run doctests on the same item twice
1 parent 4c6bf49 commit 9a2aeff

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

src/librustdoc/test.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc::hir::intravisit;
2727
use rustc::session::{self, CompileIncomplete, config};
2828
use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions};
2929
use rustc::session::search_paths::{SearchPaths, PathKind};
30+
use rustc::util::nodemap::FxHashSet;
3031
use rustc_metadata::dynamic_lib::DynamicLibrary;
3132
use tempfile::Builder as TempFileBuilder;
3233
use rustc_driver::{self, driver, target_features, Compilation};
@@ -152,6 +153,7 @@ pub fn run(input_path: &Path,
152153
collector: &mut collector,
153154
map: &map,
154155
codes: ErrorCodes::from(sess.opts.unstable_features.is_nightly_build()),
156+
tested_items: FxHashSet(),
155157
current_vis: true,
156158
};
157159
hir_collector.visit_testable("".to_string(), &krate.attrs, true, |this| {
@@ -673,6 +675,7 @@ struct HirCollector<'a, 'hir: 'a> {
673675
collector: &'a mut Collector,
674676
map: &'a hir::map::Map<'hir>,
675677
codes: ErrorCodes,
678+
tested_items: FxHashSet<ast::NodeId>,
676679
current_vis: bool,
677680
}
678681

@@ -745,8 +748,6 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
745748
if is_public {
746749
if let Some(node) = self.map.get_if_local(path.def.def_id()) {
747750
// load doctests from the actual item, not the use statement
748-
// TODO(misdreavus): this will run some doctests multiple times if an item is
749-
// re-exported multiple times (say, into a prelude)
750751
match node {
751752
// if we've re-exported an item, continue with the new item, using the
752753
// exported visibility
@@ -791,6 +792,11 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
791792
}
792793
}
793794

795+
if !self.tested_items.insert(item.id) {
796+
// item's been tested already, don't run them again
797+
return;
798+
}
799+
794800
let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.node {
795801
self.map.node_to_pretty_string(ty.id)
796802
} else {
@@ -815,19 +821,34 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
815821
}
816822

817823
fn visit_trait_item(&mut self, item: &'hir hir::TraitItem) {
824+
if !self.tested_items.insert(item.id) {
825+
// item's been tested already, don't run them again
826+
return;
827+
}
828+
818829
self.visit_testable(item.ident.to_string(), &item.attrs, true, |this| {
819830
intravisit::walk_trait_item(this, item);
820831
});
821832
}
822833

823834
fn visit_impl_item(&mut self, item: &'hir hir::ImplItem) {
835+
if !self.tested_items.insert(item.id) {
836+
// item's been tested already, don't run them again
837+
return;
838+
}
839+
824840
let is_public = item.vis.node.is_pub();
825841
self.visit_testable(item.ident.to_string(), &item.attrs, is_public, |this| {
826842
intravisit::walk_impl_item(this, item);
827843
});
828844
}
829845

830846
fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem) {
847+
if !self.tested_items.insert(item.id) {
848+
// item's been tested already, don't run them again
849+
return;
850+
}
851+
831852
let is_public = item.vis.node.is_pub();
832853
self.visit_testable(item.name.to_string(),
833854
&item.attrs,
@@ -841,12 +862,20 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
841862
v: &'hir hir::Variant,
842863
g: &'hir hir::Generics,
843864
item_id: ast::NodeId) {
865+
// FIXME(misdreavus): variants don't have their own NodeId so we can't insert them into the
866+
// set
867+
844868
self.visit_testable(v.node.name.to_string(), &v.node.attrs, true, |this| {
845869
intravisit::walk_variant(this, v, g, item_id);
846870
});
847871
}
848872

849873
fn visit_struct_field(&mut self, f: &'hir hir::StructField) {
874+
if !self.tested_items.insert(f.id) {
875+
// item's been tested already, don't run them again
876+
return;
877+
}
878+
850879
let is_public = f.vis.node.is_pub();
851880
self.visit_testable(f.ident.to_string(),
852881
&f.attrs,
@@ -857,6 +886,11 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
857886
}
858887

859888
fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef) {
889+
if !self.tested_items.insert(macro_def.id) {
890+
// item's been tested already, don't run them again
891+
return;
892+
}
893+
860894
// FIXME(misdreavus): does macro export status surface to us? is it in AccessLevels, does
861895
// its #[macro_export] attribute show up here?
862896
self.visit_testable(macro_def.name.to_string(), &macro_def.attrs, true, |_| ());

0 commit comments

Comments
 (0)