Translate const structs.

This commit is contained in:
Graydon Hoare 2012-08-07 17:11:43 -07:00
parent 4be8239ac2
commit 175be53e3f
4 changed files with 42 additions and 0 deletions

View file

@ -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(

View file

@ -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 {

View file

@ -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)))
}