Skip to content

Commit 28882c4

Browse files
committed
librustc: Fix trans for functional record update when discarding the result.
1 parent 7e30ba8 commit 28882c4

File tree

2 files changed

+23
-24
lines changed

2 files changed

+23
-24
lines changed

src/librustc/middle/trans/base.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1947,12 +1947,10 @@ pub fn trans_named_tuple_constructor<'a>(mut bcx: &'a Block<'a>,
19471947
};
19481948

19491949
if !type_is_zero_size(ccx, result_ty) {
1950-
let repr = adt::represent_type(ccx, result_ty);
1951-
19521950
match args {
19531951
callee::ArgExprs(exprs) => {
19541952
let fields = exprs.iter().map(|x| *x).enumerate().collect::<Vec<_>>();
1955-
bcx = expr::trans_adt(bcx, &*repr, disr, fields.as_slice(),
1953+
bcx = expr::trans_adt(bcx, result_ty, disr, fields.as_slice(),
19561954
None, expr::SaveIn(llresult));
19571955
}
19581956
_ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor")

src/librustc/middle/trans/expr.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -754,10 +754,9 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
754754
dest)
755755
}
756756
ast::ExprTup(ref args) => {
757-
let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
758757
let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
759758
args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
760-
trans_adt(bcx, &*repr, 0, numbered_fields.as_slice(), None, dest)
759+
trans_adt(bcx, expr_ty(bcx, expr), 0, numbered_fields.as_slice(), None, dest)
761760
}
762761
ast::ExprLit(lit) => {
763762
match lit.node {
@@ -1089,8 +1088,7 @@ fn trans_struct<'a>(bcx: &'a Block<'a>,
10891088
}
10901089
};
10911090

1092-
let repr = adt::represent_type(bcx.ccx(), ty);
1093-
trans_adt(bcx, &*repr, discr, numbered_fields.as_slice(), optbase, dest)
1091+
trans_adt(bcx, ty, discr, numbered_fields.as_slice(), optbase, dest)
10941092
})
10951093
}
10961094

@@ -1119,25 +1117,20 @@ pub struct StructBaseInfo {
11191117
* which remaining fields are copied; see comments on `StructBaseInfo`.
11201118
*/
11211119
pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
1122-
repr: &adt::Repr,
1120+
ty: ty::t,
11231121
discr: ty::Disr,
11241122
fields: &[(uint, Gc<ast::Expr>)],
11251123
optbase: Option<StructBaseInfo>,
11261124
dest: Dest) -> &'a Block<'a> {
11271125
let _icx = push_ctxt("trans_adt");
11281126
let fcx = bcx.fcx;
1127+
let repr = adt::represent_type(bcx.ccx(), ty);
1128+
1129+
// If we don't care about the result, just make a
1130+
// temporary stack slot
11291131
let addr = match dest {
1130-
Ignore => {
1131-
for &(_i, ref e) in fields.iter() {
1132-
bcx = trans_into(bcx, &**e, Ignore);
1133-
}
1134-
for sbi in optbase.iter() {
1135-
// FIXME #7261: this moves entire base, not just certain fields
1136-
bcx = trans_into(bcx, &*sbi.expr, Ignore);
1137-
}
1138-
return bcx;
1139-
}
1140-
SaveIn(pos) => pos
1132+
SaveIn(pos) => pos,
1133+
Ignore => alloc_ty(bcx, ty, "temp"),
11411134
};
11421135

11431136
// This scope holds intermediates that must be cleaned should
@@ -1153,8 +1146,8 @@ pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
11531146
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
11541147
for &(i, t) in base.fields.iter() {
11551148
let datum = base_datum.get_element(
1156-
t, |srcval| adt::trans_field_ptr(bcx, repr, srcval, discr, i));
1157-
let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
1149+
t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
1150+
let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
11581151
bcx = datum.store_to(bcx, dest);
11591152
}
11601153
},
@@ -1167,19 +1160,27 @@ pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
11671160

11681161
// Now, we just overwrite the fields we've explicity specified
11691162
for &(i, ref e) in fields.iter() {
1170-
let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
1163+
let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
11711164
let e_ty = expr_ty_adjusted(bcx, &**e);
11721165
bcx = trans_into(bcx, &**e, SaveIn(dest));
11731166
let scope = cleanup::CustomScope(custom_cleanup_scope);
11741167
fcx.schedule_lifetime_end(scope, dest);
11751168
fcx.schedule_drop_mem(scope, dest, e_ty);
11761169
}
11771170

1178-
adt::trans_set_discr(bcx, repr, addr, discr);
1171+
adt::trans_set_discr(bcx, &*repr, addr, discr);
11791172

11801173
fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
11811174

1182-
return bcx;
1175+
// If we don't care about the result drop the temporary we made
1176+
match dest {
1177+
SaveIn(_) => bcx,
1178+
Ignore => {
1179+
bcx = glue::drop_ty(bcx, addr, ty);
1180+
base::call_lifetime_end(bcx, addr);
1181+
bcx
1182+
}
1183+
}
11831184
}
11841185

11851186

0 commit comments

Comments
 (0)