about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJed Davis <jld@panix.com>2012-12-30 20:39:15 -0800
committerJed Davis <jld@panix.com>2013-01-11 23:42:51 -0800
commitabae61257c4d866bb321bfb80ad16b7531736f7e (patch)
tree5d79540c5bdbd0eb116e0d132e5b5851b166ce27
parentf76e28aa1c093c59671749006e1a7ae203d66b7c (diff)
Allow consts to be non-nullary enum constructors
-rw-r--r--src/librustc/middle/check_const.rs3
-rw-r--r--src/librustc/middle/trans/consts.rs18
2 files changed, 20 insertions, 1 deletions
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 7986352cac2..df937c92d95 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -138,11 +138,12 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
           expr_call(callee, _, false) => {
             match def_map.find(callee.id) {
                 Some(def_struct(*)) => {}    // OK.
+                Some(def_variant(*)) => {}    // OK.
                 _ => {
                     sess.span_err(
                         e.span,
                         ~"function calls in constants are limited to \
-                          structure constructors");
+                          struct and enum constructors");
                 }
             }
           }
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index baa77472404..23b4bb32eea 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -454,6 +454,24 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
                         C_named_struct(llty, ~[ llstructbody ])
                     }
                 }
+            Some(ast::def_variant(tid, vid)) => {
+                let ety = ty::expr_ty(cx.tcx, e);
+                let degen = ty::enum_is_univariant(cx.tcx, tid);
+                let size = shape::static_size_of_enum(cx, ety);
+
+                let discrim = base::get_discrim_val(cx, e.span, tid, vid);
+                let c_args = C_struct(args.map(|a| const_expr(cx, *a)));
+
+                let fields = if !degen {
+                    ~[discrim, c_args]
+                } else if size == 0 {
+                    ~[discrim]
+                } else {
+                    ~[c_args]
+                };
+
+                C_struct(fields)
+            }
                 _ => cx.sess.span_bug(e.span, ~"expected a struct def")
             }
           }