Skip to content

Commit 560aec1

Browse files
Unify rendering of type aliases without ADT items
1 parent 5f857a9 commit 560aec1

File tree

3 files changed

+151
-137
lines changed

3 files changed

+151
-137
lines changed

src/librustdoc/clean/types.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ impl Item {
610610
UnionItem(ref union_) => Some(union_.has_stripped_entries()),
611611
EnumItem(ref enum_) => Some(enum_.has_stripped_entries()),
612612
VariantItem(ref v) => v.has_stripped_entries(),
613+
TypeAliasItem(ref type_alias) => {
614+
type_alias.inner_type.as_ref().and_then(|t| t.has_stripped_entries())
615+
}
613616
_ => None,
614617
}
615618
}
@@ -2345,6 +2348,16 @@ pub(crate) enum TypeAliasInnerType {
23452348
Struct { ctor_kind: Option<CtorKind>, fields: Vec<Item> },
23462349
}
23472350

2351+
impl TypeAliasInnerType {
2352+
fn has_stripped_entries(&self) -> Option<bool> {
2353+
Some(match self {
2354+
Self::Enum { variants, .. } => variants.iter().any(|v| v.is_stripped()),
2355+
Self::Union { fields } => fields.iter().any(|f| f.is_stripped()),
2356+
Self::Struct { fields, .. } => fields.iter().any(|f| f.is_stripped()),
2357+
})
2358+
}
2359+
}
2360+
23482361
#[derive(Clone, Debug)]
23492362
pub(crate) struct TypeAlias {
23502363
pub(crate) type_: Type,

src/librustdoc/html/render/print_item.rs

Lines changed: 134 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,94 +1278,40 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) ->
12781278

12791279
match inner_type {
12801280
clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => {
1281-
let variants_iter = || variants.iter().filter(|i| !i.is_stripped());
12821281
let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity();
12831282
let enum_def_id = ty.ty_adt_def().unwrap().did();
12841283

1285-
wrap_item(w, |w| {
1286-
let variants_len = variants.len();
1287-
let variants_count = variants_iter().count();
1288-
let has_stripped_entries = variants_len != variants_count;
1289-
1290-
write!(
1291-
w,
1292-
"enum {}{}{}",
1293-
it.name.unwrap(),
1294-
t.generics.print(cx),
1295-
render_enum_fields(
1296-
cx,
1297-
Some(&t.generics),
1298-
variants,
1299-
variants_count,
1300-
has_stripped_entries,
1301-
*is_non_exhaustive,
1302-
enum_def_id,
1303-
)
1304-
)
1305-
})?;
1306-
write!(w, "{}", item_variants(cx, it, variants, enum_def_id))?;
1284+
DisplayEnum {
1285+
variants,
1286+
generics: &t.generics,
1287+
is_non_exhaustive: *is_non_exhaustive,
1288+
def_id: enum_def_id,
1289+
}
1290+
.render_into(cx, it, false, w)?;
13071291
}
13081292
clean::TypeAliasInnerType::Union { fields } => {
1309-
wrap_item(w, |w| {
1310-
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
1311-
let has_stripped_fields = fields.len() != fields_count;
1312-
1313-
write!(
1314-
w,
1315-
"union {}{}{}",
1316-
it.name.unwrap(),
1317-
t.generics.print(cx),
1318-
render_struct_fields(
1319-
Some(&t.generics),
1320-
None,
1321-
fields,
1322-
"",
1323-
true,
1324-
has_stripped_fields,
1325-
cx,
1326-
),
1327-
)
1328-
})?;
1329-
write!(w, "{}", item_fields(cx, it, fields, None))?;
1293+
ItemUnion { cx, it, fields, generics: &t.generics, document_union: false }
1294+
.render_into(w)?;
13301295
}
13311296
clean::TypeAliasInnerType::Struct { ctor_kind, fields } => {
1332-
wrap_item(w, |w| {
1333-
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
1334-
let has_stripped_fields = fields.len() != fields_count;
1335-
1336-
write!(
1337-
w,
1338-
"struct {}{}{}",
1339-
it.name.unwrap(),
1340-
t.generics.print(cx),
1341-
render_struct_fields(
1342-
Some(&t.generics),
1343-
*ctor_kind,
1344-
fields,
1345-
"",
1346-
true,
1347-
has_stripped_fields,
1348-
cx,
1349-
),
1350-
)
1351-
})?;
1352-
write!(w, "{}", item_fields(cx, it, fields, None))?;
1297+
DisplayStruct { ctor_kind: *ctor_kind, generics: &t.generics, fields }
1298+
.render_into(cx, it, false, w)?;
13531299
}
13541300
}
1301+
} else {
1302+
let def_id = it.item_id.expect_def_id();
1303+
// Render any items associated directly to this alias, as otherwise they
1304+
// won't be visible anywhere in the docs. It would be nice to also show
1305+
// associated items from the aliased type (see discussion in #32077), but
1306+
// we need #14072 to make sense of the generics.
1307+
write!(
1308+
w,
1309+
"{}{}",
1310+
render_assoc_items(cx, it, def_id, AssocItemRender::All),
1311+
document_type_layout(cx, def_id)
1312+
)?;
13551313
}
13561314

