Skip to content

Commit 7eefe2b

Browse files
committed
Fix rustdoc panic with impl Trait in type parameters
1 parent e44fc6c commit 7eefe2b

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

src/librustdoc/clean/mod.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -1754,16 +1754,39 @@ pub struct Generics {
17541754

17551755
impl Clean<Generics> for hir::Generics {
17561756
fn clean(&self, cx: &DocContext) -> Generics {
1757+
// Synthetic type-parameters are inserted after normal ones.
1758+
// In order for normal parameters to be able to refer to synthetic ones,
1759+
// scans them first.
1760+
fn is_impl_trait(param: &hir::GenericParam) -> bool {
1761+
if let hir::GenericParam::Type(ref tp) = param {
1762+
tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
1763+
} else {
1764+
false
1765+
}
1766+
}
1767+
let impl_trait_params = self.params
1768+
.iter()
1769+
.filter(|p| is_impl_trait(p))
1770+
.map(|p| {
1771+
let p = p.clean(cx);
1772+
if let GenericParamDef::Type(ref tp) = p {
1773+
cx.impl_trait_bounds
1774+
.borrow_mut()
1775+
.insert(tp.did, tp.bounds.clone());
1776+
} else {
1777+
unreachable!()
1778+
}
1779+
p
1780+
})
1781+
.collect::<Vec<_>>();
1782+
17571783
let mut params = Vec::with_capacity(self.params.len());
1758-
for p in &self.params {
1784+
for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
17591785
let p = p.clean(cx);
1760-
if let GenericParamDef::Type(ref tp) = p {
1761-
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
1762-
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
1763-
}
1764-
}
17651786
params.push(p);
17661787
}
1788+
params.extend(impl_trait_params);
1789+
17671790
let mut g = Generics {
17681791
params,
17691792
where_predicates: self.where_clause.predicates.clean(cx)

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(universal_impl_trait)]
1211
#![crate_name = "foo"]
1312

1413
use std::io::Read;
14+
use std::borrow::Borrow;
1515

1616
// @has foo/fn.foo.html
1717
// @has - //pre 'foo('
@@ -51,3 +51,15 @@ impl<T> S<T> {
5151
// @has - 'method</a>('
5252
// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
5353
impl<T> Trait for S<T> {}
54+
55+
// @has foo/fn.much_universe.html
56+
// @matches - 'T:.+Borrow.+impl .+trait\.Trait\.html'
57+
// @matches - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
58+
// @matches - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
59+
pub fn much_universe<
60+
T: Borrow<impl Trait>,
61+
U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
62+
>(
63+
_: impl Read + Clone,
64+
) {
65+
}

0 commit comments

Comments
 (0)