diff options
| author | Shotaro Yamada <sinkuu@sinkuu.xyz> | 2018-05-14 12:07:34 +0900 |
|---|---|---|
| committer | Shotaro Yamada <sinkuu@sinkuu.xyz> | 2018-05-16 11:03:02 +0900 |
| commit | 7eefe2b4735b018efa50fa1e5ebfaf4db868ba22 (patch) | |
| tree | bb3c4126187f25cc7d5c7479b6031b1dd3f3410e /src | |
| parent | e44fc6c52d9674ed09958512e3bf09bc55bccecf (diff) | |
| download | rust-7eefe2b4735b018efa50fa1e5ebfaf4db868ba22.tar.gz rust-7eefe2b4735b018efa50fa1e5ebfaf4db868ba22.zip | |
Fix rustdoc panic with `impl Trait` in type parameters
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 35 | ||||
| -rw-r--r-- | src/test/rustdoc/universal-impl-trait.rs | 14 |
2 files changed, 42 insertions, 7 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a1d77f4145b..c233e57a801 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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) diff --git a/src/test/rustdoc/universal-impl-trait.rs b/src/test/rustdoc/universal-impl-trait.rs index af51ff3d941..1c1124282d4 100644 --- a/src/test/rustdoc/universal-impl-trait.rs +++ b/src/test/rustdoc/universal-impl-trait.rs @@ -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(' @@ -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, +) { +} |
