Finish support for typechecking and translating records. Un-XFAIL rec.rs.
This commit is contained in:
parent
9c426521ee
commit
25b973df1b
@ -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 \
|
||||
|
@ -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).
|
||||
|
||||
|
@ -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: "
|
||||
|
Loading…
x
Reference in New Issue
Block a user