Skip to content

Commit 3e6636f

Browse files
committed
---
yaml --- r: 45017 b: refs/heads/master c: fdd2845 h: refs/heads/master i: 45015: 92cfc01 v: v3
1 parent 8abcdad commit 3e6636f

File tree

2 files changed

+74
-107
lines changed

2 files changed

+74
-107
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 5cbc2571c1a4df75750fcb726120db06eb61c1f9
2+
refs/heads/master: fdd28451f68a14916c57c50baa045132316cedc6
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d9689399d091c3265f00434a69c551a61c28dc
55
refs/heads/try: ef355f6332f83371e4acf04fc4eb940ab41d78d3

trunk/src/librustc/middle/trans/expr.rs

Lines changed: 73 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,8 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
604604
}
605605
ast::expr_tup(ref args) => {
606606
let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
607-
return trans_adt(bcx, &repr, 0, *args, dest);
607+
return trans_adt(bcx, &repr, 0, args.mapi(|i, arg| (i, *arg)),
608+
None, dest);
608609
}
609610
ast::expr_lit(@codemap::spanned {node: ast::lit_str(s), _}) => {
610611
return tvec::trans_lit_str(bcx, expr, s, dest);
@@ -885,7 +886,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
885886
let _icx = bcx.insn_ctxt("trans_rec_field");
886887

887888
let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base));
888-
do with_field_tys(bcx.tcx(), base_datum.ty, None) |_dtor, field_tys| {
889+
do with_field_tys(bcx.tcx(), base_datum.ty, None) |_disr, field_tys| {
889890
let ix = ty::field_idx_strict(bcx.tcx(), field, field_tys);
890891
DatumBlock {
891892
datum: base_datum.GEPi(bcx,
@@ -1098,15 +1099,14 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
10981099
pub fn with_field_tys<R>(tcx: ty::ctxt,
10991100
ty: ty::t,
11001101
node_id_opt: Option<ast::node_id>,
1101-
op: fn(bool, (&[ty::field])) -> R) -> R {
1102+
op: fn(int, (&[ty::field])) -> R) -> R {
11021103
match ty::get(ty).sty {
11031104
ty::ty_rec(ref fields) => {
1104-
op(false, *fields)
1105+
op(0, *fields)
11051106
}
11061107

11071108
ty::ty_struct(did, ref substs) => {
1108-
let has_dtor = ty::ty_dtor(tcx, did).is_present();
1109-
op(has_dtor, struct_mutable_fields(tcx, did, substs))
1109+
op(0, struct_mutable_fields(tcx, did, substs))
11101110
}
11111111

11121112
ty::ty_enum(_, ref substs) => {
@@ -1120,8 +1120,10 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
11201120
}
11211121
Some(node_id) => {
11221122
match tcx.def_map.get(&node_id) {
1123-
ast::def_variant(_, variant_id) => {
1124-
op(false, struct_mutable_fields(
1123+
ast::def_variant(enum_id, variant_id) => {
1124+
let variant_info = ty::enum_variant_with_id(
1125+
tcx, enum_id, variant_id);
1126+
op(variant_info.disr_val, struct_mutable_fields(
11251127
tcx, variant_id, substs))
11261128
}
11271129
_ => {
@@ -1150,135 +1152,100 @@ fn trans_rec_or_struct(bcx: block,
11501152
let _icx = bcx.insn_ctxt("trans_rec");
11511153
let mut bcx = bcx;
11521154

1153-
// Handle the case where the result is ignored.
1154-
let addr;
1155-
match dest {
1156-
SaveIn(p) => {
1157-
addr = p;
1158-
}
1159-
Ignore => {
1160-
// just evaluate the values for each field and drop them
1161-
// on the floor
1162-
for vec::each(fields) |fld| {
1163-
bcx = trans_into(bcx, fld.node.expr, Ignore);
1164-
}
1165-
return bcx;
1166-
}
1167-
}
1168-
1169-
// If this is a struct-like variant, write in the discriminant if
1170-
// necessary, position the address at the right location, and cast the
1171-
// address.
11721155
let ty = node_id_type(bcx, id);
11731156
let tcx = bcx.tcx();
1174-
let addr = match ty::get(ty).sty {
1175-
ty::ty_enum(_, ref substs) => {
1176-
match tcx.def_map.get(&id) {
1177-
ast::def_variant(enum_id, variant_id) => {
1178-
let variant_info = ty::enum_variant_with_id(
1179-
tcx, enum_id, variant_id);
1180-
let addr = if ty::enum_is_univariant(tcx, enum_id) {
1181-
addr
1182-
} else {
1183-
Store(bcx,
1184-
C_int(bcx.ccx(), variant_info.disr_val),
1185-
GEPi(bcx, addr, [0, 0]));
1186-
GEPi(bcx, addr, [0, 1])
1187-
};
1188-
let fields = ty::struct_mutable_fields(
1189-
tcx, variant_id, substs);
1190-
let field_lltys = do fields.map |field| {
1191-
type_of::type_of(bcx.ccx(),
1192-
ty::subst_tps(
1193-
tcx, substs.tps, None, field.mt.ty))
1194-
};
1195-
PointerCast(bcx, addr,
1196-
T_ptr(T_struct(~[T_struct(field_lltys)])))
1157+
do with_field_tys(tcx, ty, Some(id)) |discr, field_tys| {
1158+
let mut need_base = vec::from_elem(field_tys.len(), true);
1159+
1160+
let numbered_fields = do fields.map |field| {
1161+
match do vec::position(field_tys) |field_ty| {
1162+
field_ty.ident == field.node.ident
1163+
} {
1164+
Some(i) => {
1165+
need_base[i] = false;
1166+
(i, field.node.expr)
11971167
}
1198-
_ => {
1199-
tcx.sess.bug(~"resolve didn't write the right def in for \
1200-
this struct-like variant")
1168+
None => {
1169+
tcx.sess.span_bug(field.span,
1170+
~"Couldn't find field in struct type")
12011171
}
12021172
}
1203-
}
1204-
_ => addr
1205-
};
1206-
1207-
do with_field_tys(tcx, ty, Some(id)) |has_dtor, field_tys| {
1208-
// evaluate each of the fields and store them into their
1209-
// correct locations
1210-
let mut temp_cleanups = ~[];
1211-
for fields.each |field| {
1212-
let ix = ty::field_idx_strict(tcx, field.node.ident, field_tys);
1213-
let dest = GEPi(bcx, addr, struct_field(ix));
1214-
bcx = trans_into(bcx, field.node.expr, SaveIn(dest));
1215-
add_clean_temp_mem(bcx, dest, field_tys[ix].mt.ty);
1216-
temp_cleanups.push(dest);
1217-
}
1218-
1219-
// copy over any remaining fields from the base (for
1220-
// functional record update)
1221-
for base.each |base_expr| {
1222-
let base_datum = unpack_datum!(
1223-
bcx, trans_to_datum(bcx, *base_expr));
1224-
1225-
// Copy/move over inherited fields
1226-
for field_tys.eachi |i, field_ty| {
1227-
if !fields.any(|f| f.node.ident == field_ty.ident) {
1228-
let dest = GEPi(bcx, addr, struct_field(i));
1229-
let base_field =
1230-
base_datum.GEPi(bcx,
1231-
struct_field(i),
1232-
field_ty.mt.ty,
1233-
ZeroMem);
1234-
bcx = base_field.store_to(bcx, base_expr.id, INIT, dest);
1173+
};
1174+
let optbase = match base {
1175+
Some(base_expr) => {
1176+
let mut leftovers = ~[];
1177+
for need_base.eachi |i, b| {
1178+
if *b {
1179+
leftovers.push((i, field_tys[i].mt.ty))
1180+
}
12351181
}
1182+
Some(StructBaseInfo {expr: base_expr,
1183+
fields: leftovers })
12361184
}
1237-
}
1238-
1239-
// Add the drop flag if necessary.
1240-
if has_dtor {
1241-
let dest = GEPi(bcx, addr, struct_dtor());
1242-
Store(bcx, C_u8(1), dest);
1243-
}
1185+
None => {
1186+
if need_base.any(|b| *b) {
1187+
// XXX should be span bug
1188+
tcx.sess.bug(~"missing fields and no base expr")
1189+
}
1190+
None
1191+
}
1192+
};
12441193

1245-
// Now revoke the cleanups as we pass responsibility for the data
1246-
// structure on to the caller
1247-
for temp_cleanups.each |cleanup| {
1248-
revoke_clean(bcx, *cleanup);
1249-
}
1250-
bcx
1194+
let repr = adt::represent_type(bcx.ccx(), ty);
1195+
trans_adt(bcx, &repr, discr, numbered_fields, optbase, dest)
12511196
}
12521197
}
12531198

1254-
fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, elts: &[@ast::expr],
1199+
struct StructBaseInfo {
1200+
expr: @ast::expr,
1201+
fields: ~[(uint, ty::t)]
1202+
}
1203+
1204+
fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
1205+
fields: &[(uint, @ast::expr)],
1206+
optbase: Option<StructBaseInfo>,
12551207
dest: Dest) -> block {
1256-
let _icx = bcx.insn_ctxt("trans_tup");
1208+
let _icx = bcx.insn_ctxt("trans_adt");
12571209
let mut bcx = bcx;
12581210
let addr = match dest {
12591211
Ignore => {
1260-
for vec::each(elts) |ex| {
1261-
bcx = trans_into(bcx, *ex, Ignore);
1212+
for fields.each |&(_i, e)| {
1213+
bcx = trans_into(bcx, e, Ignore);
1214+
}
1215+
for optbase.each |sbi| {
1216+
bcx = trans_into(bcx, sbi.expr, Ignore);
12621217
}
12631218
return bcx;
12641219
}
1265-
SaveIn(pos) => pos,
1220+
SaveIn(pos) => pos
12661221
};
12671222
let mut temp_cleanups = ~[];
12681223
adt::trans_set_discr(bcx, repr, addr, discr);
1269-
for vec::eachi(elts) |i, e| {
1224+
for fields.each |&(i, e)| {
12701225
let dest = adt::trans_GEP(bcx, repr, addr, discr, i);
1271-
let e_ty = expr_ty(bcx, *e);
1272-
bcx = trans_into(bcx, *e, SaveIn(dest));
1226+
let e_ty = expr_ty(bcx, e);
1227+
bcx = trans_into(bcx, e, SaveIn(dest));
12731228
add_clean_temp_mem(bcx, dest, e_ty);
12741229
temp_cleanups.push(dest);
12751230
}
1231+
for optbase.each |base| {
1232+
let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base.expr));
1233+
for base.fields.each |&(i, t)| {
1234+
let datum =
1235+
// XXX convert this to adt
1236+
base_datum.GEPi(bcx, struct_field(i), t, ZeroMem);
1237+
let dest = adt::trans_GEP(bcx, repr, addr, discr, i);
1238+
bcx = datum.store_to(bcx, base.expr.id, INIT, dest);
1239+
}
1240+
}
1241+
12761242
for vec::each(temp_cleanups) |cleanup| {
12771243
revoke_clean(bcx, *cleanup);
12781244
}
12791245
return bcx;
12801246
}
12811247

1248+
12821249
fn trans_immediate_lit(bcx: block, expr: @ast::expr,
12831250
lit: ast::lit) -> DatumBlock {
12841251
// must not be a string constant, that is a RvalueDpsExpr

0 commit comments

Comments
 (0)