Skip to content

Commit 25b973d

Browse files
committed
Finish support for typechecking and translating records. Un-XFAIL rec.rs.
1 parent 9c42652 commit 25b973d

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ TEST_XFAILS_SELF := $(filter-out \
534534
item-name-overload.rs \
535535
lazy-init.rs \
536536
multiline-comment.rs \
537+
rec.rs \
537538
return-nil.rs \
538539
tup.rs \
539540
u32-decr.rs \

src/comp/middle/trans.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,13 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
280280
}
281281
ret T_struct(tys);
282282
}
283+
case (typeck.ty_rec(?fields)) {
284+
let vec[TypeRef] tys = vec();
285+
for (typeck.field f in fields) {
286+
tys += type_of(cx, f.ty);
287+
}
288+
ret T_struct(tys);
289+
}
283290
case (typeck.ty_fn(?args, ?out)) {
284291
let vec[TypeRef] atys = vec(T_taskptr());
285292
for (typeck.arg arg in args) {
@@ -1106,6 +1113,12 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
11061113
auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
11071114
ret tup(res(r.bcx, v), lv._1);
11081115
}
1116+
case (typeck.ty_rec(?fields)) {
1117+
let uint ix = typeck.field_idx(cx.fcx.ccx.sess, sp,
1118+
field, fields);
1119+
auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
1120+
ret tup(res(r.bcx, v), lv._1);
1121+
}
11091122
}
11101123
cx.fcx.ccx.sess.unimpl("field variant in trans_field");
11111124
fail;
@@ -1201,6 +1214,23 @@ impure fn trans_tup(@block_ctxt cx, vec[tup(ast.mutability, @ast.expr)] args,
12011214
ret res(r.bcx, tup_val);
12021215
}
12031216

1217+
impure fn trans_rec(@block_ctxt cx, vec[tup(ast.ident, @ast.expr)] args,
1218+
&ast.ann ann) -> result {
1219+
auto ty = node_type(cx.fcx.ccx, ann);
1220+
auto tup_val = cx.build.Alloca(ty);
1221+
let int i = 0;
1222+
auto r = res(cx, C_nil());
1223+
for (tup(ast.ident, @ast.expr) arg in args) {
1224+
auto t = typeck.expr_ty(arg._1);
1225+
auto src_res = trans_expr(r.bcx, arg._1);
1226+
auto dst_elt = r.bcx.build.GEP(tup_val, vec(C_int(0), C_int(i)));
1227+
// FIXME: calculate copy init-ness in typestate.
1228+
r = copy_ty(src_res.bcx, true, dst_elt, src_res.val, t);
1229+
i += 1;
1230+
}
1231+
ret res(r.bcx, tup_val);
1232+
}
1233+
12041234

12051235

12061236
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 {
12611291
ret trans_tup(cx, args, ann);
12621292
}
12631293

1294+
case (ast.expr_rec(?args, ?ann)) {
1295+
ret trans_rec(cx, args, ann);
1296+
}
1297+
12641298
// lval cases fall through to trans_lval and then
12651299
// possibly load the result (if it's non-structural).
12661300

src/comp/middle/typeck.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,19 @@ fn field_num(session.session sess, &span sp, &ast.ident id) -> uint {
474474
ret accum;
475475
}
476476

477+
fn field_idx(session.session sess, &span sp,
478+
&ast.ident id, vec[field] fields) -> uint {
479+
let uint i = 0u;
480+
for (field f in fields) {
481+
if (_str.eq(f.label, id)) {
482+
ret i;
483+
}
484+
i += 1u;
485+
}
486+
sess.span_err(sp, "unknown field '" + id + "' of record");
487+
fail;
488+
}
489+
477490
// Type utilities
478491

479492
// FIXME: remove me when == works on these tags.
@@ -1346,6 +1359,22 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
13461359
ast.expr_tup(args_1, ann));
13471360
}
13481361

1362+
case (ast.expr_rec(?args, _)) {
1363+
let vec[tup(ast.ident, @ast.expr)] args_1 = vec();
1364+
let vec[field] args_t = vec();
1365+
1366+
for (tup(ast.ident, @ast.expr) arg in args) {
1367+
auto expr_1 = check_expr(fcx, arg._1);
1368+
args_1 += tup(arg._0, expr_1);
1369+
append[field](args_t,rec(label=arg._0,
1370+
ty=expr_ty(expr_1)));
1371+
}
1372+
1373+
auto ann = ast.ann_type(plain_ty(ty_rec(args_t)));
1374+
ret @fold.respan[ast.expr_](expr.span,
1375+
ast.expr_rec(args_1, ann));
1376+
}
1377+
13491378
case (ast.expr_field(?base, ?field, _)) {
13501379
auto base_1 = check_expr(fcx, base);
13511380
auto base_t = expr_ty(base_1);
@@ -1363,6 +1392,21 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
13631392
field,
13641393
ann));
13651394
}
1395+
1396+
case (ty_rec(?fields)) {
1397+
let uint ix = field_idx(fcx.ccx.sess,
1398+
expr.span, field, fields);
1399+
if (ix >= _vec.len[typeck.field](fields)) {
1400+
fcx.ccx.sess.span_err(expr.span,
1401+
"bad index on record");
1402+
}
1403+
auto ann = ast.ann_type(fields.(ix).ty);
1404+
ret @fold.respan[ast.expr_](expr.span,
1405+
ast.expr_field(base_1,
1406+
field,
1407+
ann));
1408+
}
1409+
13661410
case (_) {
13671411
fcx.ccx.sess.unimpl("base type for expr_field "
13681412
+ "in typeck.check_expr: "

0 commit comments

Comments
 (0)