From 3a4714d92e49564c1cfc86fae5573510de7c2e31 Mon Sep 17 00:00:00 2001
From: Jed Davis <jld@panix.com>
Date: Sun, 24 Feb 2013 12:42:39 -0800
Subject: [PATCH] Renovate field projection expressions

---
 src/librustc/middle/trans/datum.rs | 11 +++++------
 src/librustc/middle/trans/expr.rs  | 20 ++++++++++++--------
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index ce472fd9f1f..6f27a190b17 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -511,14 +511,13 @@ pub impl Datum {
         }
     }
 
-    fn GEPi(&self, bcx: block,
-            ixs: &[uint],
-            ty: ty::t,
-            source: DatumCleanup)
-         -> Datum {
+    fn get_element(&self, bcx: block,
+                   ty: ty::t,
+                   source: DatumCleanup,
+                   gep: fn(ValueRef) -> ValueRef) -> Datum {
         let base_val = self.to_ref_llval(bcx);
         Datum {
-            val: GEPi(bcx, base_val, ixs),
+            val: gep(base_val),
             mode: ByRef,
             ty: ty,
             source: source
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 9a69acd4987..cd6d1e42b8c 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -884,13 +884,15 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
         let _icx = bcx.insn_ctxt("trans_rec_field");
 
         let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base));
-        do with_field_tys(bcx.tcx(), base_datum.ty, None) |_disr, field_tys| {
+        let repr = adt::represent_type(bcx.ccx(), base_datum.ty);
+        do with_field_tys(bcx.tcx(), base_datum.ty, None) |discr, field_tys| {
             let ix = ty::field_idx_strict(bcx.tcx(), field, field_tys);
             DatumBlock {
-                datum: base_datum.GEPi(bcx,
-                                       [0u, 0u, ix],
-                                       field_tys[ix].mt.ty,
-                                       ZeroMem),
+                datum: do base_datum.get_element(bcx,
+                                                 field_tys[ix].mt.ty,
+                                                 ZeroMem) |srcval| {
+                    adt::trans_GEP(bcx, &repr, srcval, discr, ix)
+                },
                 bcx: bcx
             }
         }
@@ -1227,11 +1229,13 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
         temp_cleanups.push(dest);
     }
     for optbase.each |base| {
+        // XXX is it sound to use the destination's repr on the base?
+        // XXX would it ever be reasonable to be here with discr != 0?
         let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base.expr));
         for base.fields.each |&(i, t)| {
-            let datum =
-                // XXX convert this to adt
-                base_datum.GEPi(bcx, struct_field(i), t, ZeroMem);
+            let datum = do base_datum.get_element(bcx, t, ZeroMem) |srcval| {
+                adt::trans_GEP(bcx, repr, srcval, discr, i)
+            };
             let dest = adt::trans_GEP(bcx, repr, addr, discr, i);
             bcx = datum.store_to(bcx, base.expr.id, INIT, dest);
         }