1357-
let def_id = it.item_id.expect_def_id();
1358-
// Render any items associated directly to this alias, as otherwise they
1359-
// won't be visible anywhere in the docs. It would be nice to also show
1360-
// associated items from the aliased type (see discussion in #32077), but
1361-
// we need #14072 to make sense of the generics.
1362-
write!(
1363-
w,
1364-
"{}{}",
1365-
render_assoc_items(cx, it, def_id, AssocItemRender::All),
1366-
document_type_layout(cx, def_id)
1367-
)?;
1368-
13691315
// [RUSTDOCIMPL] type.impl
13701316
//
13711317
// Include type definitions from the alias target type.
@@ -1463,50 +1409,53 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) ->
14631409
})
14641410
}
14651411

1466-
fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display {
1467-
item_template!(
1468-
#[template(path = "item_union.html")]
1469-
struct ItemUnion<'a, 'cx> {
1470-
cx: &'a Context<'cx>,
1471-
it: &'a clean::Item,
1472-
s: &'a clean::Union,
1473-
},
1474-
methods = [document, document_type_layout, render_attributes_in_pre, render_assoc_items]
1475-
);
1476-
1477-
impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
1478-
fn render_union(&self) -> impl Display {
1479-
render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx)
1480-
}
1412+
item_template!(
1413+
#[template(path = "item_union.html")]
1414+
struct ItemUnion<'a, 'cx> {
1415+
cx: &'a Context<'cx>,
1416+
it: &'a clean::Item,
1417+
fields: &'a [clean::Item],
1418+
generics: &'a clean::Generics,
1419+
document_union: bool,
1420+
},
1421+
methods = [document, document_type_layout, render_attributes_in_pre, render_assoc_items]
1422+
);
1423+
1424+
impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
1425+
fn render_union(&self) -> impl Display {
1426+
render_union(self.it, Some(&self.generics), &self.fields, self.cx)
1427+
}
14811428

1482-
fn document_field(&self, field: &'a clean::Item) -> impl Display {
1483-
document(self.cx, field, Some(self.it), HeadingOffset::H3)
1484-
}
1429+
fn document_field(&self, field: &'a clean::Item) -> impl Display {
1430+
document(self.cx, field, Some(self.it), HeadingOffset::H3)
1431+
}
14851432

1486-
fn stability_field(&self, field: &clean::Item) -> Option<String> {
1487-
field.stability_class(self.cx.tcx())
1488-
}
1433+
fn stability_field(&self, field: &clean::Item) -> Option<String> {
1434+
field.stability_class(self.cx.tcx())
1435+
}
14891436

