Skip to content

Commit

Permalink
rustdoc: remove details for type alias inner type and fix sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed Aug 25, 2023
1 parent 9443f84 commit 282acb9
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 104 deletions.
17 changes: 17 additions & 0 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2252,6 +2252,23 @@ pub(crate) struct TypeAlias {
pub(crate) item_type: Option<Type>,
}

impl TypeAlias {
pub(crate) fn should_display_inner_type(&self) -> bool {
// Only show inner variants if:
// - the typealias does NOT have any generics (modulo lifetimes)
// - AND the aliased type has some generics
//
// Otherwise, showing a non-generic type is rendurant with its own page, or
// if it still has some generics, it's not as useful.
self.generics
.params
.iter()
.all(|param| matches!(param.kind, GenericParamDefKind::Lifetime { .. }))
&& self.generics.where_predicates.is_empty()
&& self.type_.generics().is_some_and(|generics| !generics.is_empty())
}
}

#[derive(Clone, Debug)]
pub(crate) struct OpaqueTy {
pub(crate) bounds: Vec<GenericBound>,
Expand Down
143 changes: 51 additions & 92 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,104 +1237,63 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c

write!(w, "{}", document(cx, it, None, HeadingOffset::H2));

// Only show inner variants if:
// - the typealias does NOT have any generics (modulo lifetimes)
// - AND the aliased type has some generics
//
// Otherwise, showing a non-generic type is rendurant with its own page, or
// if it still has some generics, it's not as useful.
let should_print_inner_type = t
.generics
.params
.iter()
.all(|param| matches!(param.kind, clean::GenericParamDefKind::Lifetime { .. }))
&& t.generics.where_predicates.is_empty()
&& t.type_.generics().is_some_and(|generics| !generics.is_empty());

if should_print_inner_type {
fn toggle<W, F>(w: &mut W, f: F)
where
W: fmt::Write,
F: FnOnce(&mut W),
{
write!(
w,
"<details class=\"toggle\">\
<summary>\
<span>Show Aliased Type</span>\
</summary>",
)
.unwrap();
f(w);
write!(w, "</details>").unwrap();
}

match &t.inner_type {
Some(clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive }) => {
toggle(w, |w| {
let variants_iter = || variants.iter().filter(|i| !i.is_stripped());
wrap_item(w, |w| {
let variants_len = variants.len();
let variants_count = variants_iter().count();
let has_stripped_entries = variants_len != variants_count;

write!(w, "enum {}{}", it.name.unwrap(), t.generics.print(cx));
render_enum_fields(
w,
cx,
None,
variants_iter(),
variants_count,
has_stripped_entries,
*is_non_exhaustive,
)
});
item_variants(w, cx, it, variants_iter());
if let Some(inner_type) = &t.inner_type && t.should_display_inner_type() {
write!(
w,
"<h2 id=\"aliased-type\" class=\"small-section-header\">\
Aliased Type<a href=\"#aliased-type\" class=\"anchor\">§</a></h2>"
);

match inner_type {
clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => {
let variants_iter = || variants.iter().filter(|i| !i.is_stripped());
wrap_item(w, |w| {
let variants_len = variants.len();
let variants_count = variants_iter().count();
let has_stripped_entries = variants_len != variants_count;

write!(w, "enum {}{}", it.name.unwrap(), t.generics.print(cx));
render_enum_fields(
w,
cx,
None,
variants_iter(),
variants_count,
has_stripped_entries,
*is_non_exhaustive,
)
});
item_variants(w, cx, it, variants_iter());
}
Some(clean::TypeAliasInnerType::Union { fields }) => {
toggle(w, |w| {
wrap_item(w, |w| {
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
let has_stripped_fields = fields.len() != fields_count;

write!(w, "union {}{}", it.name.unwrap(), t.generics.print(cx));
render_struct_fields(
w,
None,
None,
fields,
"",
true,
has_stripped_fields,
cx,
);
});
item_fields(w, cx, it, fields, None);
clean::TypeAliasInnerType::Union { fields } => {
wrap_item(w, |w| {
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
let has_stripped_fields = fields.len() != fields_count;

write!(w, "union {}{}", it.name.unwrap(), t.generics.print(cx));
render_struct_fields(w, None, None, fields, "", true, has_stripped_fields, cx);
});
item_fields(w, cx, it, fields, None);
}
Some(clean::TypeAliasInnerType::Struct { ctor_kind, fields }) => {
toggle(w, |w| {
wrap_item(w, |w| {
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
let has_stripped_fields = fields.len() != fields_count;

write!(w, "struct {}{}", it.name.unwrap(), t.generics.print(cx));
render_struct_fields(
w,
None,
*ctor_kind,
fields,
"",
true,
has_stripped_fields,
cx,
);
});
item_fields(w, cx, it, fields, None);
clean::TypeAliasInnerType::Struct { ctor_kind, fields } => {
wrap_item(w, |w| {
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
let has_stripped_fields = fields.len() != fields_count;

write!(w, "struct {}{}", it.name.unwrap(), t.generics.print(cx));
render_struct_fields(
w,
None,
*ctor_kind,
fields,
"",
true,
has_stripped_fields,
cx,
);
});
item_fields(w, cx, it, fields, None);
}
None => {}
}
}

Expand Down
28 changes: 26 additions & 2 deletions src/librustdoc/html/render/sidebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
clean::PrimitiveItem(_) => sidebar_primitive(cx, it),
clean::UnionItem(ref u) => sidebar_union(cx, it, u),
clean::EnumItem(ref e) => sidebar_enum(cx, it, e),
clean::TypeAliasItem(_) => sidebar_type_alias(cx, it),
clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t),
clean::ModuleItem(ref m) => vec![sidebar_module(&m.items)],
clean::ForeignTypeItem => sidebar_foreign_type(cx, it),
_ => vec![],
Expand Down Expand Up @@ -230,8 +230,32 @@ fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBl
}
}

fn sidebar_type_alias<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
fn sidebar_type_alias<'a>(
cx: &'a Context<'_>,
it: &'a clean::Item,
t: &'a clean::TypeAlias,
) -> Vec<LinkBlock<'a>> {
let mut items = vec![];
if let Some(inner_type) = &t.inner_type && t.should_display_inner_type() {
match inner_type {
clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive: _ } => {
let mut variants = variants
.iter()
.filter(|i| !i.is_stripped())
.filter_map(|v| v.name)
.map(|name| Link::new(format!("variant.{name}"), name.to_string()))
.collect::<Vec<_>>();
variants.sort_unstable();

items.push(LinkBlock::new(Link::new("variants", "Variants"), variants));
}
clean::TypeAliasInnerType::Union { fields }
| clean::TypeAliasInnerType::Struct { ctor_kind: _, fields } => {
let fields = get_struct_fields_name(fields);
items.push(LinkBlock::new(Link::new("fields", "Fields"), fields));
}
}
}
sidebar_assoc_items(cx, it, &mut items);
items
}
Expand Down
26 changes: 16 additions & 10 deletions tests/rustdoc/typedef-inner-variants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ pub enum IrTyKind<A, I: Interner> {
pub type NearlyTyKind<A> = IrTyKind<A, TyCtxt>;

// @has 'inner_variants/type.TyKind.html'
// @count - '//*[@id="aliased-type"]' 1
// @count - '//*[@id="variants"]' 1
// @count - '//*[@id="fields"]' 0
// @count - '//*[@class="variant"]' 3
// @matches - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code' "enum TyKind"
// @has - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code/a[1]' "Adt"
// @has - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code/a[2]' "Adt"
// @has - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code/a[3]' "Ty"
// @has - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code/a[4]' "i64"
// @matches - '//pre[@class="rust item-decl"]//code' "enum TyKind"
// @has - '//pre[@class="rust item-decl"]//code/a[1]' "Adt"
// @has - '//pre[@class="rust item-decl"]//code/a[2]' "Adt"
// @has - '//pre[@class="rust item-decl"]//code/a[3]' "Ty"
// @has - '//pre[@class="rust item-decl"]//code/a[4]' "i64"
pub type TyKind = IrTyKind<i64, TyCtxt>;

// @has 'inner_variants/union.OneOr.html'
Expand All @@ -60,10 +61,11 @@ pub union OneOr<A: Copy> {
}

// @has 'inner_variants/type.OneOrF64.html'
// @count - '//*[@id="aliased-type"]' 1
// @count - '//*[@id="variants"]' 0
// @count - '//*[@id="fields"]' 1
// @count - '//*[@class="structfield small-section-header"]' 2
// @matches - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code' "union OneOrF64"
// @matches - '//pre[@class="rust item-decl"]//code' "union OneOrF64"
pub type OneOrF64 = OneOr<f64>;

// @has 'inner_variants/struct.One.html'
Expand All @@ -75,10 +77,12 @@ pub struct One<T> {
}

// @has 'inner_variants/type.OneU64.html'
// @count - '//*[@id="aliased-type"]' 1
// @count - '//*[@id="variants"]' 0
// @count - '//*[@id="fields"]' 1
// @count - '//*[@class="structfield small-section-header"]' 1
// @matches - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code' "struct OneU64"
// @matches - '//pre[@class="rust item-decl"]//code' "struct OneU64"
// @matches - '//pre[@class="rust item-decl"]//code' "pub val"
pub type OneU64 = One<u64>;

// @has 'inner_variants/struct.OnceA.html'
Expand All @@ -87,10 +91,11 @@ pub struct OnceA<'a, A> {
}

// @has 'inner_variants/type.Once.html'
// @count - '//*[@id="aliased-type"]' 1
// @count - '//*[@id="variants"]' 0
// @count - '//*[@id="fields"]' 1
// @matches - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code' "struct Once<'a>"
// @matches - '//details[@class="toggle"]//pre[@class="rust item-decl"]//code' "&'a"
// @matches - '//pre[@class="rust item-decl"]//code' "struct Once<'a>"
// @matches - '//pre[@class="rust item-decl"]//code' "&'a"
pub type Once<'a> = OnceA<'a, i64>;

// @has 'inner_variants/struct.HighlyGenericStruct.html'
Expand All @@ -100,12 +105,13 @@ pub struct HighlyGenericStruct<A, B, C, D> {

// VERIFY that we NOT show the Aliased Type
// @has 'inner_variants/type.HighlyGenericAABB.html'
// @count - '//details[@class="toggle"]' 0
// @count - '//*[@id="aliased-type"]' 1
// @count - '//*[@id="variants"]' 0
// @count - '//*[@id="fields"]' 0
pub type HighlyGenericAABB<A, B> = HighlyGenericStruct<A, A, B, B>;

// @has 'inner_variants/type.InlineU64.html'
// @count - '//*[@id="aliased-type"]' 1
// @count - '//*[@id="variants"]' 0
// @count - '//*[@id="fields"]' 1
pub use cross_crate_generic_typedef::InlineU64;

0 comments on commit 282acb9

Please sign in to comment.