From ad27e2625a84662b49af3f73b40488e8bdcc46e3 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 10 Jul 2014 15:09:21 -0700 Subject: [PATCH] librustc: Set enum discriminant only after field translation. --- src/librustc/middle/trans/adt.rs | 7 +++---- src/librustc/middle/trans/base.rs | 10 ++++------ src/librustc/middle/trans/closure.rs | 2 +- src/librustc/middle/trans/expr.rs | 26 ++++++++++++-------------- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 1d0108fa3f7..54c30e72154 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -674,11 +674,10 @@ pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr) } /** - * 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); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index bc0d5494350..7d7922ebfa9 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1735,14 +1735,12 @@ pub fn trans_named_tuple_constructor<'a>(mut bcx: &'a Block<'a>, 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::>(); + 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") } @@ -1800,7 +1798,6 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, 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, @@ -1809,6 +1806,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, i); arg_datum.store_to(bcx, lldestptr); } + adt::trans_set_discr(bcx, &*repr, fcx.llretptr.get().unwrap(), disr); } finish_fn(&fcx, bcx, result_ty); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index a3d8ab1733f..ed6050b6543 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -502,7 +502,6 @@ pub fn trans_unboxed_closure<'a>( 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, @@ -512,6 +511,7 @@ pub fn trans_unboxed_closure<'a>( 0); bcx = datum.store_to(bcx, upvar_slot_dest); } + adt::trans_set_discr(bcx, &*repr, dest_addr, 0); bcx } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index e7bde00b3de..68f577faefe 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -876,8 +876,8 @@ fn trans_def_dps_unadjusted<'a>( // 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; } } @@ -886,7 +886,7 @@ fn trans_def_dps_unadjusted<'a>( 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); } _ => {} } @@ -1098,7 +1098,7 @@ fn trans_rec_or_struct<'a>( * 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, /// The indices of fields to copy paired with their types. @@ -1114,14 +1114,12 @@ struct StructBaseInfo { * - `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)], - optbase: Option, - dest: Dest) - -> &'a Block<'a> { +pub fn trans_adt<'a>(bcx: &'a Block<'a>, + repr: &adt::Repr, + discr: ty::Disr, + fields: &[(uint, Gc)], + optbase: Option, + dest: Dest) -> &'a Block<'a> { let _icx = push_ctxt("trans_adt"); let fcx = bcx.fcx; let mut bcx = bcx; @@ -1143,8 +1141,6 @@ fn trans_adt<'a>( // 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); @@ -1166,6 +1162,8 @@ fn trans_adt<'a>( } } + adt::trans_set_discr(bcx, repr, addr, discr); + fcx.pop_custom_cleanup_scope(custom_cleanup_scope); return bcx; -- 2.44.0