提交 14f32f64 编写于 作者: S Shotaro Yamada

rustdoc: Resolve nested `impl Trait`s

上级 427c5487
...@@ -1755,8 +1755,18 @@ pub struct Generics { ...@@ -1755,8 +1755,18 @@ pub struct Generics {
impl Clean<Generics> for hir::Generics { impl Clean<Generics> for hir::Generics {
fn clean(&self, cx: &DocContext) -> 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 { let mut g = Generics {
params: self.params.clean(cx), params,
where_predicates: self.where_clause.predicates.clean(cx) where_predicates: self.where_clause.predicates.clean(cx)
}; };
...@@ -1869,9 +1879,11 @@ pub struct Method { ...@@ -1869,9 +1879,11 @@ pub struct Method {
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) { impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
fn clean(&self, cx: &DocContext) -> Method { 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 { Method {
decl: enter_impl_trait(cx, &generics.params, || (&*self.0.decl, self.2).clean(cx)), decl,
generics, generics,
unsafety: self.0.unsafety, unsafety: self.0.unsafety,
constness: self.0.constness, constness: self.0.constness,
...@@ -1899,8 +1911,9 @@ pub struct Function { ...@@ -1899,8 +1911,9 @@ pub struct Function {
impl Clean<Item> for doctree::Function { impl Clean<Item> for doctree::Function {
fn clean(&self, cx: &DocContext) -> Item { fn clean(&self, cx: &DocContext) -> Item {
let generics = self.generics.clean(cx); let (generics, decl) = enter_impl_trait(cx, || {
let decl = enter_impl_trait(cx, &generics.params, || (&self.decl, self.body).clean(cx)); (self.generics.clean(cx), (&self.decl, self.body).clean(cx))
});
Item { Item {
name: Some(self.name.clean(cx)), name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
...@@ -2139,12 +2152,12 @@ fn clean(&self, cx: &DocContext) -> Item { ...@@ -2139,12 +2152,12 @@ fn clean(&self, cx: &DocContext) -> Item {
MethodItem((sig, &self.generics, body).clean(cx)) MethodItem((sig, &self.generics, body).clean(cx))
} }
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => { 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 { TyMethodItem(TyMethod {
unsafety: sig.unsafety.clone(), unsafety: sig.unsafety.clone(),
decl: enter_impl_trait(cx, &generics.params, || { decl,
(&*sig.decl, &names[..]).clean(cx)
}),
generics, generics,
abi: sig.abi abi: sig.abi
}) })
...@@ -3415,12 +3428,12 @@ pub struct BareFunctionDecl { ...@@ -3415,12 +3428,12 @@ pub struct BareFunctionDecl {
impl Clean<BareFunctionDecl> for hir::BareFnTy { impl Clean<BareFunctionDecl> for hir::BareFnTy {
fn clean(&self, cx: &DocContext) -> BareFunctionDecl { 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 { BareFunctionDecl {
unsafety: self.unsafety, unsafety: self.unsafety,
decl: enter_impl_trait(cx, &generic_params, || { decl,
(&*self.decl, &self.arg_names[..]).clean(cx)
}),
generic_params, generic_params,
abi: self.abi, abi: self.abi,
} }
...@@ -3722,11 +3735,11 @@ impl Clean<Item> for hir::ForeignItem { ...@@ -3722,11 +3735,11 @@ impl Clean<Item> for hir::ForeignItem {
fn clean(&self, cx: &DocContext) -> Item { fn clean(&self, cx: &DocContext) -> Item {
let inner = match self.node { let inner = match self.node {
hir::ForeignItemFn(ref decl, ref names, ref generics) => { 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 { ForeignFunctionItem(Function {
decl: enter_impl_trait(cx, &generics.params, || { decl,
(&**decl, &names[..]).clean(cx)
}),
generics, generics,
unsafety: hir::Unsafety::Unsafe, unsafety: hir::Unsafety::Unsafe,
abi: Abi::Rust, abi: Abi::Rust,
...@@ -4030,23 +4043,11 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec< ...@@ -4030,23 +4043,11 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec<
once(crate_name).chain(relative).collect() 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 where
F: FnOnce() -> R, F: FnOnce() -> R,
{ {
let bounds = gps.iter() let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default());
.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 r = f(); let r = f();
assert!(cx.impl_trait_bounds.borrow().is_empty()); assert!(cx.impl_trait_bounds.borrow().is_empty());
*cx.impl_trait_bounds.borrow_mut() = old_bounds; *cx.impl_trait_bounds.borrow_mut() = old_bounds;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#![feature(universal_impl_trait)] #![feature(universal_impl_trait)]
#![crate_name = "foo"] #![crate_name = "foo"]
use std::io::Read;
// @has foo/fn.foo.html // @has foo/fn.foo.html
// @has - //pre 'foo(' // @has - //pre 'foo('
// @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"' // @matches - '_x: impl <a class="trait" href="[^"]+/trait\.Clone\.html"'
...@@ -39,6 +41,11 @@ pub fn bar(_bar: impl Copy) { ...@@ -39,6 +41,11 @@ pub fn bar(_bar: impl Copy) {
// @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html' // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html'
pub fn baz(_baz: S<impl Clone>) { 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>(' // @has - 'method</a>('
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册