about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-08 14:17:52 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-08 14:19:21 -0700
commitf110e8f21c707cb4bbb5e54b45f4458987920322 (patch)
treed4999199d287f0e3e53569ba8bdc82a593654a6c /src/libsyntax
parent166cb1b28bc23303d15e8c1c4a71d0cdff0556a2 (diff)
downloadrust-f110e8f21c707cb4bbb5e54b45f4458987920322.tar.gz
rust-f110e8f21c707cb4bbb5e54b45f4458987920322.zip
rustc: Do some plumbing work on nested enums
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/ext/auto_serialize.rs4
-rw-r--r--src/libsyntax/fold.rs5
-rw-r--r--src/libsyntax/parse/parser.rs95
-rw-r--r--src/libsyntax/print/pprust.rs31
-rw-r--r--src/libsyntax/visit.rs30
6 files changed, 98 insertions, 70 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f1c5f63bd1d..d2a6aa1f7b0 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -636,7 +636,8 @@ type variant_arg = {ty: @ty, id: node_id};
 #[auto_serialize]
 enum variant_kind {
     tuple_variant_kind(~[variant_arg]),
-    struct_variant_kind(@struct_def)
+    struct_variant_kind(@struct_def),
+    enum_variant_kind(~[variant])
 }
 
 #[auto_serialize]
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index 20cc04b2c79..d0a55b6d95c 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -913,7 +913,9 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident,
                 };
             }
             ast::struct_variant_kind(*) =>
-                fail ~"struct variants unimplemented"
+                fail ~"struct variants unimplemented",
+            ast::enum_variant_kind(*) =>
+                fail ~"enum variants unimplemented"
         }
 
         {pats: ~[@{id: cx.next_id(),
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 22713618222..d84c981504f 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -564,6 +564,11 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
                 dtor: dtor
             })
         }
+
+        enum_variant_kind(variants) => {
+            let variants = vec::map(variants, |x| fld.fold_variant(x));
+            kind = enum_variant_kind(variants);
+        }
     }
 
     let fold_attribute = |x| fold_attribute_(x, fld);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6f8128b9b76..1cc3f197721 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -17,28 +17,27 @@ import dvec::{dvec, extensions};
 import vec::{push};
 import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              bind_by_ref, bind_by_implicit_ref, bind_by_value,
-             bitand, bitor, bitxor, blk,
-             blk_check_mode, bound_const, bound_copy, bound_send, bound_trait,
-             bound_owned, box, by_copy, by_move, by_mutbl_ref, by_ref, by_val,
-             capture_clause, capture_item, cdir_dir_mod, cdir_src_mod,
-             cdir_view_item, class_immutable, class_member, class_method,
-             class_mutable, crate, crate_cfg, crate_directive, decl,
-             decl_item, decl_local, default_blk, deref, div, expl, expr,
-             expr_, expr_addr_of, expr_match, expr_again, expr_assert,
-             expr_assign, expr_assign_op, expr_binary, expr_block, expr_break,
-             expr_call, expr_cast, expr_copy, expr_do_body,
-             expr_fail, expr_field, expr_fn, expr_fn_block, expr_if,
-             expr_index, expr_lit, expr_log, expr_loop,
-             expr_loop_body, expr_mac, expr_move, expr_path, expr_rec,
-             expr_repeat, expr_ret, expr_swap, expr_struct, expr_tup,
-             expr_unary, expr_unary_move, expr_vec, expr_vstore, expr_while,
-             extern_fn, field, fn_decl, foreign_item, foreign_item_fn,
-             foreign_mod, ident, impure_fn, infer, inherited, init_assign,
-             init_move, initializer, instance_var, item, item_, item_class,
-             item_const, item_enum, item_fn, item_foreign_mod, item_impl,
-             item_mac, item_mod, item_trait, item_ty, lit, lit_, lit_bool,
-             lit_float, lit_int, lit_int_unsuffixed, lit_nil, lit_str,
-             lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq,
+             bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
+             bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
+             by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
+             capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
+             class_immutable, class_member, class_method, class_mutable,
+             crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
+             default_blk, deref, div, enum_variant_kind, expl, expr, expr_,
+             expr_addr_of, expr_match, expr_again, expr_assert, expr_assign,
+             expr_assign_op, expr_binary, expr_block, expr_break, expr_call,
+             expr_cast, expr_copy, expr_do_body, expr_fail, expr_field,
+             expr_fn, expr_fn_block, expr_if, expr_index, expr_lit, expr_log,
+             expr_loop, expr_loop_body, expr_mac, expr_move, expr_path,
+             expr_rec, expr_repeat, expr_ret, expr_swap, expr_struct,
+             expr_tup, expr_unary, expr_unary_move, expr_vec, expr_vstore,
+             expr_while, extern_fn, field, fn_decl, foreign_item,
+             foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited,
+             init_assign, init_move, initializer, instance_var, item, item_,
+             item_class, item_const, item_enum, item_fn, item_foreign_mod,
+             item_impl, item_mac, item_mod, item_trait, item_ty, lit, lit_,
+             lit_bool, lit_float, lit_int, lit_int_unsuffixed, lit_nil,
+             lit_str, lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq,
              mac_ellipsis, mac_invoc, mac_invoc_tt, mac_var, matcher,
              match_nonterminal, match_seq, match_tok, method, mode, mt, mul,
              mutability, neg, noreturn, not, pat, pat_box, pat_enum,
@@ -2842,30 +2841,8 @@ class parser {
         }
     }
 
