about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLuqman Aden <me@luqman.ca>2014-07-10 15:09:21 -0700
committerLuqman Aden <me@luqman.ca>2014-07-18 11:58:45 -0700
commitad27e2625a84662b49af3f73b40488e8bdcc46e3 (patch)
tree57c7ae00c0bbe203d51904636c120adb7f2dd7de
parent27748b09d8bb69d7f7a105aa8dd22de439c17c6c (diff)
downloadrust-ad27e2625a84662b49af3f73b40488e8bdcc46e3.tar.gz
rust-ad27e2625a84662b49af3f73b40488e8bdcc46e3.zip
librustc: Set enum discriminant only after field translation.
-rw-r--r--src/librustc/middle/trans/adt.rs7
-rw-r--r--src/librustc/middle/trans/base.rs10
-rw-r--r--src/librustc/middle/trans/closure.rs2
-rw-r--r--src/librustc/middle/trans/expr.rs26
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::<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")
         }
@@ -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<ast::Expr>,
     /// 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<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;
@@ -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;