Skip to content

Commit

Permalink
Fix rustdoc panic with impl Trait in type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
sinkuu committed May 16, 2018
1 parent e44fc6c commit 7eefe2b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
35 changes: 29 additions & 6 deletions src/librustdoc/clean/mod.rs
Expand Up @@ -1754,16 +1754,39 @@ pub struct Generics {

impl Clean<Generics> for hir::Generics {
fn clean(&self, cx: &DocContext) -> Generics {
// Synthetic type-parameters are inserted after normal ones.
// In order for normal parameters to be able to refer to synthetic ones,
// scans them first.
fn is_impl_trait(param: &hir::GenericParam) -> bool {
if let hir::GenericParam::Type(ref tp) = param {
tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
} else {
false
}
}
let impl_trait_params = self.params
.iter()
.filter(|p| is_impl_trait(p))
.map(|p| {
let p = p.clean(cx);
if let GenericParamDef::Type(ref tp) = p {
cx.impl_trait_bounds
.borrow_mut()
.insert(tp.did, tp.bounds.clone());
} else {
unreachable!()
}
p
})
.collect::<Vec<_>>();

let mut params = Vec::with_capacity(self.params.len());
for p in &self.params {
for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
let p = p.clean(cx);
if let GenericParamDef::Type(ref tp) = p {
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
}
}
params.push(p);
}
params.extend(impl_trait_params);

let mut g = Generics {
params,
where_predicates: self.where_clause.predicates.clean(cx)
Expand Down
14 changes: 13 additions & 1 deletion src/test/rustdoc/universal-impl-trait.rs
Expand Up @@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(universal_impl_trait)]
#![crate_name = "foo"]

use std::io::Read;
use std::borrow::Borrow;

// @has foo/fn.foo.html
// @has - //pre 'foo('
Expand Down Expand Up @@ -51,3 +51,15 @@ impl<T> S<T> {
// @has - 'method</a>('
// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Debug\.html"'
impl<T> Trait for S<T> {}

// @has foo/fn.much_universe.html
// @matches - 'T:.+Borrow.+impl .+trait\.Trait\.html'
// @matches - 'U:.+IntoIterator.+= impl.+Iterator\.html.+= impl.+Clone\.html'
// @matches - '_: impl .+trait\.Read\.html.+ \+ .+trait\.Clone\.html'
pub fn much_universe<
T: Borrow<impl Trait>,
U: IntoIterator<Item = impl Iterator<Item = impl Clone>>,
>(
_: impl Read + Clone,
) {
}

0 comments on commit 7eefe2b

Please sign in to comment.