Skip to content

Commit 6163bfd

Browse files
committed
Auto merge of #80661 - jyn514:duplicate-types, r=GuillaumeGomez
Cleanup rustdoc handling of associated types This is best reviewed a commit at a time. No particular reason for these changes, they just stood out as I was reviewing #80653 and thinking about #80379. The new test case worked before, it just wasn't tested. r? `@GuillaumeGomez`
2 parents 887398f + 24ef945 commit 6163bfd

File tree

5 files changed

+53
-31
lines changed

5 files changed

+53
-31
lines changed

src/librustdoc/clean/inline.rs

+3-17
Original file line numberDiff line numberDiff line change
@@ -261,26 +261,12 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
261261

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

265266
clean::Typedef {
266-
type_: cx.tcx.type_of(did).clean(cx),
267+
type_,
267268
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
268-
item_type: build_type_alias_type(cx, did),
269-
}
270-
}
271-
272-
fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
273-
let type_ = cx.tcx.type_of(did).clean(cx);
274-
type_.def_id().and_then(|did| build_ty(cx, did))
275-
}
276-
277-
crate fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
278-
match cx.tcx.def_kind(did) {
279-
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => {
280-
Some(cx.tcx.type_of(did).clean(cx))
281-
}
282-
DefKind::TyAlias => build_type_alias_type(cx, did),
283-
_ => None,
269+
item_type: None,
284270
}
285271
}
286272

src/librustdoc/clean/mod.rs

+21-10
Original file line numberDiff line numberDiff line change
@@ -1119,10 +1119,17 @@ impl Clean<Item> for hir::ImplItem<'_> {
11191119
}
11201120
MethodItem(m, Some(self.defaultness))
11211121
}
1122-
hir::ImplItemKind::TyAlias(ref ty) => {
1123-
let type_ = ty.clean(cx);
1124-
let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
1125-
TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true)
1122+
hir::ImplItemKind::TyAlias(ref hir_ty) => {
1123+
let type_ = hir_ty.clean(cx);
1124+
let item_type = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx);
1125+
TypedefItem(
1126+
Typedef {
1127+
type_,
1128+
generics: Generics::default(),
1129+
item_type: Some(item_type),
1130+
},
1131+
true,
1132+
)
11261133
}
11271134
};
11281135
Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
@@ -1268,13 +1275,13 @@ impl Clean<Item> for ty::AssocItem {
12681275

12691276
AssocTypeItem(bounds, ty.clean(cx))
12701277
} else {
1278+
// FIXME: when could this happen? ASsociated items in inherent impls?
12711279
let type_ = cx.tcx.type_of(self.def_id).clean(cx);
1272-
let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
12731280
TypedefItem(
12741281
Typedef {
12751282
type_,
12761283
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
1277-
item_type,
1284+
item_type: None,
12781285
},
12791286
true,
12801287
)
@@ -1987,11 +1994,15 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
19871994
bounds: ty.bounds.clean(cx),
19881995
generics: ty.generics.clean(cx),
19891996
}),
1990-
ItemKind::TyAlias(ty, ref generics) => {
1991-
let rustdoc_ty = ty.clean(cx);
1992-
let item_type = rustdoc_ty.def_id().and_then(|did| inline::build_ty(cx, did));
1997+
ItemKind::TyAlias(hir_ty, ref generics) => {
1998+
let rustdoc_ty = hir_ty.clean(cx);
1999+
let ty = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx);
19932000
TypedefItem(
1994-
Typedef { type_: rustdoc_ty, generics: generics.clean(cx), item_type },
2001+
Typedef {
2002+
type_: rustdoc_ty,
2003+
generics: generics.clean(cx),
2004+
item_type: Some(ty),
2005+
},
19952006
false,
19962007
)
19972008
}

src/librustdoc/clean/types.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ crate enum ItemKind {
332332
ProcMacroItem(ProcMacro),
333333
PrimitiveItem(PrimitiveType),
334334
AssocConstItem(Type, Option<String>),
335+
/// An associated item in a trait or trait impl.
336+
///
337+
/// The bounds may be non-empty if there is a `where` clause.
338+
/// The `Option<Type>` is the default concrete type (e.g. `trait Trait { type Target = usize; }`)
335339
AssocTypeItem(Vec<GenericBound>, Option<Type>),
336340
/// An item that has been stripped by a rustdoc pass
337341
StrippedItem(Box<ItemKind>),
@@ -1804,7 +1808,12 @@ crate struct PathSegment {
18041808
crate struct Typedef {
18051809
crate type_: Type,
18061810
crate generics: Generics,
1807-
// Type of target item.
1811+
/// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type
1812+
/// alias instead of the final type. This will always have the final type, regardless of whether
1813+
/// `type_` came from HIR or from metadata.
1814+
///
1815+
/// If `item_type.is_none()`, `type_` is guarenteed to come from metadata (and therefore hold the
1816+
/// final type).
18081817
crate item_type: Option<Type>,
18091818
}
18101819

src/librustdoc/html/render/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4303,6 +4303,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
43034303
.filter(|i| i.inner_impl().trait_.is_some())
43044304
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
43054305
{
4306+
debug!("found Deref: {:?}", impl_);
43064307
if let Some((target, real_target)) =
43074308
impl_.inner_impl().items.iter().find_map(|item| match *item.kind {
43084309
clean::TypedefItem(ref t, true) => Some(match *t {
@@ -4312,6 +4313,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
43124313
_ => None,
43134314
})
43144315
{
4316+
debug!("found target, real_target: {:?} {:?}", target, real_target);
43154317
let deref_mut = v
43164318
.iter()
43174319
.filter(|i| i.inner_impl().trait_.is_some())
@@ -4325,6 +4327,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
43254327
})
43264328
.and_then(|did| c.impls.get(&did));
43274329
if let Some(impls) = inner_impl {
4330+
debug!("found inner_impl: {:?}", impls);
43284331
out.push_str("<a class=\"sidebar-title\" href=\"#deref-methods\">");
43294332
out.push_str(&format!(
43304333
"Methods from {}&lt;Target={}&gt;",

src/test/rustdoc/deref-typedef.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
#![crate_name = "foo"]
22

33
// @has 'foo/struct.Bar.html'
4-
// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooC>'
4+
// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooJ>'
55
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)'
66
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
77
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
8-
// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref<Target=FooC>'
8+
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
9+
// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref<Target=FooJ>'
910
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
1011
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
1112
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'
13+
// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_j"]' 'foo_j'
1214

1315
pub struct FooA;
1416
pub type FooB = FooA;
1517
pub type FooC = FooB;
18+
pub type FooD = FooC;
19+
pub type FooE = FooD;
20+
pub type FooF = FooE;
21+
pub type FooG = FooF;
22+
pub type FooH = FooG;
23+
pub type FooI = FooH;
24+
pub type FooJ = FooI;
1625

1726
impl FooA {
1827
pub fn foo_a(&self) {}
@@ -26,8 +35,12 @@ impl FooC {
2635
pub fn foo_c(&self) {}
2736
}
2837

38+
impl FooJ {
39+
pub fn foo_j(&self) {}
40+
}
41+
2942
pub struct Bar;
3043
impl std::ops::Deref for Bar {
31-
type Target = FooC;
44+
type Target = FooJ;
3245
fn deref(&self) -> &Self::Target { unimplemented!() }
3346
}

0 commit comments

Comments
 (0)