Skip to content

Commit

Permalink
Rollup merge of rust-lang#41172 - Aaron1011:rustdoc-overflow, r=frewsxcv
Browse files Browse the repository at this point in the history
Fix rustdoc infinitely recursing when an external crate reexports itself

Previously, rustdoc's LibEmbargoVisitor unconditionally visited the
child modules of an external crate. If a module re-exported its parent
via `pub use super::*`, rustdoc would re-walk the parent, leading to
infinite recursion.

This commit makes LibEmbargoVisitor store already visited modules in an
FxHashSet, ensuring that each module is only walked once.

Fixes rust-lang#40936
  • Loading branch information
frewsxcv authored Apr 14, 2017
2 parents e6f6b44 + 63a291f commit 5d7467a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/librustdoc/visit_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc::middle::privacy::{AccessLevels, AccessLevel};
use rustc::hir::def::Def;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
use rustc::ty::Visibility;
use rustc::util::nodemap::FxHashSet;

use std::cell::RefMut;

Expand All @@ -29,6 +30,8 @@ pub struct LibEmbargoVisitor<'a, 'b: 'a, 'tcx: 'b> {
access_levels: RefMut<'a, AccessLevels<DefId>>,
// Previous accessibility level, None means unreachable
prev_level: Option<AccessLevel>,
// Keeps track of already visited modules, in case a module re-exports its parent
visited_mods: FxHashSet<DefId>,
}

impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
Expand All @@ -38,6 +41,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
cstore: &*cx.sess().cstore,
access_levels: cx.access_levels.borrow_mut(),
prev_level: Some(AccessLevel::Public),
visited_mods: FxHashSet()
}
}

Expand All @@ -62,6 +66,10 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
}

pub fn visit_mod(&mut self, def_id: DefId) {
if !self.visited_mods.insert(def_id) {
return;
}

for item in self.cstore.item_children(def_id) {
self.visit_item(item.def);
}
Expand Down
15 changes: 15 additions & 0 deletions src/test/rustdoc/auxiliary/issue-40936.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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.

pub mod outermod {
pub mod innermod {
pub use super::*;
}
}
16 changes: 16 additions & 0 deletions src/test/rustdoc/issue-40936.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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.

// aux-build:issue-40936.rs
// build-aux-docs

#![crate_name = "foo"]

extern crate issue_40936;

0 comments on commit 5d7467a

Please sign in to comment.