1490-
fn print_ty(&self, ty: &'a clean::Type) -> impl Display {
1491-
ty.print(self.cx)
1492-
}
1437+
fn print_ty(&self, ty: &'a clean::Type) -> impl Display {
1438+
ty.print(self.cx)
1439+
}
14931440

1494-
fn fields_iter(
1495-
&self,
1496-
) -> iter::Peekable<impl Iterator<Item = (&'a clean::Item, &'a clean::Type)>> {
1497-
self.s
1498-
.fields
1499-
.iter()
1500-
.filter_map(|f| match f.kind {
1501-
clean::StructFieldItem(ref ty) => Some((f, ty)),
1502-
_ => None,
1503-
})
1504-
.peekable()
1505-
}
1441+
fn fields_iter(
1442+
&self,
1443+
) -> iter::Peekable<impl Iterator<Item = (&'a clean::Item, &'a clean::Type)>> {
1444+
self.fields
1445+
.iter()
1446+
.filter_map(|f| match f.kind {
1447+
clean::StructFieldItem(ref ty) => Some((f, ty)),
1448+
_ => None,
1449+
})
1450+
.peekable()
15061451
}
1452+
}
15071453

1454+
fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display {
15081455
fmt::from_fn(|w| {
1509-
ItemUnion { cx, it, s }.render_into(w).unwrap();
1456+
ItemUnion { cx, it, fields: &s.fields, generics: &s.generics, document_union: true }
1457+
.render_into(w)
1458+
.unwrap();
15101459
Ok(())
15111460
})
15121461
}
@@ -1533,33 +1482,51 @@ fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Displa
15331482
})
15341483
}
15351484

