Skip to content

Commit 14f32f6

Browse files
committed
rustdoc: Resolve nested impl Traits
1 parent 427c548 commit 14f32f6

File tree

2 files changed

+39
-31
lines changed

2 files changed

+39
-31
lines changed

src/librustdoc/clean/mod.rs

+32-31
Original file line numberDiff line numberDiff line change
@@ -1755,8 +1755,18 @@ pub struct Generics {
17551755

17561756
impl Clean<Generics> for hir::Generics {
17571757
fn clean(&self, cx: &DocContext) -> Generics {
1758+
let mut params = Vec::with_capacity(self.params.len());
1759+
for p in &self.params {
1760+
let p = p.clean(cx);
1761+
if let GenericParam::Type(ref tp) = p {
1762+
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
1763+
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
1764+
}
1765+
}
1766+
params.push(p);
1767+
}
17581768
let mut g = Generics {
1759-
params: self.params.clean(cx),
1769+
params,
17601770
where_predicates: self.where_clause.predicates.clean(cx)
17611771
};
17621772

@@ -1869,9 +1879,11 @@ pub struct Method {
18691879

18701880
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
18711881
fn clean(&self, cx: &DocContext) -> Method {
1872-
let generics = self.1.clean(cx);
1882+
let (generics, decl) = enter_impl_trait(cx, || {
1883+
(self.1.clean(cx), (&*self.0.decl, self.2).clean(cx))
1884+
});
18731885
Method {
1874-
decl: enter_impl_trait(cx, &generics.params, || (&*self.0.decl, self.2).clean(cx)),
1886+
decl,
18751887
generics,
18761888
unsafety: self.0.unsafety,
18771889
constness: self.0.constness,
@@ -1899,8 +1911,9 @@ pub struct Function {
18991911

19001912
impl Clean<Item> for doctree::Function {
19011913
fn clean(&self, cx: &DocContext) -> Item {
1902-
let generics = self.generics.clean(cx);
1903-
let decl = enter_impl_trait(cx, &generics.params, || (&self.decl, self.body).clean(cx));
1914+
let (generics, decl) = enter_impl_trait(cx, || {
1915+
(self.generics.clean(cx), (&self.decl, self.body).clean(cx))
1916+
});
19041917
Item {
19051918
name: Some(self.name.clean(cx)),
19061919
attrs: self.attrs.clean(cx),
@@ -2139,12 +2152,12 @@ impl Clean<Item> for hir::TraitItem {
21392152
MethodItem((sig, &self.generics, body).clean(cx))
21402153
}
21412154
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
2142-
let generics = self.generics.clean(cx);
2155+
let (generics, decl) = enter_impl_trait(cx, || {
2156+
(self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
2157+
});
21432158
TyMethodItem(TyMethod {
21442159
unsafety: sig.unsafety.clone(),
2145-
decl: enter_impl_trait(cx, &generics.params, || {
2146-
(&*sig.decl, &names[..]).clean(cx)
2147-
}),
2160+
decl,
21482161
generics,
21492162
abi: sig.abi
21502163
})
@@ -3415,12 +3428,12 @@ pub struct BareFunctionDecl {
34153428

34163429
impl Clean<BareFunctionDecl> for hir::BareFnTy {
34173430
fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
3418-
let generic_params = self.generic_params.clean(cx);
3431+
let (generic_params, decl) = enter_impl_trait(cx, || {
3432+
(self.generic_params.clean(cx), (&*self.decl, &self.arg_names[..]).clean(cx))
3433+
});
34193434
BareFunctionDecl {
34203435
unsafety: self.unsafety,
3421-
decl: enter_impl_trait(cx, &generic_params, || {
3422-
(&*self.decl, &self.arg_names[..]).clean(cx)
3423-
}),
3436+
decl,
34243437
generic_params,
34253438
abi: self.abi,
34263439
}
@@ -3722,11 +3735,11 @@ impl Clean<Item> for hir::ForeignItem {
37223735
fn clean(&self, cx: &DocContext) -> Item {
37233736
let inner = match self.node {
37243737
hir::ForeignItemFn(ref decl, ref names, ref generics) => {
3725-
let generics = generics.clean(cx);
3738+
let (generics, decl) = enter_impl_trait(cx, || {
3739+
(generics.clean(cx), (&**decl, &names[..]).clean(cx))
3740+
});
37263741
ForeignFunctionItem(Function {
3727-
decl: enter_impl_trait(cx, &generics.params, || {
3728-
(&**decl, &names[..]).clean(cx)
3729-
}),
3742+
decl,
37303743
generics,
37313744
unsafety: hir::Unsafety::Unsafe,
37323745
abi: Abi::Rust,
@@ -4030,23 +4043,11 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec<
40304043
once(crate_name).chain(relative).collect()
40314044
}
40324045

4033-
pub fn enter_impl_trait<F, R>(cx: &DocContext, gps: &[GenericParam], f: F) -> R
4046+
pub fn enter_impl_trait<F, R>(cx: &DocContext, f: F) -> R
40344047
where
40354048
F: FnOnce() -> R,
40364049
{
4037-
let bounds = gps.iter()
4038-
.filter_map(|p| {
4039-
if let GenericParam::Type(ref tp) = *p {
4040-
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
4041-
return Some((tp.did, tp.bounds.clone()));
4042-
}
4043-
}
4044-
4045-
None
4046-
})
4047-
.collect::<FxHashMap<DefId, Vec<TyParamBound>>>();
4048-
4049-
let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), bounds);
4050+
let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default());
40504051
let r = f();
40514052
assert!(cx.impl_trait_bounds.borrow().is_empty());
40524053
*cx.impl_trait_bounds.borrow_mut() = old_bounds;

src/test/rustdoc/universal-impl-trait.rs

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#![feature(universal_impl_trait)]
1212
#![crate_name = "foo"]
1313

14+
use std::io::Read;
15+
1416
// @has foo/fn.foo.html
1517
// @has - //pre 'foo('
1618
// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
@@ -39,6 +41,11 @@ impl<T> S<T> {
3941
// @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
4042
pub fn baz(_baz: S<impl Clone>) {
4143
}
44+
45+
// @has - 'qux</a>('
46+
// @matches - 'trait\.Read\.html'
47+
pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) {
48+
}
4249
}
4350

4451
// @has - 'method</a>('

0 commit comments

Comments
 (0)