Skip to content

Commit

Permalink
Simplify rustdoc handling of type aliases for associated types
Browse files Browse the repository at this point in the history
The logic was very hard to follow before.
  • Loading branch information
jyn514 committed Jan 3, 2021
1 parent 18d27b2 commit a786eaa
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 31 deletions.
20 changes: 3 additions & 17 deletions src/librustdoc/clean/inline.rs
Expand Up @@ -261,26 +261,12 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {

fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
let predicates = cx.tcx.explicit_predicates_of(did);
let type_ = cx.tcx.type_of(did).clean(cx);

clean::Typedef {
type_: cx.tcx.type_of(did).clean(cx),
type_: type_.clone(),
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))
}

crate 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,
item_type: Some(type_),
}
}

Expand Down
22 changes: 11 additions & 11 deletions src/librustdoc/clean/mod.rs
Expand Up @@ -1118,10 +1118,10 @@ impl Clean<Item> for hir::ImplItem<'_> {
}
MethodItem(m, Some(self.defaultness))
}
hir::ImplItemKind::TyAlias(ref ty) => {
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::TyAlias(ref hir_ty) => {
let type_ = hir_ty.clean(cx);
let item_type = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx);
TypedefItem(Typedef { type_, generics: Generics::default(), item_type: Some(item_type) }, true)
}
};
Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
Expand Down Expand Up @@ -1267,13 +1267,13 @@ impl Clean<Item> for ty::AssocItem {

AssocTypeItem(bounds, ty.clean(cx))
} else {
// FIXME: when could this happen? ASsociated items in inherent impls?
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_,
type_: type_.clone(),
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
item_type,
item_type: Some(type_),
},
true,
)
Expand Down Expand Up @@ -1986,11 +1986,11 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
bounds: ty.bounds.clean(cx),
generics: ty.generics.clean(cx),
}),
ItemKind::TyAlias(ty, ref generics) => {
let rustdoc_ty = ty.clean(cx);
let item_type = rustdoc_ty.def_id().and_then(|did| inline::build_ty(cx, did));
ItemKind::TyAlias(hir_ty, ref generics) => {
let rustdoc_ty = hir_ty.clean(cx);
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
TypedefItem(
Typedef { type_: rustdoc_ty, generics: generics.clean(cx), item_type },
Typedef { type_: rustdoc_ty, generics: generics.clean(cx), item_type: Some(ty.clean(cx)) },
false,
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/clean/types.rs
Expand Up @@ -334,6 +334,10 @@ crate enum ItemKind {
ProcMacroItem(ProcMacro),
PrimitiveItem(PrimitiveType),
AssocConstItem(Type, Option<String>),
/// An associated item in a trait or trait impl.
///
/// The bounds may be non-empty if there is a `where` clause.
/// The `Option<Type>` is the default concrete type (e.g. `trait Trait { type Target = usize; }`)
AssocTypeItem(Vec<GenericBound>, Option<Type>),
/// An item that has been stripped by a rustdoc pass
StrippedItem(Box<ItemKind>),
Expand Down
3 changes: 3 additions & 0 deletions src/librustdoc/html/render/mod.rs
Expand Up @@ -4308,6 +4308,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
.filter(|i| i.inner_impl().trait_.is_some())
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
{
debug!("found Deref: {:?}", impl_);
if let Some((target, real_target)) =
impl_.inner_impl().items.iter().find_map(|item| match *item.kind {
clean::TypedefItem(ref t, true) => Some(match *t {
Expand All @@ -4317,6 +4318,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
_ => None,
})
{
debug!("found target, real_target: {:?} {:?}", target, real_target);
let deref_mut = v
.iter()
.filter(|i| i.inner_impl().trait_.is_some())
Expand All @@ -4328,6 +4330,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
.and_then(|prim| c.primitive_locations.get(&prim).cloned()))
.and_then(|did| c.impls.get(&did));
if let Some(impls) = inner_impl {
debug!("found inner_impl: {:?}", impls);
out.push_str("<a class=\"sidebar-title\" href=\"#deref-methods\">");
out.push_str(&format!(
"Methods from {}&lt;Target={}&gt;",
Expand Down
19 changes: 16 additions & 3 deletions src/test/rustdoc/deref-typedef.rs
@@ -1,18 +1,27 @@
#![crate_name = "foo"]

// @has 'foo/struct.Bar.html'
// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooC>'
// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooJ>'
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)'
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref<Target=FooC>'
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref<Target=FooJ>'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_j"]' 'foo_j'

pub struct FooA;
pub type FooB = FooA;
pub type FooC = FooB;
pub type FooD = FooC;
pub type FooE = FooD;
pub type FooF = FooE;
pub type FooG = FooF;
pub type FooH = FooG;
pub type FooI = FooH;
pub type FooJ = FooI;

impl FooA {
pub fn foo_a(&self) {}
Expand All @@ -26,8 +35,12 @@ impl FooC {
pub fn foo_c(&self) {}
}

impl FooJ {
pub fn foo_j(&self) {}
}

pub struct Bar;
impl std::ops::Deref for Bar {
type Target = FooC;
type Target = FooJ;
fn deref(&self) -> &Self::Target { unimplemented!() }
}

0 comments on commit a786eaa

Please sign in to comment.