From 175be53e3f62664e445a57c2ad9e23f4bcb296b2 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 7 Aug 2012 17:11:43 -0700 Subject: [PATCH] Translate const structs. --- src/rustc/middle/check_const.rs | 1 + src/rustc/middle/const_eval.rs | 1 + src/rustc/middle/trans/consts.rs | 26 ++++++++++++++++++++++++++ src/test/run-pass/const-struct.rs | 14 ++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/test/run-pass/const-struct.rs diff --git a/src/rustc/middle/check_const.rs b/src/rustc/middle/check_const.rs index 0cddd359b55c..e8f3ecb35aca 100644 --- a/src/rustc/middle/check_const.rs +++ b/src/rustc/middle/check_const.rs @@ -103,6 +103,7 @@ fn check_expr(sess: session, def_map: resolve3::DefMap, expr_vec(_, m_imm) | expr_addr_of(m_imm, _) | expr_tup(*) | + expr_struct(*) | expr_rec(*) => { } expr_addr_of(*) => { sess.span_err( diff --git a/src/rustc/middle/const_eval.rs b/src/rustc/middle/const_eval.rs index e15ef5860424..01b07d2b34e5 100644 --- a/src/rustc/middle/const_eval.rs +++ b/src/rustc/middle/const_eval.rs @@ -95,6 +95,7 @@ fn classify(e: @expr, } } + ast::expr_struct(_, fs, none) | ast::expr_rec(fs, none) => { let cs = do vec::map(fs) |f| { if f.node.mutbl == ast::m_imm { diff --git a/src/rustc/middle/trans/consts.rs b/src/rustc/middle/trans/consts.rs index 3f17352b9157..f4c67efdd773 100644 --- a/src/rustc/middle/trans/consts.rs +++ b/src/rustc/middle/trans/consts.rs @@ -153,6 +153,32 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef { ast::expr_tup(es) => { C_struct(es.map(|e| const_expr(cx, e))) } + ast::expr_struct(_, fs, _) => { + let ety = ty::expr_ty(cx.tcx, e); + let llty = type_of::type_of(cx, ety); + let class_fields = + match ty::get(ety).struct { + ty::ty_class(clsid, _) => + ty::lookup_class_fields(cx.tcx, clsid), + _ => + cx.tcx.sess.span_bug(e.span, + ~"didn't resolve to a struct") + }; + let mut cs = ~[]; + for class_fields.each |class_field| { + let mut found = false; + for fs.each |field| { + if class_field.ident == field.node.ident { + found = true; + vec::push(cs, const_expr(cx, field.node.expr)); + } + } + if !found { + cx.tcx.sess.span_bug(e.span, ~"missing struct field"); + } + } + C_named_struct(llty, cs) + } ast::expr_rec(fs, none) => { C_struct(fs.map(|f| const_expr(cx, f.node.expr))) } diff --git a/src/test/run-pass/const-struct.rs b/src/test/run-pass/const-struct.rs new file mode 100644 index 000000000000..132ecb935cf8 --- /dev/null +++ b/src/test/run-pass/const-struct.rs @@ -0,0 +1,14 @@ + +struct foo { a: int; b: int; c: int; } + +const x : foo = foo { a:1, b:2, c: 3 }; +const y : foo = foo { b:2, c:3, a: 1 }; +const z : &foo = &foo { a: 10, b: 22, c: 12 }; + +fn main() { + assert x.b == 2; + assert x == y; + assert z.b == 22; + io::println(fmt!{"0x%x", x.b as uint}); + io::println(fmt!{"0x%x", z.c as uint}); +}