diff options
| author | bors <bors@rust-lang.org> | 2021-01-04 10:32:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-01-04 10:32:28 +0000 |
| commit | 6163bfdcce6404c5d61d6ab441bf49a831082194 (patch) | |
| tree | df84df6a3ff736da63f3c06a84595b7e310cffc4 | |
| parent | 887398ff688e2e3cf8a95e588d0b51420e08fb6b (diff) | |
| parent | 24ef94593c84084be03e6461b702178523767cf7 (diff) | |
| download | rust-6163bfdcce6404c5d61d6ab441bf49a831082194.tar.gz rust-6163bfdcce6404c5d61d6ab441bf49a831082194.zip | |
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 https://github.com/rust-lang/rust/pull/80653 and thinking about https://github.com/rust-lang/rust/issues/80379. The new test case worked before, it just wasn't tested. r? `@GuillaumeGomez`
| -rw-r--r-- | src/librustdoc/clean/inline.rs | 20 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 31 | ||||
| -rw-r--r-- | src/librustdoc/clean/types.rs | 11 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 3 | ||||
| -rw-r--r-- | src/test/rustdoc/deref-typedef.rs | 19 |
5 files changed, 53 insertions, 31 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c168c56d30d..ed972cc16e9 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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_, 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: None, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 14902c318c9..0b979120ff9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1119,10 +1119,17 @@ 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) @@ -1268,13 +1275,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_, generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, - item_type, + item_type: None, }, true, ) @@ -1987,11 +1994,15 @@ 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).clean(cx); TypedefItem( - Typedef { type_: rustdoc_ty, generics: generics.clean(cx), item_type }, + Typedef { + type_: rustdoc_ty, + generics: generics.clean(cx), + item_type: Some(ty), + }, false, ) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8d5ef1ed28c..cc31461646c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -332,6 +332,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>), @@ -1804,7 +1808,12 @@ crate struct PathSegment { crate struct Typedef { crate type_: Type, crate generics: Generics, - // Type of target item. + /// `type_` can come from either the HIR or from metadata. If it comes from HIR, it may be a type + /// alias instead of the final type. This will always have the final type, regardless of whether + /// `type_` came from HIR or from metadata. + /// + /// If `item_type.is_none()`, `type_` is guarenteed to come from metadata (and therefore hold the + /// final type). crate item_type: Option<Type>, } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1c713df9276..f7eb136a754 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -4303,6 +4303,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 { @@ -4312,6 +4313,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()) @@ -4325,6 +4327,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { }) .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 {}<Target={}>", diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index 770f8d7289c..e2dac2cf417 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/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) {} @@ -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!() } } |
