diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index a9e0c9cb260f6..d4a1a35790936 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -11,6 +11,8 @@ //! Rust AST Visitor. Extracts useful information and massages it into a form //! usable for clean +use std::collections::HashSet; + use syntax::abi; use syntax::ast; use syntax::ast_util; @@ -38,16 +40,21 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> { pub attrs: Vec, pub cx: &'a core::DocContext<'tcx>, pub analysis: Option<&'a core::CrateAnalysis>, + view_item_stack: HashSet, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { pub fn new(cx: &'a core::DocContext<'tcx>, analysis: Option<&'a core::CrateAnalysis>) -> RustdocVisitor<'a, 'tcx> { + // If the root is reexported, terminate all recursion. + let mut stack = HashSet::new(); + stack.insert(ast::CRATE_NODE_ID); RustdocVisitor { module: Module::new(None), attrs: Vec::new(), cx: cx, analysis: analysis, + view_item_stack: stack, } } @@ -228,8 +235,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if !please_inline && analysis.public_items.contains(&def.node) { return false } + if !self.view_item_stack.insert(def.node) { return false } - match tcx.map.get(def.node) { + let ret = match tcx.map.get(def.node) { ast_map::NodeItem(it) => { if glob { match it.node { @@ -249,7 +257,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { true } _ => false, - } + }; + self.view_item_stack.remove(&id); + return ret; } pub fn visit_item(&mut self, item: &ast::Item, diff --git a/src/test/run-make/rustdoc-recursion/Makefile b/src/test/run-make/rustdoc-recursion/Makefile new file mode 100644 index 0000000000000..b7fc6d6c0ad5b --- /dev/null +++ b/src/test/run-make/rustdoc-recursion/Makefile @@ -0,0 +1,12 @@ +-include ../tools.mk + +# FIXME ignore windows +ifndef IS_WINDOWS +all: + $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs + $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo2.rs + $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo3.rs +else +all: +endif + diff --git a/src/test/run-make/rustdoc-recursion/foo.rs b/src/test/run-make/rustdoc-recursion/foo.rs new file mode 100644 index 0000000000000..29a909f139ead --- /dev/null +++ b/src/test/run-make/rustdoc-recursion/foo.rs @@ -0,0 +1,25 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "lib"] +#![feature(globs)] + +mod m { + pub use self::a::Foo; + + mod a { + pub struct Foo; + } + + mod b { + pub use super::*; + } +} + diff --git a/src/test/run-make/rustdoc-recursion/foo2.rs b/src/test/run-make/rustdoc-recursion/foo2.rs new file mode 100644 index 0000000000000..7505d20566dbb --- /dev/null +++ b/src/test/run-make/rustdoc-recursion/foo2.rs @@ -0,0 +1,24 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "lib"] +#![feature(globs)] + +mod m { + pub use self::a::Foo; + + mod a { + pub struct Foo; + } + + mod b { + pub use super::*; + } +} diff --git a/src/test/run-make/rustdoc-recursion/foo3.rs b/src/test/run-make/rustdoc-recursion/foo3.rs new file mode 100644 index 0000000000000..62a13f76ca4f0 --- /dev/null +++ b/src/test/run-make/rustdoc-recursion/foo3.rs @@ -0,0 +1,25 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(globs)] + +pub mod longhands { + pub use super::*; + + pub use super::common_types::computed::compute_CSSColor as to_computed_value; + + pub fn computed_as_specified() {} +} + +pub mod common_types { + pub mod computed { + pub use super::super::longhands::computed_as_specified as compute_CSSColor; + } +}