From d2b30f7d3883a9f5d2e419d3d2c86cb66e9d3410 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 23 Sep 2014 15:13:56 -0700 Subject: [PATCH] rustdoc: Prevent infinite recursion when inlining Cyclic pub-use chains triggered infinite recursion, and this commit adds a hash set to guard against cyclic recursion. This will cause one of the reexports to render as a `pub use` instead of inlining the documentation. Closes #16274 --- src/librustdoc/visit_ast.rs | 11 +++++++-- src/test/run-make/rustdoc-recursion/Makefile | 10 ++++++++ src/test/run-make/rustdoc-recursion/foo.rs | 25 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/test/run-make/rustdoc-recursion/Makefile create mode 100644 src/test/run-make/rustdoc-recursion/foo.rs diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index a9e0c9cb260..06b79b18d10 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,6 +40,7 @@ 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> { @@ -48,6 +51,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { attrs: Vec::new(), cx: cx, analysis: analysis, + view_item_stack: HashSet::new(), } } @@ -228,8 +232,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if !please_inline && analysis.public_items.contains(&def.node) { return false } + if !self.view_item_stack.insert(id) { 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 +254,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 00000000000..97c0385828d --- /dev/null +++ b/src/test/run-make/rustdoc-recursion/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +# FIXME ignore windows +ifndef IS_WINDOWS +all: + $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.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 00000000000..05f11205b71 --- /dev/null +++ b/src/test/run-make/rustdoc-recursion/foo.rs @@ -0,0 +1,25 @@ +// Copyright 2012-2013 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::*; + } +} +