]> git.lizzy.rs Git - rust.git/commitdiff
Use LvalueRef instead of MaybeSizedValue
authorMark Simulacrum <mark.simulacrum@gmail.com>
Sun, 1 Jan 2017 22:50:15 +0000 (15:50 -0700)
committerMark Simulacrum <mark.simulacrum@gmail.com>
Wed, 4 Jan 2017 18:35:33 +0000 (11:35 -0700)
src/librustc_trans/adt.rs
src/librustc_trans/base.rs
src/librustc_trans/callee.rs
src/librustc_trans/cleanup.rs
src/librustc_trans/glue.rs
src/librustc_trans/intrinsic.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/lvalue.rs
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/rvalue.rs

index 365f86c0245008c5ac6c53ecfda65461e942d76b..14882dd433ba7987b885613049595b6321c203b3 100644 (file)
@@ -48,6 +48,7 @@
 use llvm::{ValueRef, True, IntEQ, IntNE};
 use rustc::ty::layout;
 use rustc::ty::{self, Ty, AdtKind};
+use mir::lvalue::LvalueRef;
 use common::*;
 use builder::Builder;
 use glue;
@@ -64,32 +65,6 @@ pub enum BranchKind {
     Single
 }
 
-#[derive(Copy, Clone)]
-pub struct MaybeSizedValue {
-    pub value: ValueRef,
-    pub meta: ValueRef,
-}
-
-impl MaybeSizedValue {
-    pub fn sized(value: ValueRef) -> MaybeSizedValue {
-        MaybeSizedValue {
-            value: value,
-            meta: std::ptr::null_mut()
-        }
-    }
-
-    pub fn unsized_(value: ValueRef, meta: ValueRef) -> MaybeSizedValue {
-        MaybeSizedValue {
-            value: value,
-            meta: meta
-        }
-    }
-
-    pub fn has_meta(&self) -> bool {
-        !self.meta.is_null()
-    }
-}
-
 /// Given an enum, struct, closure, or tuple, extracts fields.
 /// Treats closures as a struct with one variant.
 /// `empty_if_no_variants` is a switch to deal with empty enums.
