about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-10-08 23:45:46 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-10-13 15:19:25 +0300
commit40aa09e4c9f4c3f0fa2b088895c8f5125325eaa4 (patch)
tree0ea29987683fbd21b30e2bc23769517a7984a116
parent30af54dede8b9f03a83dd5ad588bb430a5a76270 (diff)
downloadrust-40aa09e4c9f4c3f0fa2b088895c8f5125325eaa4.tar.gz
rust-40aa09e4c9f4c3f0fa2b088895c8f5125325eaa4.zip
Merge struct fields and struct kind
-rw-r--r--src/librustc/front/map/collector.rs6
-rw-r--r--src/librustc/front/map/mod.rs7
-rw-r--r--src/librustc/metadata/encoder.rs6
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/dead.rs4
-rw-r--r--src/librustc/middle/stability.rs2
-rw-r--r--src/librustc_front/fold.rs13
-rw-r--r--src/librustc_front/hir.rs36
-rw-r--r--src/librustc_front/lowering.rs13
-rw-r--r--src/librustc_front/print/pprust.rs10
-rw-r--r--src/librustc_front/visit.rs2
-rw-r--r--src/librustc_lint/bad_style.rs2
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_privacy/lib.rs10
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs24
-rw-r--r--src/librustc_trans/save/dump_csv.rs4
-rw-r--r--src/librustc_trans/trans/base.rs17
-rw-r--r--src/librustc_trans/trans/callee.rs2
-rw-r--r--src/librustc_trans/trans/inline.rs13
-rw-r--r--src/librustc_trans/trans/monomorphize.rs2
-rw-r--r--src/librustc_typeck/check/wf.rs3
-rw-r--r--src/librustc_typeck/check/wfcheck.rs3
-rw-r--r--src/librustc_typeck/collect.rs10
-rw-r--r--src/librustdoc/clean/mod.rs8
-rw-r--r--src/librustdoc/doctree.rs4
-rw-r--r--src/librustdoc/visit_ast.rs2
-rw-r--r--src/libsyntax/ast.rs36
-rw-r--r--src/libsyntax/config.rs19
-rw-r--r--src/libsyntax/ext/build.rs11
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs10
-rw-r--r--src/libsyntax/ext/deriving/primitive.rs2
-rw-r--r--src/libsyntax/feature_gate.rs6
-rw-r--r--src/libsyntax/fold.rs13
-rw-r--r--src/libsyntax/parse/parser.rs37
-rw-r--r--src/libsyntax/print/pprust.rs27
-rw-r--r--src/libsyntax/visit.rs2
36 files changed, 222 insertions, 148 deletions
diff --git a/src/librustc/front/map/collector.rs b/src/librustc/front/map/collector.rs
index a3542ff9b10..aa5d482b89a 100644
--- a/src/librustc/front/map/collector.rs
+++ b/src/librustc/front/map/collector.rs
@@ -138,7 +138,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
                                         NodeVariant(&**v),
                                         DefPathData::EnumVariant(v.node.name));
 
