librustc: Implement tuple struct constants. r=brson

This commit is contained in:
Patrick Walton 2012-11-30 16:29:28 -08:00
parent 5b5a0df7ee
commit 8fa306a0ad
3 changed files with 51 additions and 6 deletions

View File

@ -95,19 +95,36 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
match def_map.find(e.id) {
Some(def_const(def_id)) |
Some(def_fn(def_id, _)) |
Some(def_variant(_, def_id)) => {
Some(def_variant(_, def_id)) |
Some(def_class(def_id)) => {
if !ast_util::is_local(def_id) {
sess.span_err(
e.span, ~"paths in constants may only refer to \
crate-local constants or functions");
crate-local constants, functions, or \
structs");
}
}
_ => {
Some(def) => {
debug!("(checking const) found bad def: %?", def);
sess.span_err(
e.span,
~"paths in constants may only refer to \
constants or functions");
fmt!("paths in constants may only refer to \
constants or functions"));
}
None => {
sess.span_bug(e.span, ~"unbound path in const?!");
}
}
}
expr_call(callee, _, false) => {
match def_map.find(callee.id) {
Some(def_class(*)) => {} // OK.
_ => {
sess.span_err(
e.span,
~"function calls in constants are limited to \
structure constructors");
}
}
}
expr_paren(e) => { check_expr(sess, def_map, method_map,

View File

@ -416,7 +416,22 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
}
}
}
ast::expr_paren(e) => { return const_expr(cx, e); }
ast::expr_call(callee, args, _) => {
match cx.tcx.def_map.find(callee.id) {
Some(ast::def_class(def_id)) => {
let ety = ty::expr_ty(cx.tcx, e);
let llty = type_of::type_of(cx, ety);
let llstructbody = C_struct(args.map(|a| const_expr(cx, *a)));
if ty::ty_dtor(cx.tcx, def_id).is_present() {
C_named_struct(llty, ~[ llstructbody, C_u8(0) ])
} else {
C_named_struct(llty, ~[ llstructbody ])
}
}
_ => cx.sess.span_bug(e.span, ~"expected a struct def")
}
}
ast::expr_paren(e) => { return const_expr(cx, e); }
_ => cx.sess.span_bug(e.span,
~"bad constant expression type in consts::const_expr")
};

View File

@ -0,0 +1,13 @@
struct Bar(int, int);
const X: Bar = Bar(1, 2);
fn main() {
match X {
Bar(x, y) => {
assert x == 1;
assert y == 2;
}
}
}