@@ -500,11 +475,11 @@ fn assert_discr_in_range(min: Disr, max: Disr, discr: Disr) {
 /// Access a field, at a point when the value's case is known.
 pub fn trans_field_ptr<'a, 'tcx>(
     bcx: &Builder<'a, 'tcx>,
-    t: Ty<'tcx>,
-    val: MaybeSizedValue,
+    val: LvalueRef<'tcx>,
     discr: Disr,
     ix: usize
 ) -> ValueRef {
+    let t = val.ty.to_ty(bcx.tcx());
     let l = bcx.ccx.layout_of(t);
     debug!("trans_field_ptr on {} represented as {:#?}", t, l);
     // Note: if this ever needs to generate conditionals (e.g., if we
@@ -520,7 +495,7 @@ pub fn trans_field_ptr<'a, 'tcx>(
         layout::Vector { count, .. } => {
             assert_eq!(discr.0, 0);
             assert!((ix as u64) < count);
-            bcx.struct_gep(val.value, ix)
+            bcx.struct_gep(val.llval, ix)
         }
         layout::General { discr: d, ref variants, .. } => {
             let mut fields = compute_fields(bcx.ccx, t, discr.0 as usize, false);
@@ -532,7 +507,7 @@ pub fn trans_field_ptr<'a, 'tcx>(
         layout::UntaggedUnion { .. } => {
             let fields = compute_fields(bcx.ccx, t, 0, false);
             let ty = type_of::in_memory_type_of(bcx.ccx, fields[ix]);
-            bcx.pointercast(val.value, ty.ptr_to())
+            bcx.pointercast(val.llval, ty.ptr_to())
         }
         layout::RawNullablePointer { nndiscr, .. } |
         layout::StructWrappedNullablePointer { nndiscr,  .. } if discr.0 != nndiscr => {
@@ -541,14 +516,14 @@ pub fn trans_field_ptr<'a, 'tcx>(
             // (e.d., Result of Either with (), as one side.)
             let ty = type_of::type_of(bcx.ccx, nullfields[ix]);
             assert_eq!(machine::llsize_of_alloc(bcx.ccx, ty), 0);
-            bcx.pointercast(val.value, ty.ptr_to())
+            bcx.pointercast(val.llval, ty.ptr_to())
         }
         layout::RawNullablePointer { nndiscr, .. } => {
             let nnty = compute_fields(bcx.ccx, t, nndiscr as usize, false)[0];
             assert_eq!(ix, 0);
             assert_eq!(discr.0, nndiscr);
             let ty = type_of::type_of(bcx.ccx, nnty);
-            bcx.pointercast(val.value, ty.ptr_to())
+            bcx.pointercast(val.llval, ty.ptr_to())
         }
         layout::StructWrappedNullablePointer { ref nonnull, nndiscr, .. } => {
             assert_eq!(discr.0, nndiscr);
@@ -564,7 +539,7 @@ fn struct_field_ptr<'a, 'tcx>(
     bcx: &Builder<'a, 'tcx>,
     st: &layout::Struct,
     fields: &Vec<Ty<'tcx>>,
-    val: MaybeSizedValue,
+    val: LvalueRef,
     ix: usize,
     needs_cast: bool
 ) -> ValueRef {
@@ -576,9 +551,9 @@ fn struct_field_ptr<'a, 'tcx>(
             type_of::in_memory_type_of(ccx, fields[i])
         }).collect::<Vec<_>>();
         let real_ty = Type::struct_(ccx, &fields[..], st.packed);
-        bcx.pointercast(val.value, real_ty.ptr_to())
+        bcx.pointercast(val.llval, real_ty.ptr_to())
     } else {
-        val.value
+        val.llval
     };
 
     // Simple case - we can just GEP the field
@@ -600,7 +575,7 @@ fn struct_field_ptr<'a, 'tcx>(
     }
 
     // There's no metadata available, log the case and just do the GEP.
-    if !val.has_meta() {
+    if !val.has_extra() {
         debug!("Unsized field `{}`, of `{:?}` has no metadata for adjustment",
                ix, Value(ptr_val));
         return bcx.struct_gep(ptr_val, ix);
@@ -621,7 +596,7 @@ fn struct_field_ptr<'a, 'tcx>(
     // The type Foo<Foo<Trait>> is represented in LLVM as { u16, { u16, u8 }}, meaning that
     // the `y` field has 16-bit alignment.
 
-    let meta = val.meta;
+    let meta = val.llextra;
 
 
     let offset = st.offsets[ix].bytes();
index f87b44604c7b8ff91a1fd2d039bd777a7fd36014..a329b01cc160821f1aa031c7a600edc97f40b9db 100644 (file)
@@ -47,6 +47,7 @@
 use rustc_incremental::IncrementalHashesMap;
 use session::{self, DataTypeKind, Session};
 use abi::{self, Abi, FnType};
+use mir::lvalue::LvalueRef;
 use adt;
 use attributes;
 use builder::Builder;
@@ -278,8 +279,8 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                 monomorphize::field_ty(bcx.tcx(), substs_b, f)
             });
 
-            let src = adt::MaybeSizedValue::sized(src);
-            let dst = adt::MaybeSizedValue::sized(dst);
+            let src = LvalueRef::new_sized_ty(src, src_ty);
+            let dst = LvalueRef::new_sized_ty(dst, dst_ty);
 
             let iter = src_fields.zip(dst_fields).enumerate();
             for (i, (src_fty, dst_fty)) in iter {
@@ -287,8 +288,8 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                     continue;
                 }
 
-                let src_f = adt::trans_field_ptr(bcx, src_ty, src, Disr(0), i);
-                let dst_f = adt::trans_field_ptr(bcx, dst_ty, dst, Disr(0), i);
+                let src_f = adt::trans_field_ptr(bcx, src, Disr(0), i);
+                let dst_f = adt::trans_field_ptr(bcx, dst, Disr(0), i);
                 if src_fty == dst_fty {
                     memcpy_ty(bcx, dst_f, src_f, src_fty, None);
                 } else {
@@ -620,11 +621,12 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             // final ret value
             bcx.alloca(fn_ty.ret.memory_ty(ccx), "sret_slot")
         };
-        let dest_val = adt::MaybeSizedValue::sized(dest); // Can return unsized value
+        // Can return unsized value
+        let dest_val = LvalueRef::new_sized_ty(dest, sig.output());
         let mut llarg_idx = fn_ty.ret.is_indirect() as usize;
         let mut arg_idx = 0;
         for (i, arg_ty) in sig.inputs().iter().enumerate() {
-            let lldestptr = adt::trans_field_ptr(&bcx, sig.output(), dest_val, Disr::from(disr), i);
+            let lldestptr = adt::trans_field_ptr(&bcx, dest_val, Disr::from(disr), i);
             let arg = &fn_ty.args[arg_idx];
             arg_idx += 1;
             if common::type_is_fat_ptr(bcx.ccx, arg_ty) {
index e73bfd73e9b0783c2b2c8ea3a803b0e38c33621d..c99dc7ee5ef4b9f70464d520d8440ad9336857a4 100644 (file)
@@ -26,7 +26,7 @@
 use builder::Builder;
 use common::{self, CrateContext, SharedCrateContext};
 use cleanup::CleanupScope;
-use adt::MaybeSizedValue;
+use mir::lvalue::LvalueRef;
 use consts;
 use declare;
 use value::Value;
@@ -364,7 +364,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
     // Call the by-ref closure body with `self` in a cleanup scope,
     // to drop `self` when the body returns, or in case it unwinds.
     let self_scope = CleanupScope::schedule_drop_mem(
-        &bcx, MaybeSizedValue::sized(llenv), closure_ty
+        &bcx, LvalueRef::new_sized_ty(llenv, closure_ty)
     );
 
     let llfn = callee.reify(bcx.ccx);
index 8b296e9ad2988d9d65ed6a53c4dad4c97f96f925..d7ac5bee6d85a70c097ba354ead05af1f23243aa 100644 (file)
 
 use llvm::BasicBlockRef;
 use base;
-use adt::MaybeSizedValue;
+use mir::lvalue::LvalueRef;
+use rustc::mir::tcx::LvalueTy;
 use builder::Builder;
 use common::Funclet;
 use glue;
 use type_::Type;
-use rustc::ty::Ty;
 
 pub struct CleanupScope<'tcx> {
     // Cleanup to run upon scope exit.
@@ -37,14 +37,13 @@ pub struct CleanupScope<'tcx> {
 
 #[derive(Copy, Clone)]
 pub struct DropValue<'tcx> {
-    val: MaybeSizedValue,
-    ty: Ty<'tcx>,
+    val: LvalueRef<'tcx>,
     skip_dtor: bool,
 }
 
 impl<'tcx> DropValue<'tcx> {
     fn trans<'a>(&self, funclet: Option<&'a Funclet>, bcx: &Builder<'a, 'tcx>) {
-        glue::call_drop_glue(bcx, self.val, self.ty, self.skip_dtor, funclet)
+        glue::call_drop_glue(bcx, self.val, self.skip_dtor, funclet)
     }
 
     /// Creates a landing pad for the top scope. The landing pad will perform all cleanups necessary
@@ -96,12 +95,16 @@ fn get_landing_pad<'a>(&self, bcx: &Builder<'a, 'tcx>) -> BasicBlockRef {
 impl<'a, 'tcx> CleanupScope<'tcx> {
     /// Schedules a (deep) drop of `val`, which is a pointer to an instance of `ty`
     pub fn schedule_drop_mem(
-        bcx: &Builder<'a, 'tcx>, val: MaybeSizedValue, ty: Ty<'tcx>
+        bcx: &Builder<'a, 'tcx>, val: LvalueRef<'tcx>
     ) -> CleanupScope<'tcx> {
-        if !bcx.ccx.shared().type_needs_drop(ty) { return CleanupScope::noop(); }
+        if let LvalueTy::Downcast { .. } = val.ty {
+            bug!("Cannot drop downcast ty yet");
+        }
+        if !bcx.ccx.shared().type_needs_drop(val.ty.to_ty(bcx.tcx())) {
+            return CleanupScope::noop();
+        }
         let drop = DropValue {
             val: val,
-            ty: ty,
             skip_dtor: false,
         };
 
@@ -114,15 +117,19 @@ pub fn schedule_drop_mem(
     /// and dropping the contents associated with that variant
     /// *without* executing any associated drop implementation.
     pub fn schedule_drop_adt_contents(
-        bcx: &Builder<'a, 'tcx>, val: MaybeSizedValue, ty: Ty<'tcx>
+        bcx: &Builder<'a, 'tcx>, val: LvalueRef<'tcx>
     ) -> CleanupScope<'tcx> {
+        if let LvalueTy::Downcast { .. } = val.ty {
+            bug!("Cannot drop downcast ty yet");
+        }
         // `if` below could be "!contents_needs_drop"; skipping drop
         // is just an optimization, so sound to be conservative.
-        if !bcx.ccx.shared().type_needs_drop(ty) { return CleanupScope::noop(); }
+        if !bcx.ccx.shared().type_needs_drop(val.ty.to_ty(bcx.tcx())) {
+            return CleanupScope::noop();
+        }
 
         let drop = DropValue {
             val: val,
-            ty: ty,
             skip_dtor: true,
         };
 
index 8b7df0128b00b9a855b2124d1f3cff4f6035a06e..f3977004b336dd285b07b06219ba25aec2b83759 100644 (file)
@@ -22,7 +22,8 @@
 use rustc::traits;
 use rustc::ty::{self, AdtKind, Ty, TypeFoldable};
 use rustc::ty::subst::Kind;
-use adt::{self, MaybeSizedValue};
+use mir::lvalue::LvalueRef;
+use adt;
 use base::*;
 use callee::Callee;
 use cleanup::CleanupScope;
 
 use syntax_pos::DUMMY_SP;
 
-pub fn trans_exchange_free_ty<'a, 'tcx>(
-    bcx: &Builder<'a, 'tcx>,
-    ptr: MaybeSizedValue,
-    content_ty: Ty<'tcx>
-) {
+pub fn trans_exchange_free_ty<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, ptr: LvalueRef<'tcx>) {
+    let content_ty = ptr.ty.to_ty(bcx.tcx());
     let def_id = langcall(bcx.tcx(), None, "", BoxFreeFnLangItem);
     let substs = bcx.tcx().mk_substs(iter::once(Kind::from(content_ty)));
     let callee = Callee::def(bcx.ccx, def_id, substs);
@@ -51,7 +49,7 @@ pub fn trans_exchange_free_ty<'a, 'tcx>(
     let fn_ty = callee.direct_fn_type(bcx.ccx, &[]);
 
     let llret = bcx.call(callee.reify(bcx.ccx),
-        &[ptr.value, ptr.meta][..1 + ptr.has_meta() as usize], None);
+        &[ptr.llval, ptr.llextra][..1 + ptr.has_extra() as usize], None);
     fn_ty.apply_attrs_callsite(llret);
 }
 
@@ -94,17 +92,17 @@ pub fn get_drop_glue_type<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'t
     }
 }
 
-fn drop_ty<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, args: MaybeSizedValue, t: Ty<'tcx>) {
-    call_drop_glue(bcx, args, t, false, None)
+fn drop_ty<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, args: LvalueRef<'tcx>) {
+    call_drop_glue(bcx, args, false, None)
 }
 
 pub fn call_drop_glue<'a, 'tcx>(
     bcx: &Builder<'a, 'tcx>,
-    mut args: MaybeSizedValue,
-    t: Ty<'tcx>,
+    mut args: LvalueRef<'tcx>,
     skip_dtor: bool,
     funclet: Option<&'a Funclet>,
 ) {
+    let t = args.ty.to_ty(bcx.tcx());
     // NB: v is an *alias* of type t here, not a direct value.
     debug!("call_drop_glue(t={:?}, skip_dtor={})", t, skip_dtor);
     if bcx.ccx.shared().type_needs_drop(t) {
@@ -117,11 +115,11 @@ pub fn call_drop_glue<'a, 'tcx>(
         let glue = get_drop_glue_core(ccx, g);
         let glue_type = get_drop_glue_type(ccx.shared(), t);
         if glue_type != t {
-            args.value = bcx.pointercast(args.value, type_of(ccx, glue_type).ptr_to());
+            args.llval = bcx.pointercast(args.llval, type_of(ccx, glue_type).ptr_to());
         }
 
         // No drop-hint ==> call standard drop glue
-        bcx.call(glue, &[args.value, args.meta][..1 + args.has_meta() as usize],
+        bcx.call(glue, &[args.llval, args.llextra][..1 + args.has_extra() as usize],
             funclet.map(|b| b.bundle()));
     }
 }
@@ -194,9 +192,9 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
 
     let value = get_param(llfn, 0);
     let ptr = if ccx.shared().type_is_sized(t) {
-        MaybeSizedValue::sized(value)
+        LvalueRef::new_sized_ty(value, t)
     } else {
-        MaybeSizedValue::unsized_(value, get_param(llfn, 1))
+        LvalueRef::new_unsized_ty(value, get_param(llfn, 1), t)
     };
 
     let skip_dtor = match g {
@@ -211,14 +209,14 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
             // a safe-guard, assert TyBox not used with TyContents.
             assert!(!skip_dtor);
             let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) {
-                let llbox = bcx.load(get_dataptr(&bcx, ptr.value));
-                let info = bcx.load(get_meta(&bcx, ptr.value));
-                MaybeSizedValue::unsized_(llbox, info)
+                let llbox = bcx.load(get_dataptr(&bcx, ptr.llval));
+                let info = bcx.load(get_meta(&bcx, ptr.llval));
+                LvalueRef::new_unsized_ty(llbox, info, content_ty)
             } else {
-                MaybeSizedValue::sized(bcx.load(ptr.value))
+                LvalueRef::new_sized_ty(bcx.load(ptr.llval), content_ty)
             };
-            drop_ty(&bcx, ptr, content_ty);
-            trans_exchange_free_ty(&bcx, ptr, content_ty);
+            drop_ty(&bcx, ptr);
+            trans_exchange_free_ty(&bcx, ptr);
             bcx
         }
         ty::TyDynamic(..) => {
@@ -226,8 +224,8 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
             // versus without calling Drop::drop. Assert caller is
             // okay with always calling the Drop impl, if any.
             assert!(!skip_dtor);
-            let dtor = bcx.load(ptr.meta);
-            bcx.call(dtor, &[ptr.value], None);
+            let dtor = bcx.load(ptr.llextra);
+            bcx.call(dtor, &[ptr.llval], None);
             bcx
         }
         ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => {
@@ -245,7 +243,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
             // Issue #23611: schedule cleanup of contents, re-inspecting the
             // discriminant (if any) in case of variant swap in drop code.
             let contents_scope = if !shallow_drop {
-                CleanupScope::schedule_drop_adt_contents(&bcx, ptr, t)
+                CleanupScope::schedule_drop_adt_contents(&bcx, ptr)
             } else {
                 CleanupScope::noop()
             };
@@ -262,7 +260,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
             let callee = Callee::def(bcx.ccx, dtor_did, vtbl.substs);
             let fn_ty = callee.direct_fn_type(bcx.ccx, &[]);
             let llret;
-            let args = &[ptr.value, ptr.meta][..1 + ptr.has_meta() as usize];
+            let args = &[ptr.llval, ptr.llextra][..1 + ptr.has_extra() as usize];
             if let Some(landing_pad) = contents_scope.landing_pad {
                 let normal_bcx = bcx.build_new_block("normal-return");
                 llret = bcx.invoke(callee.reify(ccx), args, normal_bcx.llbb(), landing_pad, None);
@@ -279,7 +277,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi
         }
         _ => {
             if bcx.ccx.shared().type_needs_drop(t) {
-                drop_structural_ty(bcx, ptr, t)
+                drop_structural_ty(bcx, ptr)
             } else {
                 bcx
             }
@@ -396,60 +394,57 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
 }
 
 // Iterates through the elements of a structural type, dropping them.
-fn drop_structural_ty<'a, 'tcx>(cx: Builder<'a, 'tcx>,
-                                ptr: MaybeSizedValue,
-                                t: Ty<'tcx>)
-                                -> Builder<'a, 'tcx> {
+fn drop_structural_ty<'a, 'tcx>(cx: Builder<'a, 'tcx>, ptr: LvalueRef<'tcx>) -> Builder<'a, 'tcx> {
     fn iter_variant<'a, 'tcx>(cx: &Builder<'a, 'tcx>,
-                              t: Ty<'tcx>,
-                              av: adt::MaybeSizedValue,
+                              av: LvalueRef<'tcx>,
                               variant: &'tcx ty::VariantDef,
                               substs: &Substs<'tcx>) {
         let tcx = cx.tcx();
         for (i, field) in variant.fields.iter().enumerate() {
             let arg = monomorphize::field_ty(tcx, substs, field);
-            let field_ptr = adt::trans_field_ptr(&cx, t, av, Disr::from(variant.disr_val), i);
-            drop_ty(&cx, MaybeSizedValue::sized(field_ptr), arg);
+            let field_ptr = adt::trans_field_ptr(&cx, av, Disr::from(variant.disr_val), i);
+            drop_ty(&cx, LvalueRef::new_sized_ty(field_ptr, arg));
         }
     }
 
     let mut cx = cx;
+    let t = ptr.ty.to_ty(cx.tcx());
     match t.sty {
         ty::TyClosure(def_id, substs) => {
             for (i, upvar_ty) in substs.upvar_tys(def_id, cx.tcx()).enumerate() {
-                let llupvar = adt::trans_field_ptr(&cx, t, ptr, Disr(0), i);
-                drop_ty(&cx, MaybeSizedValue::sized(llupvar), upvar_ty);
+                let llupvar = adt::trans_field_ptr(&cx, ptr, Disr(0), i);
+                drop_ty(&cx, LvalueRef::new_sized_ty(llupvar, upvar_ty));
             }
         }
         ty::TyArray(_, n) => {
-            let base = get_dataptr(&cx, ptr.value);
+            let base = get_dataptr(&cx, ptr.llval);
             let len = C_uint(cx.ccx, n);
             let unit_ty = t.sequence_element_type(cx.tcx());
             cx = tvec::slice_for_each(&cx, base, unit_ty, len,
-                |bb, vv| drop_ty(bb, MaybeSizedValue::sized(vv), unit_ty));
+                |bb, vv| drop_ty(bb, LvalueRef::new_sized_ty(vv, unit_ty)));
         }
         ty::TySlice(_) | ty::TyStr => {
             let unit_ty = t.sequence_element_type(cx.tcx());
-            cx = tvec::slice_for_each(&cx, ptr.value, unit_ty, ptr.meta,
-                |bb, vv| drop_ty(bb, MaybeSizedValue::sized(vv), unit_ty));
+            cx = tvec::slice_for_each(&cx, ptr.llval, unit_ty, ptr.llextra,
+                |bb, vv| drop_ty(bb, LvalueRef::new_sized_ty(vv, unit_ty)));
         }
         ty::TyTuple(ref args) => {
             for (i, arg) in args.iter().enumerate() {
-                let llfld_a = adt::trans_field_ptr(&cx, t, ptr, Disr(0), i);
-                drop_ty(&cx, MaybeSizedValue::sized(llfld_a), *arg);
+                let llfld_a = adt::trans_field_ptr(&cx, ptr, Disr(0), i);
+                drop_ty(&cx, LvalueRef::new_sized_ty(llfld_a, *arg));
             }
         }
         ty::TyAdt(adt, substs) => match adt.adt_kind() {
             AdtKind::Struct => {
                 let VariantInfo { fields, discr } = VariantInfo::from_ty(cx.tcx(), t, None);
                 for (i, &Field(_, field_ty)) in fields.iter().enumerate() {
-                    let llfld_a = adt::trans_field_ptr(&cx, t, ptr, Disr::from(discr), i);
+                    let llfld_a = adt::trans_field_ptr(&cx, ptr, Disr::from(discr), i);
                     let ptr = if cx.ccx.shared().type_is_sized(field_ty) {
-                        MaybeSizedValue::sized(llfld_a)
+                        LvalueRef::new_sized_ty(llfld_a, field_ty)
                     } else {
-                        MaybeSizedValue::unsized_(llfld_a, ptr.meta)
+                        LvalueRef::new_unsized_ty(llfld_a, ptr.llextra, field_ty)
                     };
-                    drop_ty(&cx, ptr, field_ty);
+                    drop_ty(&cx, ptr);
                 }
             }
             AdtKind::Union => {
@@ -461,16 +456,16 @@ fn iter_variant<'a, 'tcx>(cx: &Builder<'a, 'tcx>,
                 // NB: we must hit the discriminant first so that structural
                 // comparison know not to proceed when the discriminants differ.
 
-                match adt::trans_switch(&cx, t, ptr.value, false) {
+                match adt::trans_switch(&cx, t, ptr.llval, false) {
                     (adt::BranchKind::Single, None) => {
                         if n_variants != 0 {
                             assert!(n_variants == 1);
-                            iter_variant(&cx, t, ptr, &adt.variants[0], substs);
+                            iter_variant(&cx, ptr, &adt.variants[0], substs);
                         }
                     }
                     (adt::BranchKind::Switch, Some(lldiscrim_a)) => {
                         let tcx = cx.tcx();
-                        drop_ty(&cx, MaybeSizedValue::sized(lldiscrim_a), tcx.types.isize);
+                        drop_ty(&cx, LvalueRef::new_sized_ty(lldiscrim_a, tcx.types.isize));
 
                         // Create a fall-through basic block for the "else" case of
                         // the switch instruction we're about to generate. Note that
@@ -496,7 +491,7 @@ fn iter_variant<'a, 'tcx>(cx: &Builder<'a, 'tcx>,
                             let variant_cx = cx.build_new_block(&variant_cx_name);
                             let case_val = adt::trans_case(&cx, t, Disr::from(variant.disr_val));
                             variant_cx.add_case(llswitch, case_val, variant_cx.llbb());
-                            iter_variant(&variant_cx, t, ptr, variant, substs);
+                            iter_variant(&variant_cx, ptr, variant, substs);
                             variant_cx.br(next_cx.llbb());
                         }
                         cx = next_cx;
index 41155935a6353e61d42768f4b8d4eb0f664a2c99..b80c707f37697c3d00879d96071c4c49f1cf1abb 100644 (file)
@@ -16,6 +16,7 @@
 use llvm::{ValueRef};
 use abi::{Abi, FnType};
 use adt;
+use mir::lvalue::LvalueRef;
 use base::*;
 use common::*;
 use declare;
@@ -549,10 +550,10 @@ fn modify_as_needed<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                         // destructors, and the contents are SIMD
                         // etc.
                         assert!(!bcx.ccx.shared().type_needs_drop(arg_type));
-                        let arg = adt::MaybeSizedValue::sized(llarg);
+                        let arg = LvalueRef::new_sized_ty(llarg, arg_type);
                         (0..contents.len())
                             .map(|i| {
-                                bcx.load(adt::trans_field_ptr(bcx, arg_type, arg, Disr(0), i))
+                                bcx.load(adt::trans_field_ptr(bcx, arg, Disr(0), i))
                             })
                             .collect()
                     }
index ae0d847072a59ae502f5185748101c1bad9d9299..77ce17006baa0d81b64f105794dabce93bfb74fa 100644 (file)
@@ -14,7 +14,7 @@
 use rustc::ty::{self, layout};
 use rustc::mir;
 use abi::{Abi, FnType, ArgType};
-use adt::{self, MaybeSizedValue};
+use adt;
 use base::{self, Lifetime};
 use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual};
 use builder::Builder;
@@ -37,7 +37,7 @@
 use super::{MirContext, LocalRef};
 use super::analyze::CleanupKind;
 use super::constant::Const;
-use super::lvalue::{LvalueRef};
+use super::lvalue::LvalueRef;
 use super::operand::OperandRef;
 use super::operand::OperandValue::{Pair, Ref, Immediate};
 
@@ -251,11 +251,11 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock,
                     } else {
                         lvalue.llval
                     };
-                    MaybeSizedValue::sized(value)
+                    LvalueRef::new_sized_ty(value, ty)
                 } else {
-                    MaybeSizedValue::unsized_(lvalue.llval, lvalue.llextra)
+                    LvalueRef::new_unsized_ty(lvalue.llval, lvalue.llextra, ty)
                 };
-                let args = &[ptr.value, ptr.meta][..1 + ptr.has_meta() as usize];
+                let args = &[ptr.llval, ptr.llextra][..1 + ptr.has_extra() as usize];
                 if let Some(unwind) = unwind {
                     bcx.invoke(
                         drop_fn,
@@ -707,9 +707,10 @@ fn trans_arguments_untupled(&mut self,
         // Handle both by-ref and immediate tuples.
         match tuple.val {
             Ref(llval) => {
-                let base = adt::MaybeSizedValue::sized(llval);
                 for (n, &ty) in arg_types.iter().enumerate() {
-                    let ptr = adt::trans_field_ptr(bcx, tuple.ty, base, Disr(0), n);
+                    let ptr = adt::trans_field_ptr(
+                        bcx, LvalueRef::new_sized_ty(llval, tuple.ty), Disr(0), n
+                    );
                     let val = if common::type_is_fat_ptr(bcx.ccx, ty) {
                         let (lldata, llextra) = base::load_fat_ptr(bcx, ptr, ty);
                         Pair(lldata, llextra)
index 5a926c7f7555985f671a514254e5813ef7e2390f..fe8f92c679801141c034b7031cb4932cf60823ab 100644 (file)
@@ -44,6 +44,18 @@ pub fn new_sized(llval: ValueRef, lvalue_ty: LvalueTy<'tcx>) -> LvalueRef<'tcx>
         LvalueRef { llval: llval, llextra: ptr::null_mut(), ty: lvalue_ty }
     }
 
+    pub fn new_sized_ty(llval: ValueRef, ty: Ty<'tcx>) -> LvalueRef<'tcx> {
+        LvalueRef::new_sized(llval, LvalueTy::from_ty(ty))
+    }
+
+    pub fn new_unsized_ty(llval: ValueRef, llextra: ValueRef, ty: Ty<'tcx>) -> LvalueRef<'tcx> {
+        LvalueRef {
+            llval: llval,
+            llextra: llextra,
+            ty: LvalueTy::from_ty(ty),
+        }
+    }
+
     pub fn len<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef {
         let ty = self.ty.to_ty(ccx.tcx());
         match ty.sty {
@@ -55,6 +67,10 @@ pub fn len<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef {
             _ => bug!("unexpected type `{}` in LvalueRef::len", ty)
         }
     }
+
+    pub fn has_extra(&self) -> bool {
+        !self.llextra.is_null()
+    }
 }
 
 impl<'a, 'tcx> MirContext<'a, 'tcx> {
@@ -132,11 +148,11 @@ pub fn trans_lvalue(&mut self,
                         let discr = discr as u64;
                         let is_sized = self.ccx.shared().type_is_sized(projected_ty.to_ty(tcx));
                         let base = if is_sized {
-                            adt::MaybeSizedValue::sized(tr_base.llval)
+                            LvalueRef::new_sized_ty(tr_base.llval, base_ty)
                         } else {
-                            adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
+                            LvalueRef::new_unsized_ty(tr_base.llval, tr_base.llextra, base_ty)
                         };
-                        let llprojected = adt::trans_field_ptr(bcx, base_ty, base, Disr(discr),
+                        let llprojected = adt::trans_field_ptr(bcx, base, Disr(discr),
                             field.index());
                         let llextra = if is_sized {
                             ptr::null_mut()
index 9e2c7797b53529b115e6add2c0c8550c4c198c04..01fd7979be116f79f7cbbf67dccc3697f3b86771 100644 (file)
@@ -38,7 +38,7 @@
 pub use self::constant::trans_static_initializer;
 
 use self::analyze::CleanupKind;
-use self::lvalue::{LvalueRef};
+use self::lvalue::LvalueRef;
 use rustc::mir::traversal;
 
 use self::operand::{OperandRef, OperandValue};
@@ -578,7 +578,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
 mod analyze;
 mod block;
 mod constant;
-mod lvalue;
+pub mod lvalue;
 mod operand;
 mod rvalue;
 mod statement;
index a23c3d4b2e3589c98375ad874023113313001e23..9a3d63f18e8b40565dba954aee93148737f56ecb 100644 (file)
@@ -110,10 +110,9 @@ pub fn trans_rvalue(&mut self,
                             let op = self.trans_operand(&bcx, operand);
                             // Do not generate stores and GEPis for zero-sized fields.
                             if !common::type_is_zero_size(bcx.ccx, op.ty) {
-                                let val = adt::MaybeSizedValue::sized(dest.llval);
+                                let val = LvalueRef::new_sized_ty(dest.llval, dest_ty);
                                 let field_index = active_field_index.unwrap_or(i);
-                                let lldest_i = adt::trans_field_ptr(&bcx, dest_ty, val, disr,
-                                    field_index);
+                                let lldest_i = adt::trans_field_ptr(&bcx, val, disr, field_index);
                                 self.store_operand(&bcx, lldest_i, op, None);
                             }
                         }