Skip to content

Commit 5d7467a

Browse files
authored
Rollup merge of #41172 - Aaron1011:rustdoc-overflow, r=frewsxcv
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 #40936
2 parents e6f6b44 + 63a291f commit 5d7467a

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

src/librustdoc/visit_lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc::middle::privacy::{AccessLevels, AccessLevel};
1313
use rustc::hir::def::Def;
1414
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
1515
use rustc::ty::Visibility;
16+
use rustc::util::nodemap::FxHashSet;
1617

1718
use std::cell::RefMut;
1819

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

3437
impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
@@ -38,6 +41,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
3841
cstore: &*cx.sess().cstore,
3942
access_levels: cx.access_levels.borrow_mut(),
4043
prev_level: Some(AccessLevel::Public),
44+
visited_mods: FxHashSet()
4145
}
4246
}
4347

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

6468
pub fn visit_mod(&mut self, def_id: DefId) {
69+
if !self.visited_mods.insert(def_id) {
70+
return;
71+
}
72+
6573
for item in self.cstore.item_children(def_id) {
6674
self.visit_item(item.def);
6775
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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+
pub mod outermod {
12+
pub mod innermod {
13+
pub use super::*;
14+
}
15+
}

src/test/rustdoc/issue-40936.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
// aux-build:issue-40936.rs
12+
// build-aux-docs
13+
14+
#![crate_name = "foo"]
15+
16+
extern crate issue_40936;

0 commit comments

Comments
 (0)