Support unions in rustdoc
This commit is contained in:
parent
641d8e9e4c
commit
6792bd99fe
11 changed files with 204 additions and 8 deletions
|
@ -88,6 +88,11 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
ret.extend(build_impls(cx, tcx, did));
|
ret.extend(build_impls(cx, tcx, did));
|
||||||
clean::StructItem(build_struct(cx, tcx, did))
|
clean::StructItem(build_struct(cx, tcx, did))
|
||||||
}
|
}
|
||||||
|
Def::Union(did) => {
|
||||||
|
record_extern_fqn(cx, did, clean::TypeUnion);
|
||||||
|
ret.extend(build_impls(cx, tcx, did));
|
||||||
|
clean::UnionItem(build_union(cx, tcx, did))
|
||||||
|
}
|
||||||
Def::TyAlias(did) => {
|
Def::TyAlias(did) => {
|
||||||
record_extern_fqn(cx, did, clean::TypeTypedef);
|
record_extern_fqn(cx, did, clean::TypeTypedef);
|
||||||
ret.extend(build_impls(cx, tcx, did));
|
ret.extend(build_impls(cx, tcx, did));
|
||||||
|
@ -214,6 +219,20 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_union<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
did: DefId) -> clean::Union {
|
||||||
|
let t = tcx.lookup_item_type(did);
|
||||||
|
let predicates = tcx.lookup_predicates(did);
|
||||||
|
let variant = tcx.lookup_adt_def(did).struct_variant();
|
||||||
|
|
||||||
|
clean::Union {
|
||||||
|
struct_type: doctree::Plain,
|
||||||
|
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
|
||||||
|
fields: variant.fields.clean(cx),
|
||||||
|
fields_stripped: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
did: DefId) -> clean::ItemEnum {
|
did: DefId) -> clean::ItemEnum {
|
||||||
let t = tcx.lookup_item_type(did);
|
let t = tcx.lookup_item_type(did);
|
||||||
|
|
|
@ -321,6 +321,7 @@ impl Item {
|
||||||
pub fn has_stripped_fields(&self) -> Option<bool> {
|
pub fn has_stripped_fields(&self) -> Option<bool> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
StructItem(ref _struct) => Some(_struct.fields_stripped),
|
StructItem(ref _struct) => Some(_struct.fields_stripped),
|
||||||
|
UnionItem(ref union) => Some(union.fields_stripped),
|
||||||
VariantItem(Variant { kind: StructVariant(ref vstruct)} ) => {
|
VariantItem(Variant { kind: StructVariant(ref vstruct)} ) => {
|
||||||
Some(vstruct.fields_stripped)
|
Some(vstruct.fields_stripped)
|
||||||
},
|
},
|
||||||
|
@ -351,6 +352,7 @@ pub enum ItemEnum {
|
||||||
ExternCrateItem(String, Option<String>),
|
ExternCrateItem(String, Option<String>),
|
||||||
ImportItem(Import),
|
ImportItem(Import),
|
||||||
StructItem(Struct),
|
StructItem(Struct),
|
||||||
|
UnionItem(Union),
|
||||||
EnumItem(Enum),
|
EnumItem(Enum),
|
||||||
FunctionItem(Function),
|
FunctionItem(Function),
|
||||||
ModuleItem(Module),
|
ModuleItem(Module),
|
||||||
|
@ -414,6 +416,7 @@ impl Clean<Item> for doctree::Module {
|
||||||
items.extend(self.extern_crates.iter().map(|x| x.clean(cx)));
|
items.extend(self.extern_crates.iter().map(|x| x.clean(cx)));
|
||||||
items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
|
items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
|
||||||
items.extend(self.structs.iter().map(|x| x.clean(cx)));
|
items.extend(self.structs.iter().map(|x| x.clean(cx)));
|
||||||
|
items.extend(self.unions.iter().map(|x| x.clean(cx)));
|
||||||
items.extend(self.enums.iter().map(|x| x.clean(cx)));
|
items.extend(self.enums.iter().map(|x| x.clean(cx)));
|
||||||
items.extend(self.fns.iter().map(|x| x.clean(cx)));
|
items.extend(self.fns.iter().map(|x| x.clean(cx)));
|
||||||
items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
|
items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
|
||||||
|
@ -1464,6 +1467,7 @@ pub enum TypeKind {
|
||||||
TypeConst,
|
TypeConst,
|
||||||
TypeStatic,
|
TypeStatic,
|
||||||
TypeStruct,
|
TypeStruct,
|
||||||
|
TypeUnion,
|
||||||
TypeTrait,
|
TypeTrait,
|
||||||
TypeVariant,
|
TypeVariant,
|
||||||
TypeTypedef,
|
TypeTypedef,
|
||||||
|
@ -1801,12 +1805,13 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||||
decl: (cx.map.local_def_id(0), &fty.sig).clean(cx),
|
decl: (cx.map.local_def_id(0), &fty.sig).clean(cx),
|
||||||
abi: fty.abi,
|
abi: fty.abi,
|
||||||
}),
|
}),
|
||||||
ty::TyUnion(..) => unimplemented_unions!(),
|
|
||||||
ty::TyStruct(def, substs) |
|
ty::TyStruct(def, substs) |
|
||||||
|
ty::TyUnion(def, substs) |
|
||||||
ty::TyEnum(def, substs) => {
|
ty::TyEnum(def, substs) => {
|
||||||
let did = def.did;
|
let did = def.did;
|
||||||
let kind = match self.sty {
|
let kind = match self.sty {
|
||||||
ty::TyStruct(..) => TypeStruct,
|
ty::TyStruct(..) => TypeStruct,
|
||||||
|
ty::TyUnion(..) => TypeUnion,
|
||||||
_ => TypeEnum,
|
_ => TypeEnum,
|
||||||
};
|
};
|
||||||
inline::record_extern_fqn(cx, did, kind);
|
inline::record_extern_fqn(cx, did, kind);
|
||||||
|
@ -1929,6 +1934,14 @@ pub struct Struct {
|
||||||
pub fields_stripped: bool,
|
pub fields_stripped: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
|
pub struct Union {
|
||||||
|
pub struct_type: doctree::StructType,
|
||||||
|
pub generics: Generics,
|
||||||
|
pub fields: Vec<Item>,
|
||||||
|
pub fields_stripped: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl Clean<Item> for doctree::Struct {
|
impl Clean<Item> for doctree::Struct {
|
||||||
fn clean(&self, cx: &DocContext) -> Item {
|
fn clean(&self, cx: &DocContext) -> Item {
|
||||||
Item {
|
Item {
|
||||||
|
@ -1949,6 +1962,26 @@ impl Clean<Item> for doctree::Struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clean<Item> for doctree::Union {
|
||||||
|
fn clean(&self, cx: &DocContext) -> Item {
|
||||||
|
Item {
|
||||||
|
name: Some(self.name.clean(cx)),
|
||||||
|
attrs: self.attrs.clean(cx),
|
||||||
|
source: self.whence.clean(cx),
|
||||||
|
def_id: cx.map.local_def_id(self.id),
|
||||||
|
visibility: self.vis.clean(cx),
|
||||||
|
stability: self.stab.clean(cx),
|
||||||
|
deprecation: self.depr.clean(cx),
|
||||||
|
inner: UnionItem(Union {
|
||||||
|
struct_type: self.struct_type,
|
||||||
|
generics: self.generics.clean(cx),
|
||||||
|
fields: self.fields.clean(cx),
|
||||||
|
fields_stripped: false,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This is a more limited form of the standard Struct, different in that
|
/// This is a more limited form of the standard Struct, different in that
|
||||||
/// it lacks the things most items have (name, id, parameterization). Found
|
/// it lacks the things most items have (name, id, parameterization). Found
|
||||||
/// only as a variant in an enum.
|
/// only as a variant in an enum.
|
||||||
|
@ -2748,6 +2781,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
|
||||||
Def::Enum(i) => (i, TypeEnum),
|
Def::Enum(i) => (i, TypeEnum),
|
||||||
Def::Trait(i) => (i, TypeTrait),
|
Def::Trait(i) => (i, TypeTrait),
|
||||||
Def::Struct(i) => (i, TypeStruct),
|
Def::Struct(i) => (i, TypeStruct),
|
||||||
|
Def::Union(i) => (i, TypeUnion),
|
||||||
Def::Mod(i) => (i, TypeModule),
|
Def::Mod(i) => (i, TypeModule),
|
||||||
Def::Static(i, _) => (i, TypeStatic),
|
Def::Static(i, _) => (i, TypeStatic),
|
||||||
Def::Variant(i, _) => (i, TypeEnum),
|
Def::Variant(i, _) => (i, TypeEnum),
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub struct Module {
|
||||||
pub extern_crates: Vec<ExternCrate>,
|
pub extern_crates: Vec<ExternCrate>,
|
||||||
pub imports: Vec<Import>,
|
pub imports: Vec<Import>,
|
||||||
pub structs: Vec<Struct>,
|
pub structs: Vec<Struct>,
|
||||||
|
pub unions: Vec<Union>,
|
||||||
pub enums: Vec<Enum>,
|
pub enums: Vec<Enum>,
|
||||||
pub fns: Vec<Function>,
|
pub fns: Vec<Function>,
|
||||||
pub mods: Vec<Module>,
|
pub mods: Vec<Module>,
|
||||||
|
@ -62,6 +63,7 @@ impl Module {
|
||||||
extern_crates: Vec::new(),
|
extern_crates: Vec::new(),
|
||||||
imports : Vec::new(),
|
imports : Vec::new(),
|
||||||
structs : Vec::new(),
|
structs : Vec::new(),
|
||||||
|
unions : Vec::new(),
|
||||||
enums : Vec::new(),
|
enums : Vec::new(),
|
||||||
fns : Vec::new(),
|
fns : Vec::new(),
|
||||||
mods : Vec::new(),
|
mods : Vec::new(),
|
||||||
|
@ -108,6 +110,19 @@ pub struct Struct {
|
||||||
pub whence: Span,
|
pub whence: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Union {
|
||||||
|
pub vis: hir::Visibility,
|
||||||
|
pub stab: Option<attr::Stability>,
|
||||||
|
pub depr: Option<attr::Deprecation>,
|
||||||
|
pub id: NodeId,
|
||||||
|
pub struct_type: StructType,
|
||||||
|
pub name: Name,
|
||||||
|
pub generics: hir::Generics,
|
||||||
|
pub attrs: hir::HirVec<ast::Attribute>,
|
||||||
|
pub fields: hir::HirVec<hir::StructField>,
|
||||||
|
pub whence: Span,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Enum {
|
pub struct Enum {
|
||||||
pub vis: hir::Visibility,
|
pub vis: hir::Visibility,
|
||||||
pub stab: Option<attr::Stability>,
|
pub stab: Option<attr::Stability>,
|
||||||
|
|
|
@ -49,6 +49,13 @@ pub trait DocFolder : Sized {
|
||||||
i.fields.iter().any(|f| f.is_stripped());
|
i.fields.iter().any(|f| f.is_stripped());
|
||||||
StructItem(i)
|
StructItem(i)
|
||||||
},
|
},
|
||||||
|
UnionItem(mut i) => {
|
||||||
|
let num_fields = i.fields.len();
|
||||||
|
i.fields = i.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
|
||||||
|
i.fields_stripped |= num_fields != i.fields.len() ||
|
||||||
|
i.fields.iter().any(|f| f.is_stripped());
|
||||||
|
UnionItem(i)
|
||||||
|
},
|
||||||
EnumItem(mut i) => {
|
EnumItem(mut i) => {
|
||||||
let num_variants = i.variants.len();
|
let num_variants = i.variants.len();
|
||||||
i.variants = i.variants.into_iter().filter_map(|x| self.fold_item(x)).collect();
|
i.variants = i.variants.into_iter().filter_map(|x| self.fold_item(x)).collect();
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub enum ItemType {
|
||||||
AssociatedType = 16,
|
AssociatedType = 16,
|
||||||
Constant = 17,
|
Constant = 17,
|
||||||
AssociatedConst = 18,
|
AssociatedConst = 18,
|
||||||
|
Union = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
|
||||||
clean::ExternCrateItem(..) => ItemType::ExternCrate,
|
clean::ExternCrateItem(..) => ItemType::ExternCrate,
|
||||||
clean::ImportItem(..) => ItemType::Import,
|
clean::ImportItem(..) => ItemType::Import,
|
||||||
clean::StructItem(..) => ItemType::Struct,
|
clean::StructItem(..) => ItemType::Struct,
|
||||||
|
clean::UnionItem(..) => ItemType::Union,
|
||||||
clean::EnumItem(..) => ItemType::Enum,
|
clean::EnumItem(..) => ItemType::Enum,
|
||||||
clean::FunctionItem(..) => ItemType::Function,
|
clean::FunctionItem(..) => ItemType::Function,
|
||||||
clean::TypedefItem(..) => ItemType::Typedef,
|
clean::TypedefItem(..) => ItemType::Typedef,
|
||||||
|
@ -89,6 +91,7 @@ impl From<clean::TypeKind> for ItemType {
|
||||||
fn from(kind: clean::TypeKind) -> ItemType {
|
fn from(kind: clean::TypeKind) -> ItemType {
|
||||||
match kind {
|
match kind {
|
||||||
clean::TypeStruct => ItemType::Struct,
|
clean::TypeStruct => ItemType::Struct,
|
||||||
|
clean::TypeUnion => ItemType::Union,
|
||||||
clean::TypeEnum => ItemType::Enum,
|
clean::TypeEnum => ItemType::Enum,
|
||||||
clean::TypeFunction => ItemType::Function,
|
clean::TypeFunction => ItemType::Function,
|
||||||
clean::TypeTrait => ItemType::Trait,
|
clean::TypeTrait => ItemType::Trait,
|
||||||
|
@ -108,6 +111,7 @@ impl ItemType {
|
||||||
ItemType::ExternCrate => "externcrate",
|
ItemType::ExternCrate => "externcrate",
|
||||||
ItemType::Import => "import",
|
ItemType::Import => "import",
|
||||||
ItemType::Struct => "struct",
|
ItemType::Struct => "struct",
|
||||||
|
ItemType::Union => "union",
|
||||||
ItemType::Enum => "enum",
|
ItemType::Enum => "enum",
|
||||||
ItemType::Function => "fn",
|
ItemType::Function => "fn",
|
||||||
ItemType::Typedef => "type",
|
ItemType::Typedef => "type",
|
||||||
|
|
|
@ -1053,6 +1053,7 @@ impl DocFolder for Cache {
|
||||||
// information if present.
|
// information if present.
|
||||||
Some(&(ref fqp, ItemType::Trait)) |
|
Some(&(ref fqp, ItemType::Trait)) |
|
||||||
Some(&(ref fqp, ItemType::Struct)) |
|
Some(&(ref fqp, ItemType::Struct)) |
|
||||||
|
Some(&(ref fqp, ItemType::Union)) |
|
||||||
Some(&(ref fqp, ItemType::Enum)) =>
|
Some(&(ref fqp, ItemType::Enum)) =>
|
||||||
Some(&fqp[..fqp.len() - 1]),
|
Some(&fqp[..fqp.len() - 1]),
|
||||||
Some(..) => Some(&*self.stack),
|
Some(..) => Some(&*self.stack),
|
||||||
|
@ -1106,7 +1107,8 @@ impl DocFolder for Cache {
|
||||||
clean::TypedefItem(..) | clean::TraitItem(..) |
|
clean::TypedefItem(..) | clean::TraitItem(..) |
|
||||||
clean::FunctionItem(..) | clean::ModuleItem(..) |
|
clean::FunctionItem(..) | clean::ModuleItem(..) |
|
||||||
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
||||||
clean::ConstantItem(..) | clean::StaticItem(..)
|
clean::ConstantItem(..) | clean::StaticItem(..) |
|
||||||
|
clean::UnionItem(..)
|
||||||
if !self.stripped_mod => {
|
if !self.stripped_mod => {
|
||||||
// Reexported items mean that the same id can show up twice
|
// Reexported items mean that the same id can show up twice
|
||||||
// in the rustdoc ast that we're looking at. We know,
|
// in the rustdoc ast that we're looking at. We know,
|
||||||
|
@ -1141,7 +1143,8 @@ impl DocFolder for Cache {
|
||||||
// Maintain the parent stack
|
// Maintain the parent stack
|
||||||
let orig_parent_is_trait_impl = self.parent_is_trait_impl;
|
let orig_parent_is_trait_impl = self.parent_is_trait_impl;
|
||||||
let parent_pushed = match item.inner {
|
let parent_pushed = match item.inner {
|
||||||
clean::TraitItem(..) | clean::EnumItem(..) | clean::StructItem(..) => {
|
clean::TraitItem(..) | clean::EnumItem(..) |
|
||||||
|
clean::StructItem(..) | clean::UnionItem(..) => {
|
||||||
self.parent_stack.push(item.def_id);
|
self.parent_stack.push(item.def_id);
|
||||||
self.parent_is_trait_impl = false;
|
self.parent_is_trait_impl = false;
|
||||||
true
|
true
|
||||||
|
@ -1557,6 +1560,7 @@ impl<'a> fmt::Display for Item<'a> {
|
||||||
clean::FunctionItem(..) => write!(fmt, "Function ")?,
|
clean::FunctionItem(..) => write!(fmt, "Function ")?,
|
||||||
clean::TraitItem(..) => write!(fmt, "Trait ")?,
|
clean::TraitItem(..) => write!(fmt, "Trait ")?,
|
||||||
clean::StructItem(..) => write!(fmt, "Struct ")?,
|
clean::StructItem(..) => write!(fmt, "Struct ")?,
|
||||||
|
clean::UnionItem(..) => write!(fmt, "Union ")?,
|
||||||
clean::EnumItem(..) => write!(fmt, "Enum ")?,
|
clean::EnumItem(..) => write!(fmt, "Enum ")?,
|
||||||
clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
|
clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -1613,6 +1617,7 @@ impl<'a> fmt::Display for Item<'a> {
|
||||||
item_function(fmt, self.cx, self.item, f),
|
item_function(fmt, self.cx, self.item, f),
|
||||||
clean::TraitItem(ref t) => item_trait(fmt, self.cx, self.item, t),
|
clean::TraitItem(ref t) => item_trait(fmt, self.cx, self.item, t),
|
||||||
clean::StructItem(ref s) => item_struct(fmt, self.cx, self.item, s),
|
clean::StructItem(ref s) => item_struct(fmt, self.cx, self.item, s),
|
||||||
|
clean::UnionItem(ref s) => item_union(fmt, self.cx, self.item, s),
|
||||||
clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e),
|
clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e),
|
||||||
clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t),
|
clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t),
|
||||||
clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m),
|
clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m),
|
||||||
|
@ -1715,7 +1720,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
ItemType::Trait => 9,
|
ItemType::Trait => 9,
|
||||||
ItemType::Function => 10,
|
ItemType::Function => 10,
|
||||||
ItemType::Typedef => 12,
|
ItemType::Typedef => 12,
|
||||||
_ => 13 + ty as u8,
|
ItemType::Union => 13,
|
||||||
|
_ => 14 + ty as u8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1759,6 +1765,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
ItemType::Import => ("reexports", "Reexports"),
|
ItemType::Import => ("reexports", "Reexports"),
|
||||||
ItemType::Module => ("modules", "Modules"),
|
ItemType::Module => ("modules", "Modules"),
|
||||||
ItemType::Struct => ("structs", "Structs"),
|
ItemType::Struct => ("structs", "Structs"),
|
||||||
|
ItemType::Union => ("unions", "Unions"),
|
||||||
ItemType::Enum => ("enums", "Enums"),
|
ItemType::Enum => ("enums", "Enums"),
|
||||||
ItemType::Function => ("functions", "Functions"),
|
ItemType::Function => ("functions", "Functions"),
|
||||||
ItemType::Typedef => ("types", "Type Definitions"),
|
ItemType::Typedef => ("types", "Type Definitions"),
|
||||||
|
@ -2312,6 +2319,40 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
|
s: &clean::Union) -> fmt::Result {
|
||||||
|
write!(w, "<pre class='rust union'>")?;
|
||||||
|
render_attributes(w, it)?;
|
||||||
|
render_union(w,
|
||||||
|
it,
|
||||||
|
Some(&s.generics),
|
||||||
|
&s.fields,
|
||||||
|
"",
|
||||||
|
true)?;
|
||||||
|
write!(w, "</pre>")?;
|
||||||
|
|
||||||
|
document(w, cx, it)?;
|
||||||
|
let mut fields = s.fields.iter().filter_map(|f| {
|
||||||
|
match f.inner {
|
||||||
|
clean::StructFieldItem(ref ty) => Some((f, ty)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}).peekable();
|
||||||
|
if fields.peek().is_some() {
|
||||||
|
write!(w, "<h2 class='fields'>Fields</h2>")?;
|
||||||
|
for (field, ty) in fields {
|
||||||
|
write!(w, "<span id='{shortty}.{name}' class='{shortty}'><code>{name}: {ty}</code>
|
||||||
|
</span><span class='stab {stab}'></span>",
|
||||||
|
shortty = ItemType::StructField,
|
||||||
|
stab = field.stability_class(),
|
||||||
|
name = field.name.as_ref().unwrap(),
|
||||||
|
ty = ty)?;
|
||||||
|
document(w, cx, field)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
|
||||||
|
}
|
||||||
|
|
||||||
fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
||||||
e: &clean::Enum) -> fmt::Result {
|
e: &clean::Enum) -> fmt::Result {
|
||||||
write!(w, "<pre class='rust enum'>")?;
|
write!(w, "<pre class='rust enum'>")?;
|
||||||
|
@ -2514,6 +2555,40 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_union(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
|
g: Option<&clean::Generics>,
|
||||||
|
fields: &[clean::Item],
|
||||||
|
tab: &str,
|
||||||
|
structhead: bool) -> fmt::Result {
|
||||||
|
write!(w, "{}{}{}",
|
||||||
|
VisSpace(&it.visibility),
|
||||||
|
if structhead {"union "} else {""},
|
||||||
|
it.name.as_ref().unwrap())?;
|
||||||
|
if let Some(g) = g {
|
||||||
|
write!(w, "{}", g)?
|
||||||
|
}
|
||||||
|
if let Some(g) = g {
|
||||||
|
write!(w, "{}", WhereClause(g))?
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(w, " {{\n{}", tab)?;
|
||||||
|
for field in fields {
|
||||||
|
if let clean::StructFieldItem(ref ty) = field.inner {
|
||||||
|
write!(w, " {}{}: {},\n{}",
|
||||||
|
VisSpace(&field.visibility),
|
||||||
|
field.name.as_ref().unwrap(),
|
||||||
|
*ty,
|
||||||
|
tab)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if it.has_stripped_fields().unwrap() {
|
||||||
|
write!(w, " // some fields omitted\n{}", tab)?;
|
||||||
|
}
|
||||||
|
write!(w, "}}")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
enum AssocItemLink<'a> {
|
enum AssocItemLink<'a> {
|
||||||
Anchor(Option<&'a str>),
|
Anchor(Option<&'a str>),
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
"primitive",
|
"primitive",
|
||||||
"associatedtype",
|
"associatedtype",
|
||||||
"constant",
|
"constant",
|
||||||
"associatedconstant"];
|
"associatedconstant",
|
||||||
|
"union"];
|
||||||
|
|
||||||
// used for special search precedence
|
// used for special search precedence
|
||||||
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
|
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
||||||
clean::TraitItem(..) | clean::FunctionItem(..) |
|
clean::TraitItem(..) | clean::FunctionItem(..) |
|
||||||
clean::VariantItem(..) | clean::MethodItem(..) |
|
clean::VariantItem(..) | clean::MethodItem(..) |
|
||||||
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
||||||
clean::ConstantItem(..) => {
|
clean::ConstantItem(..) | clean::UnionItem(..) => {
|
||||||
if i.def_id.is_local() {
|
if i.def_id.is_local() {
|
||||||
if !self.access_levels.is_exported(i.def_id) {
|
if !self.access_levels.is_exported(i.def_id) {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -108,6 +108,25 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn visit_union_data(&mut self, item: &hir::Item,
|
||||||
|
name: ast::Name, sd: &hir::VariantData,
|
||||||
|
generics: &hir::Generics) -> Union {
|
||||||
|
debug!("Visiting union");
|
||||||
|
let struct_type = struct_type_from_def(&*sd);
|
||||||
|
Union {
|
||||||
|
id: item.id,
|
||||||
|
struct_type: struct_type,
|
||||||
|
name: name,
|
||||||
|
vis: item.vis.clone(),
|
||||||
|
stab: self.stability(item.id),
|
||||||
|
depr: self.deprecation(item.id),
|
||||||
|
attrs: item.attrs.clone(),
|
||||||
|
generics: generics.clone(),
|
||||||
|
fields: sd.fields().iter().cloned().collect(),
|
||||||
|
whence: item.span
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn visit_enum_def(&mut self, it: &hir::Item,
|
pub fn visit_enum_def(&mut self, it: &hir::Item,
|
||||||
name: ast::Name, def: &hir::EnumDef,
|
name: ast::Name, def: &hir::EnumDef,
|
||||||
params: &hir::Generics) -> Enum {
|
params: &hir::Generics) -> Enum {
|
||||||
|
@ -258,6 +277,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
match def {
|
match def {
|
||||||
Def::Trait(did) |
|
Def::Trait(did) |
|
||||||
Def::Struct(did) |
|
Def::Struct(did) |
|
||||||
|
Def::Union(did) |
|
||||||
Def::Enum(did) |
|
Def::Enum(did) |
|
||||||
Def::TyAlias(did) if !self_is_hidden => {
|
Def::TyAlias(did) if !self_is_hidden => {
|
||||||
self.cx.access_levels.borrow_mut().map.insert(did, AccessLevel::Public);
|
self.cx.access_levels.borrow_mut().map.insert(did, AccessLevel::Public);
|
||||||
|
@ -365,8 +385,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
om.enums.push(self.visit_enum_def(item, name, ed, gen)),
|
om.enums.push(self.visit_enum_def(item, name, ed, gen)),
|
||||||
hir::ItemStruct(ref sd, ref gen) =>
|
hir::ItemStruct(ref sd, ref gen) =>
|
||||||
om.structs.push(self.visit_variant_data(item, name, sd, gen)),
|
om.structs.push(self.visit_variant_data(item, name, sd, gen)),
|
||||||
hir::ItemUnion(..) =>
|
hir::ItemUnion(ref sd, ref gen) =>
|
||||||
unimplemented_unions!(),
|
om.unions.push(self.visit_union_data(item, name, sd, gen)),
|
||||||
hir::ItemFn(ref fd, ref unsafety, constness, ref abi, ref gen, _) =>
|
hir::ItemFn(ref fd, ref unsafety, constness, ref abi, ref gen, _) =>
|
||||||
om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
|
om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
|
||||||
constness, abi, gen)),
|
constness, abi, gen)),
|
||||||
|
|
|
@ -73,6 +73,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
|
||||||
Def::ForeignMod(did) |
|
Def::ForeignMod(did) |
|
||||||
Def::Trait(did) |
|
Def::Trait(did) |
|
||||||
Def::Struct(did) |
|
Def::Struct(did) |
|
||||||
|
Def::Union(did) |
|
||||||
Def::Enum(did) |
|
Def::Enum(did) |
|
||||||
Def::TyAlias(did) |
|
Def::TyAlias(did) |
|
||||||
Def::Fn(did) |
|
Def::Fn(did) |
|
||||||
|
|
20
src/test/rustdoc/union.rs
Normal file
20
src/test/rustdoc/union.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(untagged_unions)]
|
||||||
|
|
||||||
|
// @has union/union.U.html
|
||||||
|
pub union U {
|
||||||
|
// @has - //pre "pub a: u8"
|
||||||
|
pub a: u8,
|
||||||
|
// @has - //pre "// some fields omitted"
|
||||||
|
// @!has - //pre "b: u16"
|
||||||
|
b: u16,
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue