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 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 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 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 @@ fn clean(&self, cx: &DocContext) -> Item { 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 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 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) -> Vec< once(crate_name).chain(relative).collect() } -pub fn enter_impl_trait(cx: &DocContext, gps: &[GenericParam], f: F) -> R +pub fn enter_impl_trait(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::>>(); - - 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 ) { } + + // @has - 'qux(' + // @matches - 'trait\.Read\.html' + pub fn qux(_qux: impl IntoIterator>) { + } } // @has - 'method('