]> git.lizzy.rs Git - rust.git/commitdiff
Added support for struct-like enum variants in middle::ty::enum_variants().
authorMichael Woerister <michaelwoerister@gmail>
Tue, 2 Jul 2013 21:34:35 +0000 (23:34 +0200)
committerMichael Woerister <michaelwoerister@gmail>
Tue, 2 Jul 2013 21:35:36 +0000 (23:35 +0200)
src/librustc/middle/ty.rs

index bbf548d2659a1e77c2e501be71ce07f305fd0ffa..8c70c6204768501a19e9c120d20817f9b1fa0f3c 100644 (file)
@@ -3816,41 +3816,62 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
                 }, _) => {
             let mut disr_val = -1;
             @enum_definition.variants.iter().transform(|variant| {
+
+                let ctor_ty = node_id_to_type(cx, variant.node.id);
+
                 match variant.node.kind {
                     ast::tuple_variant_kind(ref args) => {
-                        let ctor_ty = node_id_to_type(cx, variant.node.id);
-                        let arg_tys = {
-                            if args.len() > 0u {
-                                ty_fn_args(ctor_ty).map(|a| *a)
-                            } else {
+                        let arg_tys = if args.len() > 0u {
+                                ty_fn_args(ctor_ty).map(|a| *a) }
+                            else {
                                 ~[]
-                            }
-                        };
+                            };
+
                         match variant.node.disr_expr {
                           Some (ex) => {
                             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")
+                              _ => cx.sess.bug("enum_variants: bad disr expr")
                             }
                           }
                           _ => disr_val += 1
                         }
-                        @VariantInfo_{args: arg_tys,
-                          ctor_ty: ctor_ty,
-                          name: variant.node.name,
-                          id: ast_util::local_def(variant.node.id),
-                          disr_val: disr_val,
-                          vis: variant.node.vis
+                        @VariantInfo_{
+                            args: arg_tys,
+                            ctor_ty: ctor_ty,
+                            name: variant.node.name,
+                            id: ast_util::local_def(variant.node.id),
+                            disr_val: disr_val,
+                            vis: variant.node.vis
                          }
-                    }
-                    ast::struct_variant_kind(_) => {
-                        fail!("struct variant kinds unimpl in enum_variants")
+                    },
+                    ast::struct_variant_kind(struct_def) => {
+                        let arg_tys =
+                            // Is this check needed for structs too, or are they always guaranteed
+                            // to have a valid constructor function?
+                            if struct_def.fields.len() > 0 {
+                                ty_fn_args(ctor_ty).map(|a| *a)
+                            } else {
+                                ~[]
+                            };
+
+                        assert!(variant.node.disr_expr.is_none());
+                        disr_val += 1;
+
+                        @VariantInfo_{
+                            args: arg_tys,
+                            ctor_ty: ctor_ty,
+                            name: variant.node.name,
+                            id: ast_util::local_def(variant.node.id),
+                            disr_val: disr_val,
+                            vis: variant.node.vis
+                        }
                     }
                 }
             }).collect()
           }
-          _ => cx.sess.bug("tag_variants: id not bound to an enum")
+          _ => cx.sess.bug("enum_variants: id not bound to an enum")
         }
     };
     cx.enum_var_cache.insert(id, result);