Skip to content

Commit 196b2b9

Browse files
committed
Make sure trans translates record fields in the order they appear in code
This prevents surprising side-effect orders, and makes them easier for the other passes to deal with.
1 parent 68db68c commit 196b2b9

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

src/comp/middle/trans.rs

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4035,34 +4035,35 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
40354035
save_in(pos) { pos }
40364036
};
40374037

4038-
let base_val = alt base {
4038+
let ty_fields = alt ty::struct(bcx_tcx(bcx), t) { ty::ty_rec(f) { f } };
4039+
let temp_cleanups = [];
4040+
for fld in fields {
4041+
let ix = option::get(vec::position_pred({|ft|
4042+
str::eq(fld.node.ident, ft.ident)
4043+
}, ty_fields));
4044+
let dst = GEP_tup_like_1(bcx, t, addr, [0, ix as int]);
4045+
bcx = trans_expr_save_in(dst.bcx, fld.node.expr, dst.val);
4046+
add_clean_temp_mem(bcx, dst.val, ty_fields[ix].mt.ty);
4047+
temp_cleanups += [dst.val];
4048+
}
4049+
alt base {
40394050
some(bexp) {
4040-
let base_res = trans_temp_expr(bcx, bexp);
4041-
bcx = base_res.bcx;
4042-
base_res.val
4051+
let {bcx: cx, val: base_val} = trans_temp_expr(bcx, bexp), i = 0;
4052+
bcx = cx;
4053+
// Copy over inherited fields
4054+
for tf in ty_fields {
4055+
if !vec::any({|f| str::eq(f.node.ident, tf.ident)}, fields) {
4056+
let dst = GEP_tup_like_1(bcx, t, addr, [0, i]);
4057+
let base = GEP_tup_like_1(bcx, t, base_val, [0, i]);
4058+
let val = load_if_immediate(base.bcx, base.val, tf.mt.ty);
4059+
bcx = copy_val(base.bcx, INIT, dst.val, val, tf.mt.ty);
4060+
}
4061+
i += 1;
4062+
}
40434063
}
4044-
none. { C_nil() }
4064+
none. {}
40454065
};
40464066

4047-
let ty_fields = alt ty::struct(bcx_tcx(bcx), t) { ty::ty_rec(f) { f } };
4048-
let temp_cleanups = [], i = 0;
4049-
for tf in ty_fields {
4050-
let dst = GEP_tup_like_1(bcx, t, addr, [0, i]);
4051-
bcx = dst.bcx;
4052-
alt vec::find({|f| str::eq(f.node.ident, tf.ident)}, fields) {
4053-
some(f) {
4054-
bcx = trans_expr_save_in(bcx, f.node.expr, dst.val);
4055-
}
4056-
none. {
4057-
let base = GEP_tup_like_1(bcx, t, base_val, [0, i]);
4058-
let val = load_if_immediate(base.bcx, base.val, tf.mt.ty);
4059-
bcx = copy_val(base.bcx, INIT, dst.val, val, tf.mt.ty);
4060-
}
4061-
}
4062-
add_clean_temp_mem(bcx, dst.val, tf.mt.ty);
4063-
temp_cleanups += [dst.val];
4064-
i += 1;
4065-
}
40664067
// Now revoke the cleanups as we pass responsibility for the data
40674068
// structure on to the caller
40684069
for cleanup in temp_cleanups { revoke_clean(bcx, cleanup); }

0 commit comments

Comments
 (0)