}
/**
- * Begin initializing a new value of the given case of the given
- * representation. The fields, if any, should then be initialized via
- * `trans_field_ptr`.
+ * Set the discriminant for a new value of the given case of the given
+ * representation.
*/
-pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
+pub fn trans_set_discr(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) {
match *r {
CEnum(ity, min, max) => {
assert_discr_in_range(ity, min, max, discr);
if !type_is_zero_size(ccx, result_ty) {
let repr = adt::represent_type(ccx, result_ty);
- adt::trans_start_init(bcx, &*repr, llresult, disr);
match args {
callee::ArgExprs(exprs) => {
- for (i, expr) in exprs.iter().enumerate() {
- let lldestptr = adt::trans_field_ptr(bcx, &*repr, llresult, disr, i);
- bcx = expr::trans_into(bcx, *expr, expr::SaveIn(lldestptr));
- }
+ let fields = exprs.iter().map(|x| *x).enumerate().collect::<Vec<_>>();
+ bcx = expr::trans_adt(bcx, &*repr, disr, fields.as_slice(),
+ None, expr::SaveIn(llresult));
}
_ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor")
}
if !type_is_zero_size(fcx.ccx, result_ty) {
let repr = adt::represent_type(ccx, result_ty);
- adt::trans_start_init(bcx, &*repr, fcx.llretptr.get().unwrap(), disr);
for (i, arg_datum) in arg_datums.move_iter().enumerate() {
let lldestptr = adt::trans_field_ptr(bcx,
&*repr,
i);
arg_datum.store_to(bcx, lldestptr);
}
+ adt::trans_set_discr(bcx, &*repr, fcx.llretptr.get().unwrap(), disr);
}
finish_fn(&fcx, bcx, result_ty);
let repr = adt::represent_type(bcx.ccx(), node_id_type(bcx, id));
// Create the closure.
- adt::trans_start_init(bcx, &*repr, dest_addr, 0);
for freevar in freevars_ptr.iter() {
let datum = expr::trans_local_var(bcx, freevar.def);
let upvar_slot_dest = adt::trans_field_ptr(bcx,
0);
bcx = datum.store_to(bcx, upvar_slot_dest);
}
+ adt::trans_set_discr(bcx, &*repr, dest_addr, 0);
bcx
}
// Nullary variant.
let ty = expr_ty(bcx, ref_expr);
let repr = adt::represent_type(bcx.ccx(), ty);
- adt::trans_start_init(bcx, &*repr, lldest,
- variant_info.disr_val);
+ adt::trans_set_discr(bcx, &*repr, lldest,
+ variant_info.disr_val);
return bcx;
}
}
match ty::get(ty).sty {
ty::ty_struct(did, _) if ty::has_dtor(bcx.tcx(), did) => {
let repr = adt::represent_type(bcx.ccx(), ty);
- adt::trans_start_init(bcx, &*repr, lldest, 0);
+ adt::trans_set_discr(bcx, &*repr, lldest, 0);
}
_ => {}
}
* Note that `fields` may be empty; the base expression must always be
* evaluated for side-effects.
*/
-struct StructBaseInfo {
+pub struct StructBaseInfo {
/// The base expression; will be evaluated after all explicit fields.
expr: Gc<ast::Expr>,
/// The indices of fields to copy paired with their types.
* - `optbase` contains information on the base struct (if any) from
* which remaining fields are copied; see comments on `StructBaseInfo`.
*/
-fn trans_adt<'a>(
- bcx: &'a Block<'a>,
- repr: &adt::Repr,
- discr: ty::Disr,
- fields: &[(uint, Gc<ast::Expr>)],
- optbase: Option<StructBaseInfo>,
- dest: Dest)
- -> &'a Block<'a> {
+pub fn trans_adt<'a>(bcx: &'a Block<'a>,
+ repr: &adt::Repr,
+ discr: ty::Disr,
+ fields: &[(uint, Gc<ast::Expr>)],
+ optbase: Option<StructBaseInfo>,
+ dest: Dest) -> &'a Block<'a> {
let _icx = push_ctxt("trans_adt");
let fcx = bcx.fcx;
let mut bcx = bcx;
// failure occur before the ADT as a whole is ready.
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
- adt::trans_start_init(bcx, repr, addr, discr);
-
for &(i, ref e) in fields.iter() {
let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
let e_ty = expr_ty_adjusted(bcx, &**e);
}
}
+ adt::trans_set_discr(bcx, repr, addr, discr);
+
fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
return bcx;