aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/comp/middle/trans.rs34
-rw-r--r--src/comp/middle/typeck.rs44
3 files changed, 79 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
index c965f7b6..f41ea356 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -534,6 +534,7 @@ TEST_XFAILS_SELF := $(filter-out \
item-name-overload.rs \
lazy-init.rs \
multiline-comment.rs \
+ rec.rs \
return-nil.rs \
tup.rs \
u32-decr.rs \
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 8caaf5f7..d5b73826 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -280,6 +280,13 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
}
ret T_struct(tys);
}
+ case (typeck.ty_rec(?fields)) {
+ let vec[TypeRef] tys = vec();
+ for (typeck.field f in fields) {
+ tys += type_of(cx, f.ty);
+ }
+ ret T_struct(tys);
+ }
case (typeck.ty_fn(?args, ?out)) {
let vec[TypeRef] atys = vec(T_taskptr());
for (typeck.arg arg in args) {
@@ -1106,6 +1113,12 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
ret tup(res(r.bcx, v), lv._1);
}
+ case (typeck.ty_rec(?fields)) {
+ let uint ix = typeck.field_idx(cx.fcx.ccx.sess, sp,
+ field, fields);
+ auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
+ ret tup(res(r.bcx, v), lv._1);
+ }
}
cx.fcx.ccx.sess.unimpl("field variant in trans_field");
fail;
@@ -1201,6 +1214,23 @@ impure fn trans_tup(@block_ctxt cx, vec[tup(ast.mutability, @ast.expr)] args,
ret res(r.bcx, tup_val);
}
+impure fn trans_rec(@block_ctxt cx, vec[tup(ast.ident, @ast.expr)] args,
+ &ast.ann ann) -> result {
+ auto ty = node_type(cx.fcx.ccx, ann);
+ auto tup_val = cx.build.Alloca(ty);
+ let int i = 0;
+ auto r = res(cx, C_nil());
+ for (tup(ast.ident, @ast.expr) arg in args) {
+ auto t = typeck.expr_ty(arg._1);
+ auto src_res = trans_expr(r.bcx, arg._1);
+ auto dst_elt = r.bcx.build.GEP(tup_val, vec(C_int(0), C_int(i)));
+ // FIXME: calculate copy init-ness in typestate.
+ r = copy_ty(src_res.bcx, true, dst_elt, src_res.val, t);
+ i += 1;
+ }
+ ret res(r.bcx, tup_val);
+}
+
impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
@@ -1261,6 +1291,10 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
ret trans_tup(cx, args, ann);
}
+ case (ast.expr_rec(?args, ?ann)) {
+ ret trans_rec(cx, args, ann);
+ }
+
// lval cases fall through to trans_lval and then
// possibly load the result (if it's non-structural).
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 25a42e9a..78dff420 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -474,6 +474,19 @@ fn field_num(session.session sess, &span sp, &ast.ident id) -> uint {
ret accum;
}
+fn field_idx(session.session sess, &span sp,
+ &ast.ident id, vec[field] fields) -> uint {
+ let uint i = 0u;
+ for (field f in fields) {
+ if (_str.eq(f.label, id)) {
+ ret i;
+ }
+ i += 1u;
+ }
+ sess.span_err(sp, "unknown field '" + id + "' of record");
+ fail;
+}
+
// Type utilities
// FIXME: remove me when == works on these tags.
@@ -1346,6 +1359,22 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ast.expr_tup(args_1, ann));
}
+ case (ast.expr_rec(?args, _)) {
+ let vec[tup(ast.ident, @ast.expr)] args_1 = vec();
+ let vec[field] args_t = vec();
+
+ for (tup(ast.ident, @ast.expr) arg in args) {
+ auto expr_1 = check_expr(fcx, arg._1);
+ args_1 += tup(arg._0, expr_1);
+ append[field](args_t,rec(label=arg._0,
+ ty=expr_ty(expr_1)));
+ }
+
+ auto ann = ast.ann_type(plain_ty(ty_rec(args_t)));
+ ret @fold.respan[ast.expr_](expr.span,
+ ast.expr_rec(args_1, ann));
+ }
+
case (ast.expr_field(?base, ?field, _)) {
auto base_1 = check_expr(fcx, base);
auto base_t = expr_ty(base_1);
@@ -1363,6 +1392,21 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
field,
ann));
}
+
+ case (ty_rec(?fields)) {
+ let uint ix = field_idx(fcx.ccx.sess,
+ expr.span, field, fields);
+ if (ix >= _vec.len[typeck.field](fields)) {
+ fcx.ccx.sess.span_err(expr.span,
+ "bad index on record");
+ }
+ auto ann = ast.ann_type(fields.(ix).ty);
+ ret @fold.respan[ast.expr_](expr.span,
+ ast.expr_field(base_1,
+ field,
+ ann));
+ }
+
case (_) {
fcx.ccx.sess.unimpl("base type for expr_field "
+ "in typeck.check_expr: "