diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 7986352cac28..df937c92d95d 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 baa774724047..23b4bb32eeaa 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") } }