diff options
| author | Shotaro Yamada <sinkuu@sinkuu.xyz> | 2018-05-03 22:24:50 +0900 |
|---|---|---|
| committer | Shotaro Yamada <sinkuu@sinkuu.xyz> | 2018-05-03 22:34:10 +0900 |
| commit | 14f32f64c8d4700b40ce4e49596b460869b15fe7 (patch) | |
| tree | fc438ef48bd0ba8327a2749af7a8253c288a754f | |
| parent | 427c5487493fbd5e96e81b7d3ba54784e0805df7 (diff) | |
| download | rust-14f32f64c8d4700b40ce4e49596b460869b15fe7.tar.gz rust-14f32f64c8d4700b40ce4e49596b460869b15fe7.zip | |
rustdoc: Resolve nested `impl Trait`s
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 63 | ||||
| -rw-r--r-- | src/test/rustdoc/universal-impl-trait.rs | 7 |
2 files changed, 39 insertions, 31 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bd64ac67ac9..ffba91c9248 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1755,8 +1755,18 @@ pub struct Generics { impl Clean<Generics> for hir::Generics { fn clean(&self, cx: &DocContext) -> Generics { + let mut params = Vec::with_capacity(self.params.len()); + for p in &self.params { + let p = p.clean(cx); + if let GenericParam::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); + } let mut g = Generics { - params: self.params.clean(cx), + params, where_predicates: self.where_clause.predicates.clean(cx) }; @@ -1869,9 +1879,11 @@ pub struct Method { impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) { fn clean(&self, cx: &DocContext) -> Method { - let generics = self.1.clean(cx); + let (generics, decl) = enter_impl_trait(cx, || { + (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)) + }); Method { - decl: enter_impl_trait(cx, &generics.params, || (&*self.0.decl, self.2).clean(cx)), + decl, generics, unsafety: self.0.unsafety, constness: self.0.constness, @@ -1899,8 +1911,9 @@ pub struct Function { impl Clean<Item> for doctree::Function { fn clean(&self, cx: &DocContext) -> Item { - let generics = self.generics.clean(cx); - let decl = enter_impl_trait(cx, &generics.params, || (&self.decl, self.body).clean(cx)); + let (generics, decl) = enter_impl_trait(cx, || { + (self.generics.clean(cx), (&self.decl, self.body).clean(cx)) + }); Item { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), @@ -2139,12 +2152,12 @@ impl Clean<Item> for hir::TraitItem { MethodItem((sig, &self.generics, body).clean(cx)) } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => { - let generics = self.generics.clean(cx); + let (generics, decl) = enter_impl_trait(cx, || { + (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx)) + }); TyMethodItem(TyMethod { unsafety: sig.unsafety.clone(), - decl: enter_impl_trait(cx, &generics.params, || { - (&*sig.decl, &names[..]).clean(cx) - }), + decl, generics, abi: sig.abi }) @@ -3415,12 +3428,12 @@ pub struct BareFunctionDecl { impl Clean<BareFunctionDecl> for hir::BareFnTy { fn clean(&self, cx: &DocContext) -> BareFunctionDecl { - let generic_params = self.generic_params.clean(cx); + let (generic_params, decl) = enter_impl_trait(cx, || { + (self.generic_params.clean(cx), (&*self.decl, &self.arg_names[..]).clean(cx)) + }); BareFunctionDecl { unsafety: self.unsafety, - decl: enter_impl_trait(cx, &generic_params, || { - (&*self.decl, &self.arg_names[..]).clean(cx) - }), + decl, generic_params, abi: self.abi, } @@ -3722,11 +3735,11 @@ impl Clean<Item> for hir::ForeignItem { fn clean(&self, cx: &DocContext) -> Item { let inner = match self.node { hir::ForeignItemFn(ref decl, ref names, ref generics) => { - let generics = generics.clean(cx); + let (generics, decl) = enter_impl_trait(cx, || { + (generics.clean(cx), (&**decl, &names[..]).clean(cx)) + }); ForeignFunctionItem(Function { - decl: enter_impl_trait(cx, &generics.params, || { - (&**decl, &names[..]).clean(cx) - }), + decl, generics, unsafety: hir::Unsafety::Unsafe, abi: Abi::Rust, @@ -4030,23 +4043,11 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec< once(crate_name).chain(relative).collect() } -pub fn enter_impl_trait<F, R>(cx: &DocContext, gps: &[GenericParam], f: F) -> R +pub fn enter_impl_trait<F, R>(cx: &DocContext, f: F) -> R where F: FnOnce() -> R, { - let bounds = gps.iter() - .filter_map(|p| { - if let GenericParam::Type(ref tp) = *p { - if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) { - return Some((tp.did, tp.bounds.clone())); - } - } - - None - }) - .collect::<FxHashMap<DefId, Vec<TyParamBound>>>(); - - let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), bounds); + let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default()); let r = f(); assert!(cx.impl_trait_bounds.borrow().is_empty()); *cx.impl_trait_bounds.borrow_mut() = old_bounds; diff --git a/src/test/rustdoc/universal-impl-trait.rs b/src/test/rustdoc/universal-impl-trait.rs index 4cf99562c52..af51ff3d941 100644 --- a/src/test/rustdoc/universal-impl-trait.rs +++ b/src/test/rustdoc/universal-impl-trait.rs @@ -11,6 +11,8 @@ #![feature(universal_impl_trait)] #![crate_name = "foo"] +use std::io::Read; + // @has foo/fn.foo.html // @has - //pre 'foo(' // @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"' @@ -39,6 +41,11 @@ impl<T> S<T> { // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html' pub fn baz(_baz: S<impl Clone>) { } + + // @has - 'qux</a>(' + // @matches - 'trait\.Read\.html' + pub fn qux(_qux: impl IntoIterator<Item = S<impl Read>>) { + } } // @has - 'method</a>(' |