-    fn parse_item_enum() -> item_info {
-        let id = self.parse_ident();
-        self.parse_region_param();
-        let ty_params = self.parse_ty_params();
+    fn parse_enum_body(ty_params: ~[ast::ty_param]) -> ~[ast::variant] {
         let mut variants: ~[variant] = ~[];
-        // Newtype syntax
-        if self.token == token::EQ {
-            self.check_restricted_keywords_(*id);
-            self.bump();
-            let ty = self.parse_ty(false);
-            self.expect(token::SEMI);
-            let variant =
-                spanned(ty.span.lo, ty.span.hi,
-                        {name: id,
-                         attrs: ~[],
-                         kind: tuple_variant_kind
-                            (~[{ty: ty, id: self.get_id()}]),
-                         id: self.get_id(),
-                         disr_expr: none,
-                         vis: public});
-            return (id, item_enum(~[variant], ty_params), none);
-        }
-        self.expect(token::LBRACE);
-
         let mut all_nullary = true, have_disr = false;
 
         while self.token != token::RBRACE {
@@ -2954,6 +2931,34 @@ class parser {
             self.fatal(~"discriminator values can only be used with a c-like \
                         enum");
         }
+
+        return variants;
+    }
+
+    fn parse_item_enum() -> item_info {
+        let id = self.parse_ident();
+        self.parse_region_param();
+        let ty_params = self.parse_ty_params();
+        // Newtype syntax
+        if self.token == token::EQ {
+            self.check_restricted_keywords_(*id);
+            self.bump();
+            let ty = self.parse_ty(false);
+            self.expect(token::SEMI);
+            let variant =
+                spanned(ty.span.lo, ty.span.hi,
+                        {name: id,
+                         attrs: ~[],
+                         kind: tuple_variant_kind
+                            (~[{ty: ty, id: self.get_id()}]),
+                         id: self.get_id(),
+                         disr_expr: none,
+                         vis: public});
+            return (id, item_enum(~[variant], ty_params), none);
+        }
+        self.expect(token::LBRACE);
+
+        let variants = self.parse_enum_body(ty_params);
         (id, item_enum(variants, ty_params), none)
     }
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 4b23fbf74a9..56b3197c336 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -516,18 +516,7 @@ fn print_item(s: ps, &&item: @ast::item) {
             word(s.s, ~";");
             end(s);
         } else {
-            bopen(s);
-            for variants.each |v| {
-                space_if_not_bol(s);
-                maybe_print_comment(s, v.span.lo);
-                print_outer_attributes(s, v.node.attrs);
-                ibox(s, indent_unit);
-                print_variant(s, v);
-                word(s.s, ~",");
-                end(s);
-                maybe_print_trailing_comment(s, v.span, none::<uint>);
-            }
-            bclose(s, item.span);
+            print_variants(s, variants, item.span);
         }
       }
       ast::item_class(struct_def, tps) => {
@@ -582,6 +571,21 @@ fn print_item(s: ps, &&item: @ast::item) {
     s.ann.post(ann_node);
 }
 
+fn print_variants(s: ps, variants: ~[ast::variant], span: ast::span) {
+    bopen(s);
+    for variants.each |v| {
+        space_if_not_bol(s);
+        maybe_print_comment(s, v.span.lo);
+        print_outer_attributes(s, v.node.attrs);
+        ibox(s, indent_unit);
+        print_variant(s, v);
+        word(s.s, ~",");
+        end(s);
+        maybe_print_trailing_comment(s, v.span, none::<uint>);
+    }
+    bclose(s, span);
+}
+
 fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param],
                 ident: ast::ident, span: ast::span) {
     word_nbsp(s, *ident);
@@ -710,6 +714,9 @@ fn print_variant(s: ps, v: ast::variant) {
             head(s, ~"");
             print_struct(s, struct_def, ~[], v.node.name, v.span);
         }
+        ast::enum_variant_kind(variants) => {
+            print_variants(s, variants, v.span);
+        }
     }
     match v.node.disr_expr {
       some(d) => {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a47685dd42c..f526f8c73e1 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -138,17 +138,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
       }
       item_enum(variants, tps) => {
         v.visit_ty_params(tps, e, v);
-        for variants.each |vr| {
-            match vr.node.kind {
-                tuple_variant_kind(variant_args) => {
-                    for variant_args.each |va| { v.visit_ty(va.ty, e, v); }
-                }
-                struct_variant_kind(struct_def) => {
-                    v.visit_struct_def(struct_def, vr.node.name, tps,
-                                       vr.node.id, e, v);
-                }
-            }
-        }
+        visit_variants(variants, tps, e, v);
       }
       item_impl(tps, traits, ty, methods) => {
         v.visit_ty_params(tps, e, v);
@@ -175,6 +165,24 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
     }
 }
 
+fn visit_variants<E>(variants: ~[ast::variant], tps: ~[ast::ty_param], e: E,
+                     v: vt<E>) {
+    for variants.each |vr| {
+        match vr.node.kind {
+            tuple_variant_kind(variant_args) => {
+                for variant_args.each |va| { v.visit_ty(va.ty, e, v); }
+            }
+            struct_variant_kind(struct_def) => {
+                v.visit_struct_def(struct_def, vr.node.name, tps,
+                                   vr.node.id, e, v);
+            }
+            enum_variant_kind(variants) => {
+                visit_variants(variants, tps, e, v);
+            }
+        }
+    }
+}
+
 fn visit_class_item<E>(cm: @class_member, e:E, v:vt<E>) {
     match cm.node {
       instance_var(_, t, _, _, _) => v.visit_ty(t, e, v),