Use the correct type for Enum variant tuples
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b6ff389..5b4a1a3 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1703,12 +1703,28 @@ fn clean(&self, cx: &mut DocContext<'_>) -> VariantStruct {
}
}
+impl Clean<Vec<Item>> for hir::VariantData<'_> {
+ fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
+ self.fields().iter().map(|x| x.clean(cx)).collect()
+ }
+}
+
impl Clean<Item> for ty::VariantDef {
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
let kind = match self.ctor_kind {
CtorKind::Const => Variant::CLike,
CtorKind::Fn => Variant::Tuple(
- self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect(),
+ self.fields
+ .iter()
+ .map(|field| {
+ let name = Some(field.ident.name);
+ let kind = StructFieldItem(cx.tcx.type_of(field.did).clean(cx));
+ let what_rustc_thinks =
+ Item::from_def_id_and_parts(field.did, name, kind, cx);
+ // don't show `pub` for fields, which are always public
+ Item { visibility: Visibility::Inherited, ..what_rustc_thinks }
+ })
+ .collect(),
),
CtorKind::Fictive => Variant::Struct(VariantStruct {
struct_type: CtorKind::Fictive,
@@ -1738,13 +1754,7 @@ impl Clean<Variant> for hir::VariantData<'_> {
fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
match self {
hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)),
- // Important note here: `Variant::Tuple` is used on tuple structs which are not in an
- // enum (so where converting from `ty::VariantDef`). In case we are in an enum, the kind
- // is provided by the `Variant` wrapper directly, and since we need the fields' name
- // (even for a tuple struct variant!), it's simpler to just store it as a
- // `Variant::Struct` instead of a `Variant::Tuple` (otherwise it would force us to make
- // a lot of changes when rendering them to generate the name as well).
- hir::VariantData::Tuple(..) => Variant::Struct(self.clean(cx)),
+ hir::VariantData::Tuple(..) => Variant::Tuple(self.clean(cx)),
hir::VariantData::Unit(..) => Variant::CLike,
}
}
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7025574..4194c99 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -715,6 +715,7 @@ impl ItemKind {
StructItem(s) => s.fields.iter(),
UnionItem(u) => u.fields.iter(),
VariantItem(Variant::Struct(v)) => v.fields.iter(),
+ VariantItem(Variant::Tuple(v)) => v.iter(),
EnumItem(e) => e.variants.iter(),
TraitItem(t) => t.items.iter(),
ImplItem(i) => i.items.iter(),
@@ -1937,7 +1938,7 @@ impl Visibility {
#[derive(Clone, Debug)]
crate enum Variant {
CLike,
- Tuple(Vec<Type>),
+ Tuple(Vec<Item>),
Struct(VariantStruct),
}
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 45aae71..b4859e4 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -56,6 +56,10 @@ fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind {
|| j.fields.iter().any(|f| f.is_stripped());
VariantItem(Variant::Struct(j))
}
+ Variant::Tuple(fields) => {
+ let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
+ VariantItem(Variant::Tuple(fields))
+ }
_ => VariantItem(i2),
}
}
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 8f4857a..722cfc9 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -937,6 +937,19 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
document_type_layout(w, cx, def_id);
}
+fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item]) {
+ for (i, ty) in s
+ .iter()
+ .map(|f| if let clean::StructFieldItem(ref ty) = *f.kind { ty } else { unreachable!() })
+ .enumerate()
+ {
+ if i > 0 {
+ w.write_str(", ");
+ }
+ write!(w, "{}", ty.print(cx));
+ }
+}
+
fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) {
wrap_into_docblock(w, |w| {
wrap_item(w, "enum", |w| {
@@ -964,14 +977,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
match *v.kind {
clean::VariantItem(ref var) => match var {
clean::Variant::CLike => write!(w, "{}", name),
- clean::Variant::Tuple(ref tys) => {
+ clean::Variant::Tuple(ref s) => {
write!(w, "{}(", name);
- for (i, ty) in tys.iter().enumerate() {
- if i > 0 {
- w.write_str(", ")
- }
- write!(w, "{}", ty.print(cx));
- }
+ print_tuple_struct_fields(w, cx, s);
w.write_str(")");
}
clean::Variant::Struct(ref s) => {
@@ -1024,14 +1032,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
id = id,
name = variant.name.as_ref().unwrap()
);
- if let clean::VariantItem(clean::Variant::Tuple(ref tys)) = *variant.kind {
+ if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
w.write_str("(");
- for (i, ty) in tys.iter().enumerate() {
- if i > 0 {
- w.write_str(", ");
- }
- write!(w, "{}", ty.print(cx));
- }
+ print_tuple_struct_fields(w, cx, s);
w.write_str(")");
}
w.write_str("</code>");
@@ -1041,7 +1044,11 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
document_non_exhaustive(w, variant);
use crate::clean::Variant;
- if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
+ if let Some((extra, fields)) = match *variant.kind {
+ clean::VariantItem(Variant::Struct(ref s)) => Some(("", &s.fields)),
+ clean::VariantItem(Variant::Tuple(ref fields)) => Some(("Tuple ", fields)),
+ _ => None,
+ } {
let variant_id = cx.derive_id(format!(
"{}.{}.fields",
ItemType::Variant,
@@ -1051,10 +1058,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
write!(
w,
"<h3>{extra}Fields of <b>{name}</b></h3><div>",
- extra = if s.struct_type == CtorKind::Fn { "Tuple " } else { "" },
+ extra = extra,
name = variant.name.as_ref().unwrap(),
);
- for field in &s.fields {
+ for field in fields {
use crate::clean::StructFieldItem;
if let StructFieldItem(ref ty) = *field.kind {
let id = cx.derive_id(format!(
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index f3eeea6..9453e6d 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -569,7 +569,18 @@ fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self {
use clean::Variant::*;
match variant {
CLike => Variant::Plain,
- Tuple(t) => Variant::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
+ Tuple(fields) => Variant::Tuple(
+ fields
+ .into_iter()
+ .map(|f| {
+ if let clean::StructFieldItem(ty) = *f.kind {
+ ty.into_tcx(tcx)
+ } else {
+ unreachable!()
+ }
+ })
+ .collect(),
+ ),
Struct(s) => Variant::Struct(ids(s.fields)),
}
}
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 4305268..a717c53 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -93,8 +93,8 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
// implementations of traits are always public.
clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
- // Struct variant fields have inherited visibility
- clean::VariantItem(clean::Variant::Struct(..)) => true,
+ // Variant fields have inherited visibility
+ clean::VariantItem(clean::Variant::Struct(..) | clean::Variant::Tuple(..)) => true,
_ => false,
};