1536-
fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display {
1537-
fmt::from_fn(|w| {
1538-
let count_variants = e.non_stripped_variants().count();
1485+
struct DisplayEnum<'a> {
1486+
variants: &'a IndexVec<VariantIdx, clean::Item>,
1487+
generics: &'a clean::Generics,
1488+
is_non_exhaustive: bool,
1489+
def_id: DefId,
1490+
}
1491+
1492+
impl<'a> DisplayEnum<'a> {
1493+
fn render_into<W: fmt::Write>(
1494+
self,
1495+
cx: &Context<'_>,
1496+
it: &clean::Item,
1497+
document_enum: bool,
1498+
w: &mut W,
1499+
) -> fmt::Result {
1500+
let variants_count = self.variants.iter().filter(|i| !i.is_stripped()).count();
1501+
let variants_len = self.variants.len();
1502+
let has_stripped_entries = variants_len != variants_count;
1503+
15391504
wrap_item(w, |w| {
15401505
render_attributes_in_code(w, it, cx);
15411506
write!(
15421507
w,
15431508
"{}enum {}{}{}",
15441509
visibility_print_with_space(it, cx),
15451510
it.name.unwrap(),
1546-
e.generics.print(cx),
1511+
self.generics.print(cx),
15471512
render_enum_fields(
15481513
cx,
1549-
Some(&e.generics),
1550-
&e.variants,
1551-
count_variants,
1552-
e.has_stripped_entries(),
1553-
it.is_non_exhaustive(),
1554-
it.def_id().unwrap(),
1514+
Some(self.generics),
1515+
self.variants,
1516+
variants_count,
1517+
has_stripped_entries,
1518+
self.is_non_exhaustive,
1519+
self.def_id,
15551520
),
15561521
)
15571522
})?;
15581523

1559-
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
1524+
if document_enum {
1525+
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
1526+
}
15601527

1561-
if count_variants != 0 {
1562-
write!(w, "{}", item_variants(cx, it, &e.variants, it.def_id().unwrap()))?;
1528+
if variants_count != 0 {
1529+
write!(w, "{}", item_variants(cx, it, self.variants, self.def_id))?;
15631530
}
15641531
let def_id = it.item_id.expect_def_id();
15651532
write!(
@@ -1568,6 +1535,18 @@ fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::D
15681535
render_assoc_items(cx, it, def_id, AssocItemRender::All),
15691536
document_type_layout(cx, def_id)
15701537
)
1538+
}
1539+
}
1540+
1541+
fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display {
1542+
fmt::from_fn(|w| {
1543+
DisplayEnum {
1544+
variants: &e.variants,
1545+
generics: &e.generics,
1546+
is_non_exhaustive: it.is_non_exhaustive(),
1547+
def_id: it.def_id().unwrap(),
1548+
}
1549+
.render_into(cx, it, true, w)
15711550
})
15721551
}
15731552

@@ -1955,27 +1934,48 @@ fn item_constant(
19551934
})
19561935
}
19571936

1958-
fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display {
1959-
fmt::from_fn(|w| {
1937+
struct DisplayStruct<'a> {
1938+
ctor_kind: Option<CtorKind>,
1939+
generics: &'a clean::Generics,
1940+
fields: &'a [clean::Item],
1941+
}
1942+
1943+
impl<'a> DisplayStruct<'a> {
1944+
fn render_into<W: fmt::Write>(
1945+
self,
1946+
cx: &Context<'_>,
1947+
it: &clean::Item,
1948+
document_struct: bool,
1949+
w: &mut W,
1950+
) -> fmt::Result {
19601951
wrap_item(w, |w| {
19611952
render_attributes_in_code(w, it, cx);
19621953
write!(
19631954
w,
19641955
"{}",
1965-
render_struct(it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx)
1956+
render_struct(it, Some(self.generics), self.ctor_kind, self.fields, "", true, cx)
19661957
)
19671958
})?;
19681959

1969-
let def_id = it.item_id.expect_def_id();
1960+
if document_struct {
1961+
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
1962+
}
19701963

1964+
let def_id = it.item_id.expect_def_id();
19711965
write!(
19721966
w,
1973-
"{}{}{}{}",
1974-
document(cx, it, None, HeadingOffset::H2),
1975-
item_fields(cx, it, &s.fields, s.ctor_kind),
1967+
"{}{}{}",
1968+
item_fields(cx, it, self.fields, self.ctor_kind),
19761969
render_assoc_items(cx, it, def_id, AssocItemRender::All),
19771970
document_type_layout(cx, def_id),
19781971
)
1972+
}
1973+
}
1974+
1975+
fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display {
1976+
fmt::from_fn(|w| {
1977+
DisplayStruct { ctor_kind: s.ctor_kind, generics: &s.generics, fields: s.fields.as_slice() }
1978+
.render_into(cx, it, true, w)
19791979
})
19801980
}
19811981

src/librustdoc/html/templates/item_union.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
{{ self.render_attributes_in_pre()|safe }}
33
{{ self.render_union()|safe }}
44
</code></pre>
5-
{{ self.document()|safe }}
5+
{% if self.document_union %}
6+
{{ self.document()|safe }}
7+
{% endif %}
68
{% if self.fields_iter().peek().is_some() %}
79
<h2 id="fields" class="fields section-header"> {# #}
810
Fields<a href="#fields" class="anchor">§</a> {# #}
911
</h2>
1012
{% for (field, ty) in self.fields_iter() %}
1113
{% let name = field.name.expect("union field name") %}
12-
<span id="structfield.{{ name }}" {#+ #}
13-
class="{{ ItemType::StructField +}} section-header"> {# #}
14+
<span id="structfield.{{ name }}" class="{{ ItemType::StructField +}} section-header"> {# #}
1415
<a href="#structfield.{{ name }}" class="anchor field">§</a> {# #}
1516
<code>{{ name }}: {{+ self.print_ty(ty)|safe }}</code> {# #}
1617
</span>

0 commit comments

Comments
 (0)