-                    for field in &v.node.data.fields {
+                    for field in v.node.data.fields() {
                         self.create_def_with_parent(
                             Some(variant_def_index),
                             field.node.id,
@@ -150,13 +150,13 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
             }
             ItemStruct(ref struct_def, _) => {
                 // If this is a tuple-like struct, register the constructor.
-                if struct_def.kind != VariantKind::Struct {
+                if !struct_def.is_struct() {
                     self.insert_def(struct_def.id,
                                     NodeStructCtor(&**struct_def),
                                     DefPathData::StructCtor);
                 }
 
-                for field in &struct_def.fields {
+                for field in struct_def.fields() {
                     self.create_def(field.node.id, DefPathData::Field(field.node.kind));
                 }
             }
diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs
index 1e31bfe9aca..028e1ad5ce9 100644
--- a/src/librustc/front/map/mod.rs
+++ b/src/librustc/front/map/mod.rs
@@ -480,9 +480,10 @@ impl<'ast> Map<'ast> {
                 }
             }
             Some(NodeVariant(variant)) => {
-                match variant.node.data.kind {
-                    VariantKind::Struct => &variant.node.data,
-                    _ => panic!("struct ID bound to enum variant that isn't struct-like"),
+                if variant.node.data.is_struct() {
+                    &variant.node.data
+                } else {
+                    panic!("struct ID bound to enum variant that isn't struct-like")
                 }
             }
             _ => panic!(format!("expected struct, found {}", self.node_to_string(id))),
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 2bee3f296c9..81305099705 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -381,7 +381,7 @@ fn each_auxiliary_node_id<F>(item: &hir::Item, callback: F) -> bool where
     match item.node {
         hir::ItemStruct(ref struct_def, _) => {
             // If this is a newtype struct, return the constructor.
-            if struct_def.kind == hir::VariantKind::Tuple {
+            if struct_def.is_tuple() {
                 continue_ = callback(struct_def.id);
             }
         }
@@ -1068,7 +1068,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         // Encode inherent implementations for this structure.
         encode_inherent_implementations(ecx, rbml_w, def_id);
 
-        if struct_def.kind != hir::VariantKind::Struct {
+        if !struct_def.is_struct() {
             let ctor_did = ecx.tcx.map.local_def_id(struct_def.id);
             rbml_w.wr_tagged_u64(tag_items_data_item_struct_ctor,
                                  def_to_u64(ctor_did));
@@ -1081,7 +1081,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         }
 
         // If this is a tuple-like struct, encode the type of the constructor.
-        if struct_def.kind != hir::VariantKind::Struct {
+        if !struct_def.is_struct() {
             encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def.id, index, item.id);
         }
       }
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 9bf70cce602..ca05de81e77 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -1320,7 +1320,7 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) {
                 }
             }
             hir::ItemStruct(ref def, _) => {
-                if def.kind != hir::VariantKind::Struct {
+                if !def.is_struct() {
                     let ctor_did = dcx.tcx.lookup_adt_def(orig_did)
                         .struct_variant().did;
                     debug!("astencode: copying ctor {:?} => {:?}", ctor_did,
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index d0d6cf39af7..9d15b53a6d8 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -219,7 +219,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
                         _: &hir::Generics, _: ast::NodeId, _: codemap::Span) {
         let has_extern_repr = self.struct_has_extern_repr;
         let inherited_pub_visibility = self.inherited_pub_visibility;
-        let live_fields = def.fields.iter().filter(|f| {
+        let live_fields = def.fields().filter(|f| {
             has_extern_repr || inherited_pub_visibility || match f.node.kind {
                 hir::NamedField(_, hir::Public) => true,
                 _ => false
@@ -426,7 +426,7 @@ fn find_live(tcx: &ty::ctxt,
 
 fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
     match item.node {
-        hir::ItemStruct(ref struct_def, _) if struct_def.kind != hir::VariantKind::Struct => {
+        hir::ItemStruct(ref struct_def, _) if !struct_def.is_struct() => {
             Some(struct_def.id)
         }
         _ => None
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index df5582e9414..23bb4a1fe39 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -185,7 +185,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Annotator<'a, 'tcx> {
                       |v| visit::walk_item(v, i), required);
 
         if let hir::ItemStruct(ref sd, _) = i.node {
-            if sd.kind != hir::VariantKind::Struct {
+            if !sd.is_struct() {
                 self.annotate(sd.id, true, &i.attrs, i.span, |_| {}, true)
             }
         }
diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs
index ecea50f8495..fd69d2007ff 100644
--- a/src/librustc_front/fold.rs
+++ b/src/librustc_front/fold.rs
@@ -694,11 +694,18 @@ pub fn noop_fold_where_predicate<T: Folder>(pred: WherePredicate, fld: &mut T) -
 }
 
 pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> {
-    struct_def.map(|VariantData { fields, id, kind }| {
+    struct_def.map(|VariantData { data_, id }| {
         VariantData {
-            fields: fields.move_map(|f| fld.fold_struct_field(f)),
+            data_: match data_ {
+                VariantData_::Struct(fields) => {
+                    VariantData_::Struct(fields.move_map(|f| fld.fold_struct_field(f)))
+                }
+                VariantData_::Tuple(fields) => {
+                    VariantData_::Tuple(fields.move_map(|f| fld.fold_struct_field(f)))
+                }
+                VariantData_::Unit => VariantData_::Unit
+            },
             id: fld.new_id(id),
-            kind: kind,
         }
     })
 }
diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs
index 92a52c38176..b5170b7496b 100644
--- a/src/librustc_front/hir.rs
+++ b/src/librustc_front/hir.rs
@@ -49,6 +49,7 @@ use print::pprust;
 use util;
 
 use std::fmt;
+use std::{iter, option, slice};
 use serialize::{Encodable, Encoder, Decoder};
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
@@ -1160,21 +1161,42 @@ impl StructFieldKind {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum VariantKind {
-    Struct,
-    Tuple,
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum VariantData_ {
+    Struct(Vec<StructField>),
+    Tuple(Vec<StructField>),
     Unit,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct VariantData {
-    /// Fields, not including ctor
-    pub fields: Vec<StructField>,
+    pub data_: VariantData_,
     /// ID of the constructor. This is only used for tuple- or enum-like
     /// structs.
     pub id: NodeId,
-    pub kind: VariantKind,
+}
+
+pub type FieldIter<'a> = iter::FlatMap<option::IntoIter<&'a Vec<StructField>>,
+                                       slice::Iter<'a, StructField>,
+                                       fn(&Vec<StructField>) -> slice::Iter<StructField>>;
+
+impl VariantData {
+    pub fn fields(&self) -> FieldIter {
+        fn vec_iter<T>(v: &Vec<T>) -> slice::Iter<T> { v.iter() }
+        match self.data_ {
+            VariantData_::Struct(ref fields) | VariantData_::Tuple(ref fields) => Some(fields),
+            _ => None,
+        }.into_iter().flat_map(vec_iter)
+    }
+    pub fn is_struct(&self) -> bool {
+        if let VariantData_::Struct(..) = self.data_ { true } else { false }
+    }
+    pub fn is_tuple(&self) -> bool {
+        if let VariantData_::Tuple(..) = self.data_ { true } else { false }
+    }
+    pub fn is_unit(&self) -> bool {
+        if let VariantData_::Unit = self.data_ { true } else { false }
+    }
 }
 
 /*
diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs
index ecbfbd1362e..cd32ad15744 100644
--- a/src/librustc_front/lowering.rs
+++ b/src/librustc_front/lowering.rs
@@ -500,12 +500,15 @@ pub fn lower_where_predicate(_lctx: &LoweringContext,
 
 pub fn lower_struct_def(sd: &VariantData) -> P<hir::VariantData> {
     P(hir::VariantData {
-        fields: sd.fields.iter().map(|f| lower_struct_field(_lctx, f)).collect(),
         id: sd.id,
-        kind: match sd.kind {
-            VariantKind::Struct => hir::VariantKind::Struct,
-            VariantKind::Tuple => hir::VariantKind::Tuple,
-            VariantKind::Unit => hir::VariantKind::Unit,
+        data_: match sd.data_ {
+            VariantData_::Struct(ref fields) => {
+                hir::VariantData_::Struct(fields.iter().map(|f| lower_struct_field(_lctx, f)).collect())
+            }
+            VariantData_::Tuple(ref fields) => {
+                hir::VariantData_::Tuple(fields.iter().map(|f| lower_struct_field(_lctx, f)).collect())
+            }
+            VariantData_::Unit => hir::VariantData_::Unit
         }
     })
 }
diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs
index 948134c8025..5e78aa5fbc1 100644
--- a/src/librustc_front/print/pprust.rs
+++ b/src/librustc_front/print/pprust.rs
@@ -896,11 +896,11 @@ impl<'a> State<'a> {
                         -> io::Result<()> {
         try!(self.print_name(name));
         try!(self.print_generics(generics));
-        if struct_def.kind != hir::VariantKind::Struct {
-            if struct_def.kind == hir::VariantKind::Tuple {
+        if !struct_def.is_struct() {
+            if struct_def.is_tuple() {
                 try!(self.popen());
-                try!(self.commasep(Inconsistent,
-                                   &struct_def.fields,
+                try!(self.commasep_iter(Inconsistent,
+                                   struct_def.fields(),
                                    |s, field| {
                                        match field.node.kind {
                                            hir::NamedField(..) => panic!("unexpected named field"),
@@ -925,7 +925,7 @@ impl<'a> State<'a> {
             try!(self.bopen());
             try!(self.hardbreak_if_not_bol());
 
-            for field in &struct_def.fields {
+            for field in struct_def.fields() {
                 match field.node.kind {
                     hir::UnnamedField(..) => panic!("unexpected unnamed field"),
                     hir::NamedField(name, visibility) => {
diff --git a/src/librustc_front/visit.rs b/src/librustc_front/visit.rs
index 8472bef3cd1..00c2c3a3ddd 100644
--- a/src/librustc_front/visit.rs
+++ b/src/librustc_front/visit.rs
@@ -629,7 +629,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
 }
 
 pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
-    walk_list!(visitor, visit_struct_field, &struct_definition.fields);
+    walk_list!(visitor, visit_struct_field, struct_definition.fields());
 }
 
 pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs
index 6b6b90b1ba6..693de1740bf 100644
--- a/src/librustc_lint/bad_style.rs
+++ b/src/librustc_lint/bad_style.rs
@@ -282,7 +282,7 @@ impl LateLintPass for NonSnakeCase {
 
     fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData,
                         _: ast::Name, _: &hir::Generics, _: ast::NodeId) {
-        for sf in &s.fields {
+        for sf in s.fields() {
             if let hir::StructField_ { kind: hir::NamedField(name, _), .. } = sf.node {
                 self.check_snake_case(cx, "structure field", &name.as_str(),
                                       Some(sf.span));
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index df15dbe4d6c..ea8ea4ebf0d 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -123,7 +123,7 @@ impl LateLintPass for BoxPointers {
         // If it's a struct, we also have to check the fields' types
         match it.node {
             hir::ItemStruct(ref struct_def, _) => {
-                for struct_field in &struct_def.fields {
+                for struct_field in struct_def.fields() {
                     self.check_heap_type(cx, struct_field.span,
                                          cx.tcx.node_id_to_type(struct_field.node.id));
                 }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index e1e51ae666b..b139b275785 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -132,13 +132,13 @@ impl<'v> Visitor<'v> for ParentVisitor {
                         _: &'v hir::Generics, item_id: ast::NodeId, _: Span) {
         // Struct constructors are parented to their struct definitions because
         // they essentially are the struct definitions.
-        if s.kind != hir::VariantKind::Struct {
+        if !s.is_struct() {
             self.parents.insert(s.id, item_id);
         }
 
         // While we have the id of the struct definition, go ahead and parent
         // all the fields.
-        for field in &s.fields {
+        for field in s.fields() {
             self.parents.insert(field.node.id, self.curparent);
         }
         visit::walk_struct_def(self, s)
@@ -319,11 +319,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
 
             // Struct constructors are public if the struct is all public.
             hir::ItemStruct(ref def, _) if public_first => {
-                if def.kind != hir::VariantKind::Struct {
+                if !def.is_struct() {
                     self.exported_items.insert(def.id);
                 }
                 // fields can be public or private, so lets check
-                for field in &def.fields {
+                for field in def.fields() {
                     let vis = match field.node.kind {
                         hir::NamedField(_, vis) | hir::UnnamedField(vis) => vis
                     };
@@ -1089,7 +1089,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
             }
         }
         let check_struct = |def: &hir::VariantData| {
-            for f in &def.fields {
+            for f in def.fields() {
                match f.node.kind {
                     hir::NamedField(_, p) => check_inherited(tcx, f.span, p),
                     hir::UnnamedField(..) => {}
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 4484cfe9590..43943fbb129 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -492,9 +492,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             // These items live in both the type and value namespaces.
             ItemStruct(ref struct_def, _) => {
                 // Adding to both Type and Value namespaces or just Type?
-                let (forbid, ctor_id) = match struct_def.kind {
-                    hir::VariantKind::Struct => (ForbidDuplicateTypesAndModules, None),
-                    _                     => (ForbidDuplicateTypesAndValues, Some(struct_def.id)),
+                let (forbid, ctor_id) = if struct_def.is_struct() {
+                    (ForbidDuplicateTypesAndModules, None)
+                } else {
+                    (ForbidDuplicateTypesAndValues, Some(struct_def.id))
                 };
 
                 let name_bindings = self.add_child(name, parent, forbid, sp);
@@ -513,7 +514,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 }
 
                 // Record the def ID and fields of this struct.
-                let named_fields = struct_def.fields.iter().filter_map(|f| {
+                let named_fields = struct_def.fields().filter_map(|f| {
                     match f.node.kind {
                         NamedField(name, _) => Some(name),
                         UnnamedField(_) => None
@@ -587,14 +588,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                        item_id: DefId,
                                        parent: &Rc<Module>) {
         let name = variant.node.name;
-        let is_exported = match variant.node.data.kind {
-            hir::VariantKind::Struct => {
-                // Not adding fields for variants as they are not accessed with a self receiver
-                let variant_def_id = self.ast_map.local_def_id(variant.node.data.id);
-                self.structs.insert(variant_def_id, Vec::new());
-                true
-            }
-            _ => false,
+        let is_exported = if variant.node.data.is_struct() {
+            // Not adding fields for variants as they are not accessed with a self receiver
+            let variant_def_id = self.ast_map.local_def_id(variant.node.data.id);
+            self.structs.insert(variant_def_id, Vec::new());
+            true
+        } else {
+            false
         };
 
         let child = self.add_child(name, parent,
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 5235bd49a28..d31b8b6f0e4 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -473,7 +473,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                             &val);
 
         // fields
-        for field in &def.fields {
+        for field in def.fields() {
             self.process_struct_field_def(field, item.id);
             self.visit_ty(&field.node.ty);
         }
@@ -510,7 +510,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                         &val,
                                         enum_data.id);
 
-            for field in &variant.node.data.fields {
+            for field in variant.node.data.fields() {
                 self.process_struct_field_def(field, variant.node.data.id);
                 self.visit_ty(&*field.node.ty);
             }
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index d7ace6e2541..c692f8a1836 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2428,12 +2428,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
         hir_map::NodeVariant(ref v) => {
             let llfn;
-            let fields = if v.node.data.kind == hir::VariantKind::Struct {
+            let fields = if v.node.data.is_struct() {
                 ccx.sess().bug("struct variant kind unexpected in get_item_val")
             } else {
-                &v.node.data.fields
+                v.node.data.fields()
             };
-            assert!(!fields.is_empty());
+            assert!(fields.count() != 0);
             let ty = ccx.tcx().node_id_to_type(id);
             let parent = ccx.tcx().map.get_parent(id);
             let enm = ccx.tcx().map.expect_item(parent);
@@ -2454,12 +2454,11 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
         hir_map::NodeStructCtor(struct_def) => {
             // Only register the constructor if this is a tuple-like struct.
-            let ctor_id = match struct_def.kind {
-                hir::VariantKind::Struct => {
-                    ccx.sess().bug("attempt to register a constructor of \
-                                    a non-tuple-like struct")
-                }
-                _ => struct_def.id,
+            let ctor_id = if struct_def.is_struct() {
+                ccx.sess().bug("attempt to register a constructor of \
+                                  a non-tuple-like struct")
+            } else {
+                struct_def.id
             };
             let parent = ccx.tcx().map.get_parent(id);
             let struct_item = ccx.tcx().map.expect_item(parent);
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 455eb709291..c8525e33e26 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -418,7 +418,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
 
         match map_node {
             hir_map::NodeVariant(v) => {
-                v.node.data.kind == hir::VariantKind::Tuple
+                v.node.data.is_tuple()
             }
             hir_map::NodeStructCtor(_) => true,
             _ => false
diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs
index 2f747606e59..923214a5362 100644
--- a/src/librustc_trans/trans/inline.rs
+++ b/src/librustc_trans/trans/inline.rs
@@ -115,13 +115,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
                     }
                 }
                 hir::ItemStruct(ref struct_def, _) => {
-                    match struct_def.kind {
-                        hir::VariantKind::Struct => ccx.sess().bug("instantiate_inline: called on a \
-                                                                 non-tuple struct"),
-                        _ => {
-                            ccx.external().borrow_mut().insert(fn_id, Some(struct_def.id));
-                            my_id = struct_def.id;
-                        }
+                    if struct_def.is_struct() {
+                        ccx.sess().bug("instantiate_inline: called on a \
+                                                                 non-tuple struct")
+                    } else {
+                        ccx.external().borrow_mut().insert(fn_id, Some(struct_def.id));
+                        my_id = struct_def.id;
                     }
                 }
                 _ => ccx.sess().bug("instantiate_inline: item has a \
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 80d683a8f35..440b667e801 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -246,7 +246,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         hir_map::NodeStructCtor(struct_def) => {
             let d = mk_lldecl(abi::Rust);
             attributes::inline(d, attributes::InlineAttr::Hint);
-            if struct_def.kind == hir::VariantKind::Struct {
+            if struct_def.is_struct() {
                 panic!("ast-mapped struct didn't have a ctor id")
             }
             base::trans_tuple_struct(ccx,
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index ebf54f62b52..14947d9955e 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -627,8 +627,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                             struct_def: &hir::VariantData)
                             -> AdtVariant<'tcx> {
     let fields =
-        struct_def.fields
-        .iter()
+        struct_def.fields()
         .map(|field| {
             let field_ty = fcx.tcx().node_id_to_type(field.node.id);
             let field_ty = fcx.instantiate_type_scheme(field.span,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 0d2d37714c0..4cfc34dbb23 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -524,8 +524,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                             struct_def: &hir::VariantData)
                             -> AdtVariant<'tcx> {
     let fields =
-        struct_def.fields
-        .iter()
+        struct_def.fields()
         .map(|field| {
             let field_ty = fcx.tcx().node_id_to_type(field.node.id);
             let field_ty = fcx.instantiate_type_scheme(field.span,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index c38befd7444..44e06688774 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1010,11 +1010,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
             let it_def_id = ccx.tcx.map.local_def_id(it.id);
             let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
 
-            for (f, ty_f) in struct_def.fields.iter().zip(variant.fields.iter()) {
+            for (f, ty_f) in struct_def.fields().zip(variant.fields.iter()) {
                 convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
             }
 
-            if struct_def.kind != hir::VariantKind::Struct {
+            if !struct_def.is_struct() {
                 convert_variant_ctor(tcx, struct_def.id, variant, scheme, predicates);
             }
         },
@@ -1067,7 +1067,7 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                         variants: &[P<hir::Variant>]) {
     // fill the field types
     for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) {
-        for (f, ty_f) in variant.node.data.fields.iter().zip(ty_variant.fields.iter()) {
+        for (f, ty_f) in variant.node.data.fields().zip(ty_variant.fields.iter()) {
             convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
         }
 
@@ -1089,7 +1089,7 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
                                 disr_val: ty::Disr,
                                 def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
     let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
-    let fields = def.fields.iter().map(|f| {
+    let fields = def.fields().map(|f| {
         let fid = tcx.map.local_def_id(f.node.id);
         match f.node.kind {
             hir::NamedField(name, vis) => {
@@ -1125,7 +1125,7 @@ fn convert_struct_def<'tcx>(tcx: &ty::ctxt<'tcx>,
 {
 
     let did = tcx.map.local_def_id(it.id);
-    let ctor_id = if def.kind != hir::VariantKind::Struct {
+    let ctor_id = if !def.is_struct() {
         tcx.map.local_def_id(def.id)
     } else {
         did
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f935210ef28..e5090c167df 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1809,7 +1809,7 @@ impl Clean<VariantStruct> for ::rustc_front::hir::VariantData {
     fn clean(&self, cx: &DocContext) -> VariantStruct {
         VariantStruct {
             struct_type: doctree::struct_type_from_def(self),
-            fields: self.fields.clean(cx),
+            fields: self.fields().map(|x| x.clean(cx)).collect(),
             fields_stripped: false,
         }
     }
@@ -1918,12 +1918,12 @@ pub enum VariantKind {
 }
 
 fn struct_def_to_variant_kind(struct_def: &hir::VariantData, cx: &DocContext) -> VariantKind {
-    if struct_def.kind == hir::VariantKind::Struct {
+    if struct_def.is_struct() {
         StructVariant(struct_def.clean(cx))
-    } else if struct_def.kind == hir::VariantKind::Unit {
+    } else if struct_def.is_unit() {
         CLikeVariant
     } else {
-        TupleVariant(struct_def.fields.iter().map(|x| x.node.ty.clean(cx)).collect())
+        TupleVariant(struct_def.fields().map(|x| x.node.ty.clean(cx)).collect())
     }
 }
 
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 112c6aebfc5..47cc007f605 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -234,9 +234,9 @@ pub struct Import {
 }
 
 pub fn struct_type_from_def(sd: &hir::VariantData) -> StructType {
-    if sd.kind != hir::VariantKind::Struct {
+    if !sd.is_struct() {
         // We are in a tuple-struct
-        match sd.fields.len() {
+        match sd.fields().count() {
             0 => Unit,
             1 => Newtype,
             _ => Tuple
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index e84d7f549a9..19edccc4fe2 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -97,7 +97,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             stab: self.stability(item.id),
             attrs: item.attrs.clone(),
             generics: generics.clone(),
-            fields: sd.fields.clone(),
+            fields: sd.fields().cloned().collect(),
             whence: item.span
         }
     }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index af623549767..34181b2e097 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -65,6 +65,7 @@ use std::fmt;
 use std::rc::Rc;
 use std::borrow::Cow;
 use std::hash::{Hash, Hasher};
+use std::{iter, option, slice};
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 /// A name is a part of an identifier, representing a string or gensym. It's
@@ -1740,21 +1741,42 @@ impl StructFieldKind {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum VariantKind {
-    Struct,
-    Tuple,
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum VariantData_ {
+    Struct(Vec<StructField>),
+    Tuple(Vec<StructField>),
     Unit,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct VariantData {
-    /// Fields, not including ctor
-    pub fields: Vec<StructField>,
+    pub data_: VariantData_,
     /// ID of the constructor. This is only used for tuple- or enum-like
     /// structs.
     pub id: NodeId,
-    pub kind: VariantKind,
+}
+
+pub type FieldIter<'a> = iter::FlatMap<option::IntoIter<&'a Vec<StructField>>,
+                                       slice::Iter<'a, StructField>,
+                                       fn(&Vec<StructField>) -> slice::Iter<StructField>>;
+
+impl VariantData {
+    pub fn fields(&self) -> FieldIter {
+        fn vec_iter<T>(v: &Vec<T>) -> slice::Iter<T> { v.iter() }
+        match self.data_ {
+            VariantData_::Struct(ref fields) | VariantData_::Tuple(ref fields) => Some(fields),
+            _ => None,
+        }.into_iter().flat_map(vec_iter)
+    }
+    pub fn is_struct(&self) -> bool {
+        if let VariantData_::Struct(..) = self.data_ { true } else { false }
+    }
+    pub fn is_tuple(&self) -> bool {
+        if let VariantData_::Tuple(..) = self.data_ { true } else { false }
+    }
+    pub fn is_unit(&self) -> bool {
+        if let VariantData_::Unit = self.data_ { true } else { false }
+    }
 }
 
 /*
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 02a9d0b5c38..739bb36d985 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -167,13 +167,22 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
 fn fold_struct<F>(cx: &mut Context<F>, def: P<ast::VariantData>) -> P<ast::VariantData> where
     F: FnMut(&[ast::Attribute]) -> bool
 {
-    def.map(|ast::VariantData { fields, id, kind }| {
+    def.map(|ast::VariantData { data_, id }| {
         ast::VariantData {
-            fields: fields.into_iter().filter(|m| {
-                (cx.in_cfg)(&m.node.attrs)
-            }).collect(),
+            data_: match data_ {
+                ast::VariantData_::Struct(fields) => {
+                    ast::VariantData_::Struct(fields.into_iter().filter(|m| {
+                        (cx.in_cfg)(&m.node.attrs)
+                    }).collect())
+                }
+                ast::VariantData_::Tuple(fields) => {
+                    ast::VariantData_::Tuple(fields.into_iter().filter(|m| {
+                        (cx.in_cfg)(&m.node.attrs)
+                    }).collect())
+                }
+                ast::VariantData_::Unit => ast::VariantData_::Unit
+            },
             id: id,
-            kind: kind,
         }
     })
 }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 105a7036c5f..25657b9c6cc 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -1002,15 +1002,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             }}
         }).collect();
 
-        let kind = if fields.is_empty() { ast::VariantKind::Unit } else { ast::VariantKind::Tuple };
+        let data_ = if fields.is_empty() {
+            ast::VariantData_::Unit
+        } else {
+            ast::VariantData_::Tuple(fields)
+        };
 
         respan(span,
                ast::Variant_ {
                    name: name,
                    attrs: Vec::new(),
-                   data: P(ast::VariantData { fields: fields,
-                                           id: ast::DUMMY_NODE_ID,
-                                           kind: kind }),
+                   data: P(ast::VariantData { data_: data_,
+                                           id: ast::DUMMY_NODE_ID}),
                    disr_expr: None,
                })
     }
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index b375dee4e2c..2a5c4993112 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -652,7 +652,7 @@ impl<'a> TraitDef<'a> {
                          struct_def: &'a VariantData,
                          type_ident: Ident,
                          generics: &Generics) -> P<ast::Item> {
-        let field_tys: Vec<P<ast::Ty>> = struct_def.fields.iter()
+        let field_tys: Vec<P<ast::Ty>> = struct_def.fields()
             .map(|field| field.node.ty.clone())
             .collect();
 
@@ -700,7 +700,7 @@ impl<'a> TraitDef<'a> {
         let mut field_tys = Vec::new();
 
         for variant in &enum_def.variants {
-            field_tys.extend(variant.node.data.fields.iter()
+            field_tys.extend(variant.node.data.fields()
                 .map(|field| field.node.ty.clone()));
         }
 
@@ -1444,7 +1444,7 @@ impl<'a> TraitDef<'a> {
                         struct_def: &VariantData) -> StaticFields {
         let mut named_idents = Vec::new();
         let mut just_spans = Vec::new();
-        for field in struct_def.fields.iter(){
+        for field in struct_def.fields(){
             let sp = self.set_expn_info(cx, field.span);
             match field.node.kind {
                 ast::NamedField(ident, _) => named_idents.push((ident, sp)),
@@ -1483,7 +1483,7 @@ impl<'a> TraitDef<'a> {
                              -> (P<ast::Pat>, Vec<(Span, Option<Ident>,
                                                    P<Expr>,
                                                    &'a [ast::Attribute])>) {
-        if struct_def.fields.is_empty() {
+        if struct_def.fields().count() == 0 {
             return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
         }
 
@@ -1491,7 +1491,7 @@ impl<'a> TraitDef<'a> {
         let mut ident_expr = Vec::new();
         let mut struct_type = Unknown;
 
-        for (i, struct_field) in struct_def.fields.iter().enumerate() {
+        for (i, struct_field) in struct_def.fields().enumerate() {
             let sp = self.set_expn_info(cx, struct_field.span);
             let opt_id = match struct_field.node.kind {
                 ast::NamedField(ident, _) if (struct_type == Unknown ||
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index 3a079717b8b..07b58778358 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -95,7 +95,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
 
             for variant in &enum_def.variants {
                 let def = &variant.node.data;
-                if def.kind != ast::VariantKind::Unit {
+                if !def.is_unit() {
                     cx.span_err(trait_span, "`FromPrimitive` cannot be derived \
                                              for enums with non-unit variants");
                     return cx.expr_fail(trait_span,
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index a6922c24693..be6ad931111 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -859,11 +859,11 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
 
     fn visit_variant_data(&mut self, s: &'v ast::VariantData, _: ast::Ident,
                         _: &'v ast::Generics, _: ast::NodeId, span: Span) {
-        if s.fields.is_empty() {
-            if s.kind == ast::VariantKind::Struct {
+        if s.fields().count() == 0 {
+            if s.is_struct() {
                 self.gate_feature("braced_empty_structs", span,
                                   "empty structs and enum variants with braces are unstable");
-            } else if s.kind == ast::VariantKind::Tuple {
+            } else if s.is_tuple() {
                 self.context.span_handler.span_err(span, "empty tuple structs and enum variants \
                                                           are not allowed, use unit structs and \
                                                           enum variants instead");
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index d7b7fc242b4..329ffb286eb 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -815,10 +815,17 @@ pub fn noop_fold_where_predicate<T: Folder>(
 }
 
 pub fn noop_fold_struct_def<T: Folder>(struct_def: P<VariantData>, fld: &mut T) -> P<VariantData> {
-    struct_def.map(|VariantData { fields, id, kind }| VariantData {
-        fields: fields.move_map(|f| fld.fold_struct_field(f)),
+    struct_def.map(|VariantData { data_, id }| VariantData {
+        data_: match data_ {
+            ast::VariantData_::Struct(fields) => {
+                ast::VariantData_::Struct(fields.move_map(|f| fld.fold_struct_field(f)))
+            }
+            ast::VariantData_::Tuple(fields) => {
+                ast::VariantData_::Tuple(fields.move_map(|f| fld.fold_struct_field(f)))
+            }
+            ast::VariantData_::Unit => ast::VariantData_::Unit
+        },
         id: fld.new_id(id),
-        kind: kind,
     })
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f944c93073a..2431c8cbe88 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -45,7 +45,7 @@ use ast::{PatRegion, PatStruct, PatTup, PatVec, PatWild, PatWildMulti};
 use ast::PatWildSingle;
 use ast::{PolyTraitRef, QSelf};
 use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
-use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField, VariantKind};
+use ast::{StmtExpr, StmtSemi, StmtMac, VariantData, StructField, VariantData_};
 use ast::{BiSub, StrStyle};
 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
@@ -4640,26 +4640,24 @@ impl<'a> Parser<'a> {
         // Otherwise if we look ahead and see a paren we parse a tuple-style
         // struct.
 
-        let (fields, kind) = if self.token.is_keyword(keywords::Where) {
+        let data_ = if self.token.is_keyword(keywords::Where) {
             generics.where_clause = try!(self.parse_where_clause());
             if try!(self.eat(&token::Semi)) {
                 // If we see a: `struct Foo<T> where T: Copy;` style decl.
-                (Vec::new(), VariantKind::Unit)
+                VariantData_::Unit
             } else {
                 // If we see: `struct Foo<T> where T: Copy { ... }`
-                (try!(self.parse_record_struct_body()), VariantKind::Struct)
+                VariantData_::Struct(try!(self.parse_record_struct_body()))
             }
         // No `where` so: `struct Foo<T>;`
         } else if try!(self.eat(&token::Semi) ){
-            (Vec::new(), VariantKind::Unit)
+            VariantData_::Unit
         // Record-style struct definition
         } else if self.token == token::OpenDelim(token::Brace) {
-            let fields = try!(self.parse_record_struct_body());
-            (fields, VariantKind::Struct)
+            VariantData_::Struct(try!(self.parse_record_struct_body()))
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(token::Paren) {
-            let fields = try!(self.parse_tuple_struct_body(&mut generics));
-            (fields, VariantKind::Tuple)
+            VariantData_::Tuple(try!(self.parse_tuple_struct_body(&mut generics)))
         } else {
             let token_str = self.this_token_to_string();
             return Err(self.fatal(&format!("expected `where`, `{{`, `(`, or `;` after struct \
@@ -4668,9 +4666,8 @@ impl<'a> Parser<'a> {
 
         Ok((class_name,
          ItemStruct(P(ast::VariantData {
-             fields: fields,
+             data_: data_,
              id: ast::DUMMY_NODE_ID,
-             kind: kind,
          }), generics),
          None))
     }
@@ -5111,9 +5108,8 @@ impl<'a> Parser<'a> {
         try!(self.bump());
 
         Ok(P(VariantData {
-            fields: fields,
+            data_: VariantData_::Struct(fields),
             id: ast::DUMMY_NODE_ID,
-            kind: VariantKind::Struct,
         }))
     }
 
@@ -5150,19 +5146,16 @@ impl<'a> Parser<'a> {
                         id: ast::DUMMY_NODE_ID,
                     }});
                 }
-                struct_def = P(VariantData { fields: fields,
-                                           id: ast::DUMMY_NODE_ID,
-                                           kind: ast::VariantKind::Tuple });
+                struct_def = P(VariantData { data_: ast::VariantData_::Tuple(fields),
+                                           id: ast::DUMMY_NODE_ID});
             } else if try!(self.eat(&token::Eq) ){
                 disr_expr = Some(try!(self.parse_expr_nopanic()));
                 any_disr = disr_expr.as_ref().map(|expr| expr.span);
-                struct_def = P(VariantData { fields: Vec::new(),
-                                           id: ast::DUMMY_NODE_ID,
-                                           kind: ast::VariantKind::Unit });
+                struct_def = P(VariantData { data_: ast::VariantData_::Unit,
+                                           id: ast::DUMMY_NODE_ID});
             } else {
-                struct_def = P(VariantData { fields: Vec::new(),
-                                           id: ast::DUMMY_NODE_ID,
-                                           kind: ast::VariantKind::Unit });
+                struct_def = P(VariantData { data_: ast::VariantData_::Unit,
+                                           id: ast::DUMMY_NODE_ID});
             }
 
             let vr = ast::Variant_ {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0f6041d2cd0..161f6243f85 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -520,6 +520,18 @@ pub trait PrintState<'a> {
         self.end()
     }
 
+    fn commasep_iter<'it, T: 'it, F, I>(&mut self, b: Breaks, elts: I, mut op: F) -> io::Result<()>
+        where F: FnMut(&mut Self, &T) -> io::Result<()>,
+              I: Iterator<Item=&'it T>,
+    {
+        try!(self.rbox(0, b));
+        let mut first = true;
+        for elt in elts {
+            if first { first = false; } else { try!(self.word_space(",")); }
+            try!(op(self, elt));
+        }
+        self.end()
+    }
 
     fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> {
         let mut cur_lit = self.cur_cmnt_and_lit().cur_lit;
@@ -1392,11 +1404,11 @@ impl<'a> State<'a> {
                         print_finalizer: bool) -> io::Result<()> {
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
-        if struct_def.kind != ast::VariantKind::Struct {
-            if struct_def.kind == ast::VariantKind::Tuple {
+        if !struct_def.is_struct() {
+            if struct_def.is_tuple() {
                 try!(self.popen());
-                try!(self.commasep(
-                    Inconsistent, &struct_def.fields,
+                try!(self.commasep_iter(
+                    Inconsistent, struct_def.fields(),
                     |s, field| {
                         match field.node.kind {
                             ast::NamedField(..) => panic!("unexpected named field"),
@@ -1422,7 +1434,7 @@ impl<'a> State<'a> {
             try!(self.bopen());
             try!(self.hardbreak_if_not_bol());
 
-            for field in &struct_def.fields {
+            for field in struct_def.fields() {
                 match field.node.kind {
                     ast::UnnamedField(..) => panic!("unexpected unnamed field"),
                     ast::NamedField(ident, visibility) => {
@@ -3119,9 +3131,8 @@ mod tests {
             name: ident,
             attrs: Vec::new(),
             // making this up as I go.... ?
-            data: P(ast::VariantData { fields: Vec::new(),
-                                    id: ast::DUMMY_NODE_ID,
-                                    kind: ast::VariantKind::Unit }),
+            data: P(ast::VariantData { data_: ast::VariantData_::Unit,
+                                    id: ast::DUMMY_NODE_ID}),
             disr_expr: None,
         });
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index fdff0bf72eb..b7d202804c5 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -604,7 +604,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
 
 pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
                                            struct_definition: &'v VariantData) {
-    walk_list!(visitor, visit_struct_field, &struct_definition.fields);
+    walk_list!(visitor, visit_struct_field, struct_definition.fields());
 }
 
 pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,