clean::Typedef {
type_: cx.tcx.type_of(did).clean(cx),
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
+ item_type: build_type_alias_type(cx, did),
+ }
+}
+
+fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
+ let type_ = cx.tcx.type_of(did).clean(cx);
+ type_.def_id().and_then(|did| build_ty(cx, did))
+}
+
+pub fn build_ty(cx: &DocContext, did: DefId) -> Option<clean::Type> {
+ match cx.tcx.def_kind(did)? {
+ DefKind::Struct |
+ DefKind::Union |
+ DefKind::Enum |
+ DefKind::Const |
+ DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)),
+ DefKind::TyAlias => build_type_alias_type(cx, did),
+ _ => None,
}
}
MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx))
}
hir::ImplItemKind::TyAlias(ref ty) => {
- TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true)
+ let type_ = ty.clean(cx);
+ let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
+ TypedefItem(
+ Typedef {
+ type_,
+ generics: Generics::default(),
+ item_type,
+ },
+ true,
+ )
}
hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(
OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() },
AssocTypeItem(bounds, ty.clean(cx))
} else {
+ let type_ = cx.tcx.type_of(self.def_id).clean(cx);
+ let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
TypedefItem(
Typedef {
- type_: cx.tcx.type_of(self.def_id).clean(cx),
+ type_,
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
+ item_type,
},
true,
)
impl Clean<Item> for doctree::Typedef<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
+ let type_ = self.ty.clean(cx);
+ let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx),
inner: TypedefItem(
- Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) },
+ Typedef {
+ type_,
+ generics: self.gen.clean(cx),
+ item_type,
+ },
false,
),
}
pub struct Typedef {
pub type_: Type,
pub generics: Generics,
+ // Type of target item.
+ pub item_type: Option<Type>,
+}
+
+impl GetDefId for Typedef {
+ fn def_id(&self) -> Option<DefId> {
+ self.type_.def_id()
+ }
}
#[derive(Clone, Debug)]
deref_mut: bool,
) {
let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
- let target = impl_
+ let (target, real_target) = impl_
.inner_impl()
.items
.iter()
.filter_map(|item| match item.inner {
- clean::TypedefItem(ref t, true) => Some(&t.type_),
+ clean::TypedefItem(ref t, true) => {
+ Some(match *t {
+ clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_),
+ _ => (&t.type_, &t.type_),
+ })
+ }
_ => None,
})
.next()
.expect("Expected associated type binding");
let what =
AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut };
- if let Some(did) = target.def_id() {
+ if let Some(did) = real_target.def_id() {
render_assoc_items(w, cx, container_item, did, what)
} else {
- if let Some(prim) = target.primitive_type() {
+ if let Some(prim) = real_target.primitive_type() {
if let Some(&did) = cx.cache.primitive_locations.get(&prim) {
render_assoc_items(w, cx, container_item, did, what);
}
.filter(|i| i.inner_impl().trait_.is_some())
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
{
- if let Some(target) = impl_
+ if let Some((target, real_target)) = impl_
.inner_impl()
.items
.iter()
.filter_map(|item| match item.inner {
- clean::TypedefItem(ref t, true) => Some(&t.type_),
+ clean::TypedefItem(ref t, true) => {
+ Some(match *t {
+ clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_),
+ _ => (&t.type_, &t.type_),
+ })
+ }
_ => None,
})
.next()
{
- let inner_impl = target
+ let inner_impl = real_target
.def_id()
.or(target
.primitive_type()
| clean::StructFieldItem(..)
| clean::VariantItem(..) => (
(
- Some(*self.parent_stack.last().unwrap()),
+ Some(*self.parent_stack.last().expect("parent_stack is empty")),
Some(&self.stack[..self.stack.len() - 1]),
),
false,
if self.parent_stack.is_empty() {
((None, None), false)
} else {
- let last = self.parent_stack.last().unwrap();
+ let last = self.parent_stack.last().expect("parent_stack is empty 2");
let did = *last;
let path = match self.paths.get(&did) {
// The current stack not necessarily has correlation
self.impls.entry(did).or_insert(vec![]).push(impl_item.clone());
}
} else {
- let trait_did = impl_item.trait_did().unwrap();
+ let trait_did = impl_item.trait_did().expect("no trait did");
self.orphan_trait_impls.push((trait_did, dids, impl_item));
}
None
});
if pushed {
- self.stack.pop().unwrap();
+ self.stack.pop().expect("stack already empty");
}
if parent_pushed {
- self.parent_stack.pop().unwrap();
+ self.parent_stack.pop().expect("parent stack already empty");
}
self.stripped_mod = orig_stripped_mod;
self.parent_is_trait_impl = orig_parent_is_trait_impl;
// has since been learned.
for &(did, ref item) in orphan_impl_items {
if let Some(&(ref fqp, _)) = paths.get(&did) {
+ if item.name.is_none() { // this is most likely from a typedef
+ continue;
+ }
search_index.push(IndexItem {
ty: item.type_(),
name: item.name.clone().unwrap(),
let mut lastpathid = 0usize;
for item in search_index {
- item.parent_idx = item.parent.map(|nodeid| {
- if nodeid_to_pathid.contains_key(&nodeid) {
- *nodeid_to_pathid.get(&nodeid).unwrap()
- } else {
- let pathid = lastpathid;
- nodeid_to_pathid.insert(nodeid, pathid);
- lastpathid += 1;
+ item.parent_idx = match item.parent {
+ Some(nodeid) => {
+ Some(if nodeid_to_pathid.contains_key(&nodeid) {
+ *nodeid_to_pathid.get(&nodeid).expect("no pathid")
+ } else {
+ let pathid = lastpathid;
+ nodeid_to_pathid.insert(nodeid, pathid);
+ lastpathid += 1;
- let &(ref fqp, short) = paths.get(&nodeid).unwrap();
- crate_paths.push((short, fqp.last().unwrap().clone()));
- pathid
+ if let Some(&(ref fqp, short)) = paths.get(&nodeid) {
+ crate_paths.push((short, fqp.last().expect("no fqp").clone()));
+ } else {
+ continue
+ }
+ pathid
+ })
}
- });
+ None => None,
+ };
// Omit the parent path if it is same to that of the prior item.
if lastpath == item.path {
items: crate_items,
paths: crate_paths,
})
- .unwrap()
+ .expect("failed serde conversion")
)
}