about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-08-07 14:24:04 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-08-07 14:25:53 -0700
commit727c7c74994cf54baecab8ab6b03c50ace44d634 (patch)
tree7a3d1ae73f49614ed0163ba20a03f23451d69f00 /src
parentbc267c696c015525ea303e03d448d1507b6afeb6 (diff)
rustc: Add stub support for struct variants to the AST
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/ast.rs8
-rw-r--r--src/libsyntax/ast_util.rs11
-rw-r--r--src/libsyntax/ext/auto_serialize.rs122
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs2
-rw-r--r--src/libsyntax/fold.rs13
-rw-r--r--src/libsyntax/parse/parser.rs21
-rw-r--r--src/libsyntax/print/pprust.rs37
-rw-r--r--src/libsyntax/visit.rs6
-rw-r--r--src/rustc/metadata/encoder.rs8
-rw-r--r--src/rustc/middle/trans/base.rs62
-rw-r--r--src/rustc/middle/ty.rs49
-rw-r--r--src/rustc/middle/typeck/check.rs10
-rw-r--r--src/rustc/middle/typeck/coherence.rs1
-rw-r--r--src/rustc/middle/typeck/collect.rs31
14 files changed, 237 insertions, 144 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 577ef1464cf..87fe7fe67a9 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -632,7 +632,13 @@ type foreign_mod =
 type variant_arg = {ty: @ty, id: node_id};
 
 #[auto_serialize]
-type variant_ = {name: ident, attrs: ~[attribute], args: ~[variant_arg],
+enum variant_kind {
+    tuple_variant_kind(~[variant_arg]),
+    struct_variant_kind
+}
+
+#[auto_serialize]
+type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
                  id: node_id, disr_expr: option<@expr>, vis: visibility};
 
 #[auto_serialize]
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index deb8bb5963d..7d7867d0516 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -187,12 +187,13 @@ fn is_exported(i: ident, m: _mod) -> bool {
     for m.items.each |it| {
         if it.ident == i { local = true; }
         match it.node {
-          item_enum(variants, _) => for variants.each |v| {
-            if v.node.name == i {
-                local = true;
-                parent_enum = some(/* FIXME (#2543) */ copy it.ident);
+          item_enum(variants, _) =>
+            for variants.each |v| {
+                if v.node.name == i {
+                    local = true;
+                    parent_enum = some(/* FIXME (#2543) */ copy it.ident);
+                }
             }
-          },
           _ => ()
         }
         if local { break; }
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index 053c972d1ea..4ce017eeae9 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -830,43 +830,51 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident,
         let variant = variants[vidx];
         let v_span = variant.span;
         let v_name = variant.node.name;
-        let variant_tys = vec::map(variant.node.args, |a| a.ty);
-
-        ser_variant(
-            cx, tps, variant_tys, v_span, cx.clone(s),
-
-            // Generate pattern var(v1, v2, v3)
-            |pats| {
-                if vec::is_empty(pats) {
-                    ast::pat_ident(ast::bind_by_implicit_ref,
-                                   cx.path(v_span, ~[v_name]),
-                                   none)
-                } else {
-                    ast::pat_enum(cx.path(v_span, ~[v_name]), some(pats))
-                }
-            },
-
-            // Generate body s.emit_enum_variant("foo", 0u,
-            //                                   3u, {|| blk })
-            |-s, blk| {
-                let v_name = cx.lit_str(v_span, v_name);
-                let v_id = cx.lit_uint(v_span, vidx);
-                let sz = cx.lit_uint(v_span, vec::len(variant_tys));
-                let body = cx.lambda(blk);
-                #ast[expr]{
-                    $(s).emit_enum_variant($(v_name), $(v_id),
-                                           $(sz), $(body))
-                }
-            },
-
-            // Generate s.emit_enum_variant_arg(i, {|| blk })
-            |-s, i, blk| {
-                let idx = cx.lit_uint(v_span, i);
-                let body = cx.lambda(blk);
-                #ast[expr]{
-                    $(s).emit_enum_variant_arg($(idx), $(body))
-                }
-            })
+
+        match variant.node.kind {
+            ast::tuple_variant_kind(args) => {
+                let variant_tys = vec::map(args, |a| a.ty);
+
+                ser_variant(
+                    cx, tps, variant_tys, v_span, cx.clone(s),
+
+                    // Generate pattern var(v1, v2, v3)
+                    |pats| {
+                        if vec::is_empty(pats) {
+                            ast::pat_ident(ast::bind_by_implicit_ref,
+                                           cx.path(v_span, ~[v_name]),
+                                           none)
+                        } else {
+                            ast::pat_enum(cx.path(v_span, ~[v_name]),
+                                                  some(pats))
+                        }
+                    },
+
+                    // Generate body s.emit_enum_variant("foo", 0u,
+                    //                                   3u, {|| blk })
+                    |-s, blk| {
+                        let v_name = cx.lit_str(v_span, v_name);
+                        let v_id = cx.lit_uint(v_span, vidx);
+                        let sz = cx.lit_uint(v_span, vec::len(variant_tys));
+                        let body = cx.lambda(blk);
+                        #ast[expr]{
+                            $(s).emit_enum_variant($(v_name), $(v_id),
+                                                   $(sz), $(body))
+                        }
+                    },
+
+                    // Generate s.emit_enum_variant_arg(i, {|| blk })
+                    |-s, i, blk| {
+                        let idx = cx.lit_uint(v_span, i);
+                        let body = cx.lambda(blk);
+                        #ast[expr]{
+                            $(s).emit_enum_variant_arg($(idx), $(body))
+                        }
+                    })
+            }
+            _ =>
+                fail ~"struct variants unimplemented for auto serialize"
+        }
     };
     let lam = cx.lambda(cx.blk(e_span, ~[cx.alt_stmt(arms, e_span, v)]));
     let e_name = cx.lit_str(e_span, e_name);
