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,18 +95,35 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
match def_map.find(e.id) { match def_map.find(e.id) {
Some(def_const(def_id)) | Some(def_const(def_id)) |
Some(def_fn(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) { if !ast_util::is_local(def_id) {
sess.span_err( sess.span_err(
e.span, ~"paths in constants may only refer to \ 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,
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( sess.span_err(
e.span, e.span,
~"paths in constants may only refer to \ ~"function calls in constants are limited to \
constants or functions"); structure constructors");
} }
} }
} }

View File

@ -416,6 +416,21 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
} }
} }
} }
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); } ast::expr_paren(e) => { return const_expr(cx, e); }
_ => cx.sess.span_bug(e.span, _ => cx.sess.span_bug(e.span,
~"bad constant expression type in consts::const_expr") ~"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;
}
}
}