about summary refs log tree commit diff
path: root/src/libsyntax
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 /src/libsyntax
parent30af54dede8b9f03a83dd5ad588bb430a5a76270 (diff)
downloadrust-40aa09e4c9f4c3f0fa2b088895c8f5125325eaa4.tar.gz
rust-40aa09e4c9f4c3f0fa2b088895c8f5125325eaa4.zip
Merge struct fields and struct kind
Diffstat (limited to 'src/libsyntax')
-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
10 files changed, 104 insertions, 59 deletions
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,