@@ -881,24 +889,32 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident,
         let variant = variants[vidx];
         let v_span = variant.span;
         let v_name = variant.node.name;
-        let tys = vec::map(variant.node.args, |a| a.ty);
-
-        let arg_exprs = do vec::from_fn(vec::len(tys)) |i| {
-            let idx = cx.lit_uint(v_span, i);
-            let body = deser_lambda(cx, tps, tys[i], cx.clone(d));
-            #ast{ $(d).read_enum_variant_arg($(idx), $(body)) }
-        };
 
-        let body = {
-            if vec::is_empty(tys) {
-                // for a nullary variant v, do "v"
-                cx.var_ref(v_span, v_name)
-            } else {
-                // for an n-ary variant v, do "v(a_1, ..., a_n)"
-                cx.expr(v_span, ast::expr_call(
-                    cx.var_ref(v_span, v_name), arg_exprs, false))
+        let body;
+        match variant.node.kind {
+            ast::tuple_variant_kind(args) => {
+                let tys = vec::map(args, |a| a.ty);
+
+                let arg_exprs = do vec::from_fn(vec::len(tys)) |i| {
+                    let idx = cx.lit_uint(v_span, i);
+                    let body = deser_lambda(cx, tps, tys[i], cx.clone(d));
+                    #ast{ $(d).read_enum_variant_arg($(idx), $(body)) }
+                };
+
+                body = {
+                    if vec::is_empty(tys) {
+                        // for a nullary variant v, do "v"
+                        cx.var_ref(v_span, v_name)
+                    } else {
+                        // for an n-ary variant v, do "v(a_1, ..., a_n)"
+                        cx.expr(v_span, ast::expr_call(
+                            cx.var_ref(v_span, v_name), arg_exprs, false))
+                    }
+                };
             }
-        };
+            ast::struct_variant_kind =>
+                fail ~"struct variants unimplemented"
+        }
 
         {pats: ~[@{id: cx.next_id(),
                   node: ast::pat_lit(cx.lit_uint(v_span, vidx)),
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index b8c37f84452..06a22b63fe0 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -254,7 +254,7 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
 
         {node: {name: name,
                 attrs: ~[],
-                args: args,
+                kind: ast::tuple_variant_kind(args),
                 id: self.next_id(),
                 disr_expr: none,
                 vis: ast::public},
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index ab39bf53f6a..0ceee7f7d97 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -541,7 +541,15 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
         return {ty: fld.fold_ty(va.ty), id: fld.new_id(va.id)};
     }
     let fold_variant_arg = |x| fold_variant_arg_(x, fld);
-    let args = vec::map(v.args, fold_variant_arg);
+
+    let kind;
+    match v.kind {
+        tuple_variant_kind(variant_args) =>
+            kind = tuple_variant_kind(vec::map(variant_args,
+                                               fold_variant_arg)),
+        struct_variant_kind =>
+            kind = struct_variant_kind
+    }
 
     let fold_attribute = |x| fold_attribute_(x, fld);
     let attrs = vec::map(v.attrs, fold_attribute);
@@ -552,7 +560,8 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
     };
     return {name: /* FIXME (#2543) */ copy v.name,
          attrs: attrs,
-         args: args, id: fld.new_id(v.id),
+         kind: kind,
+         id: fld.new_id(v.id),
          disr_expr: de,
          vis: v.vis};
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 993419bd9c4..5feb753657d 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -49,14 +49,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
              stmt_semi, subtract, sty_box, sty_by_ref, sty_region, sty_uniq,
              sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq,
-             tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
-             ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
-             ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq,
-             ty_vec, ty_fixed_length, unchecked_blk, uniq, unsafe_blk,
-             unsafe_fn, variant, view_item, view_item_, view_item_export,
-             view_item_import, view_item_use, view_path, view_path_glob,
-             view_path_list, view_path_simple, visibility, vstore, vstore_box,
-             vstore_fixed, vstore_slice, vstore_uniq};
+             tt_tok, tt_nonterminal, tuple_variant_kind, ty, ty_, ty_bot,
+             ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method, ty_nil,
+             ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr,
+             ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length, unchecked_blk,
+             uniq, unsafe_blk, unsafe_fn, variant, view_item, view_item_,
+             view_item_export, view_item_import, view_item_use, view_path,
+             view_path_glob, view_path_list, view_path_simple, visibility,
+             vstore, vstore_box, vstore_fixed, vstore_slice, vstore_uniq};
 
 export file_type;
 export parser;
@@ -2830,7 +2830,8 @@ class parser {
                 spanned(ty.span.lo, ty.span.hi,
                         {name: id,
                          attrs: ~[],
-                         args: ~[{ty: ty, id: self.get_id()}],
+                         kind: tuple_variant_kind
+                            (~[{ty: ty, id: self.get_id()}]),
                          id: self.get_id(),
                          disr_expr: none,
                          vis: public});
@@ -2861,7 +2862,7 @@ class parser {
             }
 
             let vr = {name: ident, attrs: variant_attrs,
-                      args: args, id: self.get_id(),
+                      kind: tuple_variant_kind(args), id: self.get_id(),
                       disr_expr: disr_expr, vis: vis};
             vec::push(variants, spanned(vlo, self.last_span.hi, vr));
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 41b61f57f92..d3eef85f062 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -488,21 +488,31 @@ fn print_item(s: ps, &&item: @ast::item) {
         end(s); // end the outer ibox
       }
       ast::item_enum(variants, params) => {
-        let newtype =
+        let mut newtype =
             vec::len(variants) == 1u &&
-                str::eq(item.ident, variants[0].node.name) &&
-                vec::len(variants[0].node.args) == 1u;
+                str::eq(item.ident, variants[0].node.name);
+        if newtype {
+            match variants[0].node.kind {
+                ast::tuple_variant_kind(args) if args.len() == 1 => {}
+                _ => newtype = false
+            }
+        }
         if newtype {
             ibox(s, indent_unit);
             word_space(s, ~"enum");
-        } else { head(s, ~"enum"); }
+        } else {
+            head(s, ~"enum");
+        }
 
         word(s.s, *item.ident);
         print_type_params(s, params);
         space(s.s);
         if newtype {
             word_space(s, ~"=");
-            print_type(s, variants[0].node.args[0].ty);
+            match variants[0].node.kind {
+                ast::tuple_variant_kind(args) => print_type(s, args[0].ty),
+                _ => fail ~"newtype syntax with struct?"
+            }
             word(s.s, ~";");
             end(s);
         } else {
@@ -680,13 +690,18 @@ fn print_tt(s: ps, tt: ast::token_tree) {
 
 fn print_variant(s: ps, v: ast::variant) {
     word(s.s, *v.node.name);
-    if vec::len(v.node.args) > 0u {
-        popen(s);
-        fn print_variant_arg(s: ps, arg: ast::variant_arg) {
-            print_type(s, arg.ty);
+    match v.node.kind {
+        ast::tuple_variant_kind(args) => {
+            if vec::len(args) > 0u {
+                popen(s);
+                fn print_variant_arg(s: ps, arg: ast::variant_arg) {
+                    print_type(s, arg.ty);
+                }
+                commasep(s, consistent, args, print_variant_arg);
+                pclose(s);
+            }
         }
-        commasep(s, consistent, v.node.args, print_variant_arg);
-        pclose(s);
+        ast::struct_variant_kind => {}
     }
     match v.node.disr_expr {
       some(d) => {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 830114b47ad..3bf820dd5cf 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -135,7 +135,11 @@ 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| {
-            for vr.node.args.each |va| { v.visit_ty(va.ty, e, v); }
+            match vr.node.kind {
+                tuple_variant_kind(variant_args) =>
+                    for variant_args.each |va| { v.visit_ty(va.ty, e, v); },
+                struct_variant_kind => {}
+            }
         }
       }
       item_impl(tps, traits, ty, methods) => {
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 49299ac850c..267bb55e09e 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -362,8 +362,12 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
         encode_parent_item(ebml_w, local_def(id));
         encode_type(ecx, ebml_w,
                     node_id_to_type(ecx.tcx, variant.node.id));
-        if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
-            encode_symbol(ecx, ebml_w, variant.node.id);
+        match variant.node.kind {
+            ast::tuple_variant_kind(args)
+                    if args.len() > 0 && ty_params.len() == 0 => {
+                encode_symbol(ecx, ebml_w, variant.node.id);
+            }
+            ast::tuple_variant_kind(_) | ast::struct_variant_kind => {}
         }
         encode_discriminant(ecx, ebml_w, variant.node.id);
         if vi[i].disr_val != disr_val {
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 81ea48f9501..eb23008f185 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -2173,8 +2173,14 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
             tv.id.node == fn_id.node}));
         let d = mk_lldecl();
         set_inline_hint(d);
-        trans_enum_variant(ccx, enum_item.id, v, this_tv.disr_val,
-                           (*tvs).len() == 1u, psubsts, d);
+        match v.node.kind {
+            ast::tuple_variant_kind(args) => {
+                trans_enum_variant(ccx, enum_item.id, v, args,
+                                   this_tv.disr_val, (*tvs).len() == 1u,
+                                   psubsts, d);
+            }
+            ast::struct_variant_kind => {}
+        }
         d
       }
       ast_map::node_method(mth, impl_def_id, _) => {
@@ -4671,13 +4677,16 @@ fn trans_fn(ccx: @crate_ctxt,
     }
 }
 
-fn trans_enum_variant(ccx: @crate_ctxt, enum_id: ast::node_id,
-                      variant: ast::variant, disr: int, is_degen: bool,
+fn trans_enum_variant(ccx: @crate_ctxt,
+                      enum_id: ast::node_id,
+                      variant: ast::variant,
+                      args: ~[ast::variant_arg],
+                      disr: int, is_degen: bool,
                       param_substs: option<param_substs>,
                       llfndecl: ValueRef) {
     let _icx = ccx.insn_ctxt(~"trans_enum_variant");
     // Translate variant arguments to function arguments.
-    let fn_args = vec::map(variant.node.args, |varg|
+    let fn_args = vec::map(args, |varg|
         {mode: ast::expl(ast::by_copy),
          ty: varg.ty,
          ident: @~"arg",
@@ -4705,7 +4714,7 @@ fn trans_enum_variant(ccx: @crate_ctxt, enum_id: ast::node_id,
     };
     let t_id = local_def(enum_id);
     let v_id = local_def(variant.node.id);
-    for vec::eachi(variant.node.args) |i, va| {
+    for vec::eachi(args) |i, va| {
         let lldestptr = GEP_enum(bcx, llblobptr, t_id, v_id,
                                  ty_param_substs, i);
         // If this argument to this function is a enum, it'll have come in to
@@ -4867,11 +4876,16 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
             let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
             let mut i = 0;
             for vec::each(variants) |variant| {
-                if variant.node.args.len() > 0u {
-                    let llfn = get_item_val(ccx, variant.node.id);
-                    trans_enum_variant(ccx, item.id, variant,
-                                       vi[i].disr_val, degen,
-                                       none, llfn);
+                match variant.node.kind {
+                    ast::tuple_variant_kind(args) if args.len() > 0 => {
+                        let llfn = get_item_val(ccx, variant.node.id);
+                        trans_enum_variant(ccx, item.id, variant, args,
+                                           vi[i].disr_val, degen,
+                                           none, llfn);
+                    }
+                    ast::tuple_variant_kind(_) | ast::struct_variant_kind => {
+                        // Nothing to do.
+                    }
                 }
                 i += 1;
             }
@@ -5166,15 +5180,23 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
           }
 
           ast_map::node_variant(v, enm, pth) => {
-            assert v.node.args.len() != 0u;
-            let pth = vec::append(*pth,
-                                  ~[path_name(enm.ident),
-                                   path_name(v.node.name)]);
-            let llfn = match check enm.node {
-              ast::item_enum(_, _) => {
-                register_fn(ccx, v.span, pth, id)
-              }
-            };
+            let llfn;
+            match v.node.kind {
+                ast::tuple_variant_kind(args) => {
+                    assert args.len() != 0u;
+                    let pth = vec::append(*pth,
+                                          ~[path_name(enm.ident),
+                                           path_name(v.node.name)]);
+                    llfn = match check enm.node {
+                      ast::item_enum(_, _) => {
+                        register_fn(ccx, v.span, pth, id)
+                      }
+                    };
+                }
+                ast::struct_variant_kind => {
+                    fail ~"struct unexpected in get_item_val"
+                }
+            }
             set_inline_hint(llfn);
             llfn
           }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 1f79774256d..db8d2b3ae3e 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -2837,28 +2837,37 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[variant_info] {
           ast_map::node_item(@{node: ast::item_enum(variants, _), _}, _) => {
             let mut disr_val = -1;
             @vec::map(variants, |variant| {
-                let ctor_ty = node_id_to_type(cx, variant.node.id);
-                let arg_tys = {
-                    if vec::len(variant.node.args) > 0u {
-                        ty_fn_args(ctor_ty).map(|a| a.ty)
-                    } else { ~[] }
-                };
-                match variant.node.disr_expr {
-                  some (ex) => {
-                    // FIXME: issue #1417
-                    disr_val = match const_eval::eval_const_expr(cx, ex) {
-                      const_eval::const_int(val) =>val as int,
-                      _ => cx.sess.bug(~"tag_variants: bad disr expr")
+                match variant.node.kind {
+                    ast::tuple_variant_kind(args) => {
+                        let ctor_ty = node_id_to_type(cx, variant.node.id);
+                        let arg_tys = {
+                            if vec::len(args) > 0u {
+                                ty_fn_args(ctor_ty).map(|a| a.ty)
+                            } else {
+                                ~[]
+                            }
+                        };
+                        match variant.node.disr_expr {
+                          some (ex) => {
+                            // FIXME: issue #1417
+                            disr_val = match const_eval::eval_const_expr(cx,
+                                                                         ex) {
+                              const_eval::const_int(val) => val as int,
+                              _ => cx.sess.bug(~"tag_variants: bad disr expr")
+                            }
+                          }
+                          _ => disr_val += 1
+                        }
+                        @{args: arg_tys,
+                          ctor_ty: ctor_ty,
+                          name: variant.node.name,
+                          id: ast_util::local_def(variant.node.id),
+                          disr_val: disr_val
+                         }
                     }
-                  }
-                  _ => disr_val += 1
+                    ast::struct_variant_kind =>
+                        fail ~"struct variant kinds unimpl in enum_variants"
                 }
-                @{args: arg_tys,
-                  ctor_ty: ctor_ty,
-                  name: variant.node.name,
-                  id: ast_util::local_def(variant.node.id),
-                  disr_val: disr_val
-                 }
             })
           }
           _ => cx.sess.bug(~"tag_variants: id not bound to an enum")
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index c9f9e45bb78..c62861e211d 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -2073,9 +2073,13 @@ fn check_enum_variants(ccx: @crate_ctxt,
         }
         vec::push(disr_vals, disr_val);
         let ctor_ty = ty::node_id_to_type(ccx.tcx, v.node.id);
-        let arg_tys = if v.node.args.len() > 0u {
-            ty::ty_fn_args(ctor_ty).map(|a| a.ty)
-          } else { ~[] };
+        let arg_tys;
+        match v.node.kind {
+            ast::tuple_variant_kind(args) if args.len() > 0u =>
+                arg_tys = ty::ty_fn_args(ctor_ty).map(|a| a.ty),
+            ast::tuple_variant_kind(_) | ast::struct_variant_kind =>
+                arg_tys = ~[]
+        };
         vec::push(variants, @{args: arg_tys, ctor_ty: ctor_ty,
               name: v.node.name, id: local_def(v.node.id),
               disr_val: disr_val});
diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs
index c6633efe43f..037a93fdf3d 100644
--- a/src/rustc/middle/typeck/coherence.rs
+++ b/src/rustc/middle/typeck/coherence.rs
@@ -111,7 +111,6 @@ fn get_base_type_def_id(inference_context: infer_ctxt,
 class CoherenceInfo {
     // Contains implementations of methods that are inherent to a type.
     // Methods in these implementations don't need to be exported.
-
     let inherent_methods: hashmap<def_id,@dvec<@Impl>>;
 
     // Contains implementations of methods associated with a trait. For these,
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index ce41330d25d..3f68cc40f1d 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -115,20 +115,23 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
     for variants.each |variant| {
         // Nullary enum constructors get turned into constants; n-ary enum
         // constructors get turned into functions.
-        let result_ty = if vec::len(variant.node.args) == 0u {
-            enum_ty
-        } else {
-            let rs = type_rscope(rp);
-            let args = variant.node.args.map(|va| {
-                let arg_ty = ccx.to_ty(rs, va.ty);
-                {mode: ast::expl(ast::by_copy), ty: arg_ty}
-            });
-            ty::mk_fn(tcx, {purity: ast::pure_fn,
-                            proto: ast::proto_box,
-                            bounds: @~[],
-                            inputs: args,
-                            output: enum_ty,
-                            ret_style: ast::return_val})
+        let result_ty;
+        match variant.node.kind {
+            ast::tuple_variant_kind(args) if args.len() > 0 => {
+                let rs = type_rscope(rp);
+                let args = args.map(|va| {
+                    let arg_ty = ccx.to_ty(rs, va.ty);
+                    {mode: ast::expl(ast::by_copy), ty: arg_ty}
+                });
+                result_ty = ty::mk_fn(tcx, {purity: ast::pure_fn,
+                                            proto: ast::proto_box,
+                                            bounds: @~[],
+                                            inputs: args,
+                                            output: enum_ty,
+                                            ret_style: ast::return_val});
+            }
+            ast::tuple_variant_kind(_) | ast::struct_variant_kind =>
+                result_ty = enum_ty
         };
         let tpt = {bounds: ty_param_bounds(ccx, ty_params),
                    rp: rp,