Skip to content

Commit 12f029b

Browse files
Fix deref impl on type alias
1 parent bf84eb5 commit 12f029b

File tree

5 files changed

+90
-27
lines changed

5 files changed

+90
-27
lines changed

src/librustdoc/clean/inline.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,24 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
273273
clean::Typedef {
274274
type_: cx.tcx.type_of(did).clean(cx),
275275
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
276+
item_type: build_type_alias_type(cx, did),
277+
}
278+
}
279+
280+
fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
281+
let type_ = cx.tcx.type_of(did).clean(cx);
282+
type_.def_id().and_then(|did| build_ty(cx, did))
283+
}
284+
285+
pub fn build_ty(cx: &DocContext, did: DefId) -> Option<clean::Type> {
286+
match cx.tcx.def_kind(did)? {
287+
DefKind::Struct |
288+
DefKind::Union |
289+
DefKind::Enum |
290+
DefKind::Const |
291+
DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)),
292+
DefKind::TyAlias => build_type_alias_type(cx, did),
293+
_ => None,
276294
}
277295
}
278296

src/librustdoc/clean/mod.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,16 @@ impl Clean<Item> for hir::ImplItem<'_> {
11221122
MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx))
11231123
}
11241124
hir::ImplItemKind::TyAlias(ref ty) => {
1125-
TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true)
1125+
let type_ = ty.clean(cx);
1126+
let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
1127+
TypedefItem(
1128+
Typedef {
1129+
type_,
1130+
generics: Generics::default(),
1131+
item_type,
1132+
},
1133+
true,
1134+
)
11261135
}
11271136
hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(
11281137
OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() },
@@ -1282,10 +1291,13 @@ impl Clean<Item> for ty::AssocItem {
12821291

12831292
AssocTypeItem(bounds, ty.clean(cx))
12841293
} else {
1294+
let type_ = cx.tcx.type_of(self.def_id).clean(cx);
1295+
let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
12851296
TypedefItem(
12861297
Typedef {
1287-
type_: cx.tcx.type_of(self.def_id).clean(cx),
1298+
type_,
12881299
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
1300+
item_type,
12891301
},
12901302
true,
12911303
)
@@ -1989,6 +2001,8 @@ impl Clean<String> for ast::Name {
19892001

19902002
impl Clean<Item> for doctree::Typedef<'_> {
19912003
fn clean(&self, cx: &DocContext<'_>) -> Item {
2004+
let type_ = self.ty.clean(cx);
2005+
let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
19922006
Item {
19932007
name: Some(self.name.clean(cx)),
19942008
attrs: self.attrs.clean(cx),
@@ -1998,7 +2012,11 @@ impl Clean<Item> for doctree::Typedef<'_> {
19982012
stability: cx.stability(self.id).clean(cx),
19992013
deprecation: cx.deprecation(self.id).clean(cx),
20002014
inner: TypedefItem(
2001-
Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) },
2015+
Typedef {
2016+
type_,
2017+
generics: self.gen.clean(cx),
2018+
item_type,
2019+
},
20022020
false,
20032021
),
20042022
}

src/librustdoc/clean/types.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,14 @@ pub struct PathSegment {
14061406
pub struct Typedef {
14071407
pub type_: Type,
14081408
pub generics: Generics,
1409+
// Type of target item.
1410+
pub item_type: Option<Type>,
1411+
}
1412+
1413+
impl GetDefId for Typedef {
1414+
fn def_id(&self) -> Option<DefId> {
1415+
self.type_.def_id()
1416+
}
14091417
}
14101418

14111419
#[derive(Clone, Debug)]

src/librustdoc/html/render.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3469,22 +3469,27 @@ fn render_deref_methods(
34693469
deref_mut: bool,
34703470
) {
34713471
let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
3472-
let target = impl_
3472+
let (target, real_target) = impl_
34733473
.inner_impl()
34743474
.items
34753475
.iter()
34763476
.filter_map(|item| match item.inner {
3477-
clean::TypedefItem(ref t, true) => Some(&t.type_),
3477+
clean::TypedefItem(ref t, true) => {
3478+
Some(match *t {
3479+
clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_),
3480+
_ => (&t.type_, &t.type_),
3481+
})
3482+
}
34783483
_ => None,
34793484
})
34803485
.next()
34813486
.expect("Expected associated type binding");
34823487
let what =
34833488
AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut };
3484-
if let Some(did) = target.def_id() {
3489+
if let Some(did) = real_target.def_id() {
34853490
render_assoc_items(w, cx, container_item, did, what)
34863491
} else {
3487-
if let Some(prim) = target.primitive_type() {
3492+
if let Some(prim) = real_target.primitive_type() {
34883493
if let Some(&did) = cx.cache.primitive_locations.get(&prim) {
34893494
render_assoc_items(w, cx, container_item, did, what);
34903495
}
@@ -4123,17 +4128,22 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
41234128
.filter(|i| i.inner_impl().trait_.is_some())
41244129
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
41254130
{
4126-
if let Some(target) = impl_
4131+
if let Some((target, real_target)) = impl_
41274132
.inner_impl()
41284133
.items
41294134
.iter()
41304135
.filter_map(|item| match item.inner {
4131-
clean::TypedefItem(ref t, true) => Some(&t.type_),
4136+
clean::TypedefItem(ref t, true) => {
4137+
Some(match *t {
4138+
clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_),
4139+
_ => (&t.type_, &t.type_),
4140+
})
4141+
}
41324142
_ => None,
41334143
})
41344144
.next()
41354145
{
4136-
let inner_impl = target
4146+
let inner_impl = real_target
41374147
.def_id()
41384148
.or(target
41394149
.primitive_type()

src/librustdoc/html/render/cache.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ impl DocFolder for Cache {
277277
| clean::StructFieldItem(..)
278278
| clean::VariantItem(..) => (
279279
(
280-
Some(*self.parent_stack.last().unwrap()),
280+
Some(*self.parent_stack.last().expect("parent_stack is empty")),
281281
Some(&self.stack[..self.stack.len() - 1]),
282282
),
283283
false,
@@ -286,7 +286,7 @@ impl DocFolder for Cache {
286286
if self.parent_stack.is_empty() {
287287
((None, None), false)
288288
} else {
289-
let last = self.parent_stack.last().unwrap();
289+
let last = self.parent_stack.last().expect("parent_stack is empty 2");
290290
let did = *last;
291291
let path = match self.paths.get(&did) {
292292
// The current stack not necessarily has correlation
@@ -468,7 +468,7 @@ impl DocFolder for Cache {
468468
self.impls.entry(did).or_insert(vec![]).push(impl_item.clone());
469469
}
470470
} else {
471-
let trait_did = impl_item.trait_did().unwrap();
471+
let trait_did = impl_item.trait_did().expect("no trait did");
472472
self.orphan_trait_impls.push((trait_did, dids, impl_item));
473473
}
474474
None
@@ -478,10 +478,10 @@ impl DocFolder for Cache {
478478
});
479479

480480
if pushed {
481-
self.stack.pop().unwrap();
481+
self.stack.pop().expect("stack already empty");
482482
}
483483
if parent_pushed {
484-
self.parent_stack.pop().unwrap();
484+
self.parent_stack.pop().expect("parent stack already empty");
485485
}
486486
self.stripped_mod = orig_stripped_mod;
487487
self.parent_is_trait_impl = orig_parent_is_trait_impl;
@@ -574,6 +574,9 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
574574
// has since been learned.
575575
for &(did, ref item) in orphan_impl_items {
576576
if let Some(&(ref fqp, _)) = paths.get(&did) {
577+
if item.name.is_none() { // this is most likely from a typedef
578+
continue;
579+
}
577580
search_index.push(IndexItem {
578581
ty: item.type_(),
579582
name: item.name.clone().unwrap(),
@@ -592,19 +595,25 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
592595
let mut lastpathid = 0usize;
593596

594597
for item in search_index {
595-
item.parent_idx = item.parent.map(|nodeid| {
596-
if nodeid_to_pathid.contains_key(&nodeid) {
597-
*nodeid_to_pathid.get(&nodeid).unwrap()
598-
} else {
599-
let pathid = lastpathid;
600-
nodeid_to_pathid.insert(nodeid, pathid);
601-
lastpathid += 1;
598+
item.parent_idx = match item.parent {
599+
Some(nodeid) => {
600+
Some(if nodeid_to_pathid.contains_key(&nodeid) {
601+
*nodeid_to_pathid.get(&nodeid).expect("no pathid")
602+
} else {
603+
let pathid = lastpathid;
604+
nodeid_to_pathid.insert(nodeid, pathid);
605+
lastpathid += 1;
602606

603-
let &(ref fqp, short) = paths.get(&nodeid).unwrap();
604-
crate_paths.push((short, fqp.last().unwrap().clone()));
605-
pathid
607+
if let Some(&(ref fqp, short)) = paths.get(&nodeid) {
608+
crate_paths.push((short, fqp.last().expect("no fqp").clone()));
609+
} else {
610+
continue
611+
}
612+
pathid
613+
})
606614
}
607-
});
615+
None => None,
616+
};
608617

609618
// Omit the parent path if it is same to that of the prior item.
610619
if lastpath == item.path {
@@ -639,7 +648,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
639648
items: crate_items,
640649
paths: crate_paths,
641650
})
642-
.unwrap()
651+
.expect("failed serde conversion")
643652
)
644653
}
645654

0 commit comments

Comments
 (0)