Skip to content

Commit 8fa306a

Browse files
committed
librustc: Implement tuple struct constants. r=brson
1 parent 5b5a0df commit 8fa306a

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

src/librustc/middle/check_const.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,36 @@ fn check_expr(sess: Session, def_map: resolve::DefMap,
9595
match def_map.find(e.id) {
9696
Some(def_const(def_id)) |
9797
Some(def_fn(def_id, _)) |
98-
Some(def_variant(_, def_id)) => {
98+
Some(def_variant(_, def_id)) |
99+
Some(def_class(def_id)) => {
99100
if !ast_util::is_local(def_id) {
100101
sess.span_err(
101102
e.span, ~"paths in constants may only refer to \
102-
crate-local constants or functions");
103+
crate-local constants, functions, or \
104+
structs");
103105
}
104106
}
105-
_ => {
107+
Some(def) => {
108+
debug!("(checking const) found bad def: %?", def);
106109
sess.span_err(
107110
e.span,
108-
~"paths in constants may only refer to \
109-
constants or functions");
111+
fmt!("paths in constants may only refer to \
112+
constants or functions"));
110113
}
114+
None => {
115+
sess.span_bug(e.span, ~"unbound path in const?!");
116+
}
117+
}
118+
}
119+
expr_call(callee, _, false) => {
120+
match def_map.find(callee.id) {
121+
Some(def_class(*)) => {} // OK.
122+
_ => {
123+
sess.span_err(
124+
e.span,
125+
~"function calls in constants are limited to \
126+
structure constructors");
127+
}
111128
}
112129
}
113130
expr_paren(e) => { check_expr(sess, def_map, method_map,

src/librustc/middle/trans/consts.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,22 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
416416
}
417417
}
418418
}
419-
ast::expr_paren(e) => { return const_expr(cx, e); }
419+
ast::expr_call(callee, args, _) => {
420+
match cx.tcx.def_map.find(callee.id) {
421+
Some(ast::def_class(def_id)) => {
422+
let ety = ty::expr_ty(cx.tcx, e);
423+
let llty = type_of::type_of(cx, ety);
424+
let llstructbody = C_struct(args.map(|a| const_expr(cx, *a)));
425+
if ty::ty_dtor(cx.tcx, def_id).is_present() {
426+
C_named_struct(llty, ~[ llstructbody, C_u8(0) ])
427+
} else {
428+
C_named_struct(llty, ~[ llstructbody ])
429+
}
430+
}
431+
_ => cx.sess.span_bug(e.span, ~"expected a struct def")
432+
}
433+
}
434+
ast::expr_paren(e) => { return const_expr(cx, e); }
420435
_ => cx.sess.span_bug(e.span,
421436
~"bad constant expression type in consts::const_expr")
422437
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
struct Bar(int, int);
2+
3+
const X: Bar = Bar(1, 2);
4+
5+
fn main() {
6+
match X {
7+
Bar(x, y) => {
8+
assert x == 1;
9+
assert y == 2;
10+
}
11+
}
12+
}
13+

0 commit comments

Comments
 (0)