Skip to content

Commit aee50f4

Browse files
committed
fix rustdoc stack overflow on mutually recursive Deref
fix #85095
1 parent 9089771 commit aee50f4

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/librustdoc/html/render/mod.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1960,13 +1960,19 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
19601960
.filter(|i| i.inner_impl().trait_.is_some())
19611961
.find(|i| i.inner_impl().trait_.def_id_full(cache) == cx.cache.deref_trait_did)
19621962
{
1963-
sidebar_deref_methods(cx, out, impl_, v);
1963+
sidebar_deref_methods(cx, out, impl_, v, FxHashSet::default());
19641964
}
19651965
}
19661966
}
19671967
}
19681968

1969-
fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &Vec<Impl>) {
1969+
fn sidebar_deref_methods(
1970+
cx: &Context<'_>,
1971+
out: &mut Buffer,
1972+
impl_: &Impl,
1973+
v: &Vec<Impl>,
1974+
mut already_seen: FxHashSet<DefId>,
1975+
) {
19701976
let c = cx.cache();
19711977

19721978
debug!("found Deref: {:?}", impl_);
@@ -2032,7 +2038,15 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
20322038
.filter(|i| i.inner_impl().trait_.is_some())
20332039
.find(|i| i.inner_impl().trait_.def_id_full(c) == c.deref_trait_did)
20342040
{
2035-
sidebar_deref_methods(cx, out, target_deref_impl, target_impls);
2041+
if already_seen.insert(target_did.clone()) {
2042+
sidebar_deref_methods(
2043+
cx,
2044+
out,
2045+
target_deref_impl,
2046+
target_impls,
2047+
already_seen,
2048+
);
2049+
}
20362050
}
20372051
}
20382052
}

src/test/rustdoc/issue-85095.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::ops::Deref;
2+
3+
pub struct A;
4+
pub struct B;
5+
6+
// @has issue_85095/struct.A.html '//code' 'impl Deref for A'
7+
impl Deref for A {
8+
type Target = B;
9+
10+
fn deref(&self) -> &Self::Target {
11+
panic!()
12+
}
13+
}
14+
15+
// @has issue_85095/struct.B.html '//code' 'impl Deref for B'
16+
impl Deref for B {
17+
type Target = A;
18+
19+
fn deref(&self) -> &Self::Target {
20+
panic!()
21+
}
22+
}

0 commit comments

Comments
 (0)