Skip to content

Commit fd9c710

Browse files
sinkuupietroalbini
authored andcommitted
rustdoc: Resolve nested impl Traits
1 parent 1f200ac commit fd9c710

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
@@ -1729,8 +1729,18 @@ pub struct Generics {
17291729

17301730
impl Clean<Generics> for hir::Generics {
17311731
fn clean(&self, cx: &DocContext) -> Generics {
1732+
let mut params = Vec::with_capacity(self.params.len());
1733+
for p in &self.params {
1734+
let p = p.clean(cx);
1735+
if let GenericParam::Type(ref tp) = p {
1736+
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
1737+
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
1738+
}
1739+
}
1740+
params.push(p);
1741+
}
17321742
let mut g = Generics {
1733-
params: self.params.clean(cx),
1743+
params,
17341744
where_predicates: self.where_clause.predicates.clean(cx)
17351745
};
17361746

@@ -1843,9 +1853,11 @@ pub struct Method {
18431853

18441854
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
18451855
fn clean(&self, cx: &DocContext) -> Method {
1846-
let generics = self.1.clean(cx);
1856+
let (generics, decl) = enter_impl_trait(cx, || {
1857+
(self.1.clean(cx), (&*self.0.decl, self.2).clean(cx))
1858+
});
18471859
Method {
1848-
decl: enter_impl_trait(cx, &generics.params, || (&*self.0.decl, self.2).clean(cx)),
1860+
decl,
18491861
generics,
18501862
unsafety: self.0.unsafety,
18511863
constness: self.0.constness,
@@ -1873,8 +1885,9 @@ pub struct Function {
18731885

18741886
impl Clean<Item> for doctree::Function {
18751887
fn clean(&self, cx: &DocContext) -> Item {
1876-
let generics = self.generics.clean(cx);
1877-
let decl = enter_impl_trait(cx, &generics.params, || (&self.decl, self.body).clean(cx));
1888+
let (generics, decl) = enter_impl_trait(cx, || {
1889+
(self.generics.clean(cx), (&self.decl, self.body).clean(cx))
1890+
});
18781891
Item {
18791892
name: Some(self.name.clean(cx)),
18801893
attrs: self.attrs.clean(cx),
@@ -2113,12 +2126,12 @@ impl Clean<Item> for hir::TraitItem {
21132126
MethodItem((sig, &self.generics, body).clean(cx))
21142127
}
21152128
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
2116-
let generics = self.generics.clean(cx);
2129+
let (generics, decl) = enter_impl_trait(cx, || {
2130+
(self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
2131+
});
21172132
TyMethodItem(TyMethod {
21182133
unsafety: sig.unsafety.clone(),
2119-
decl: enter_impl_trait(cx, &generics.params, || {
2120-
(&*sig.decl, &names[..]).clean(cx)
2121-
}),
2134+
decl,
21222135
generics,
21232136
abi: sig.abi
21242137
})
@@ -3389,12 +3402,12 @@ pub struct BareFunctionDecl {
33893402

33903403
impl Clean<BareFunctionDecl> for hir::BareFnTy {
33913404
fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
3392-
let generic_params = self.generic_params.clean(cx);
3405+
let (generic_params, decl) = enter_impl_trait(cx, || {
3406+
(self.generic_params.clean(cx), (&*self.decl, &self.arg_names[..]).clean(cx))
3407+
});
33933408
BareFunctionDecl {
33943409
unsafety: self.unsafety,
3395-
decl: enter_impl_trait(cx, &generic_params, || {
3396-
(&*self.decl, &self.arg_names[..]).clean(cx)
3397-
}),
3410+
decl,
33983411
generic_params,
33993412
abi: self.abi,
34003413
}
@@ -3696,11 +3709,11 @@ impl Clean<Item> for hir::ForeignItem {
36963709
fn clean(&self, cx: &DocContext) -> Item {
36973710
let inner = match self.node {
36983711
hir::ForeignItemFn(ref decl, ref names, ref generics) => {
3699-
let generics = generics.clean(cx);
3712+
let (generics, decl) = enter_impl_trait(cx, || {
3713+
(generics.clean(cx), (&**decl, &names[..]).clean(cx))
3714+
});
37003715
ForeignFunctionItem(Function {
3701-
decl: enter_impl_trait(cx, &generics.params, || {
3702-
(&**decl, &names[..]).clean(cx)
3703-
}),
3716+
decl,
37043717
generics,
37053718
unsafety: hir::Unsafety::Unsafe,
37063719
abi: Abi::Rust,
@@ -4003,23 +4016,11 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec<
40034016
once(crate_name).chain(relative).collect()
40044017
}
40054018

4006-
pub fn enter_impl_trait<F, R>(cx: &DocContext, gps: &[GenericParam], f: F) -> R
4019+
pub fn enter_impl_trait<F, R>(cx: &DocContext, f: F) -> R
40074020
where
40084021
F: FnOnce() -> R,
40094022
{
4010-
let bounds = gps.iter()
4011-
.filter_map(|p| {
4012-
if let GenericParam::Type(ref tp) = *p {
4013-
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
4014-
return Some((tp.did, tp.bounds.clone()));
4015-
}
4016-
}
4017-
4018-
None
4019-
})
4020-
.collect::<FxHashMap<DefId, Vec<TyParamBound>>>();
4021-
4022-
let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), bounds);
4023+
let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default());
40234024
let r = f();
40244025
assert!(cx.impl_trait_bounds.borrow().is_empty());
40254026
*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)