diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index d3658e89a2a53..1359a66d5511c 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -49,6 +49,7 @@ use std::num::Int; use std::rc::Rc; use llvm::{ValueRef, True, IntEQ, IntNE}; +use back::abi::slice_elt_base; use middle::subst; use middle::subst::Subst; use middle::trans::_match; @@ -235,7 +236,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr { if cases[1 - discr].is_zerolen(cx, t) { let st = mk_struct(cx, cases[discr].tys.as_slice(), false, t); - match cases[discr].find_ptr() { + match cases[discr].find_ptr(cx) { Some(ThinPointer(_)) if st.fields.len() == 1 => { return RawNullablePointer { nndiscr: discr as Disr, @@ -290,7 +291,7 @@ struct Case { #[deriving(Eq, PartialEq, Show)] pub enum PointerField { ThinPointer(uint), - FatPointer(uint, uint) + FatPointer(uint) } impl Case { @@ -298,31 +299,22 @@ impl Case { mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0 } - fn find_ptr(&self) -> Option { - use back::abi::{fn_field_code, slice_elt_base, trt_field_box}; - + fn find_ptr(&self, cx: &CrateContext) -> Option { for (i, &ty) in self.tys.iter().enumerate() { match ty::get(ty).sty { - // &T/&mut T could either be a thin or fat pointer depending on T - ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty { + // &T/&mut T/Box could either be a thin or fat pointer depending on T + ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) => match ty::get(ty).sty { // &[T] and &str are a pointer and length pair - ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)), - - // &Trait/&mut Trait are a pair of pointers: the actual object and a vtable - ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)), - - // Any other &T/&mut T is just a pointer - _ => return Some(ThinPointer(i)) - }, + ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i)), - // Box could either be a thin or fat pointer depending on T - ty::ty_uniq(t) => match ty::get(t).sty { - ty::ty_vec(_, None) => return Some(FatPointer(i, slice_elt_base)), + // &Trait is a pair of pointers: the actual object and a vtable + ty::ty_trait(..) => return Some(FatPointer(i)), - // Box is a pair of pointers: the actual object and a vtable - ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)), + ty::ty_struct(..) if !ty::type_is_sized(cx.tcx(), ty) => { + return Some(FatPointer(i)) + } - // Any other Box is just a pointer + // Any other &T is just a pointer _ => return Some(ThinPointer(i)) }, @@ -330,7 +322,7 @@ impl Case { ty::ty_bare_fn(..) => return Some(ThinPointer(i)), // Closures are a pair of pointers: the code and environment - ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)), + ty::ty_closure(..) => return Some(FatPointer(i)), // Anything else is not a pointer _ => continue @@ -636,6 +628,7 @@ pub fn trans_get_discr(bcx: Block, r: &Repr, scrutinee: ValueRef, cast_to: Optio -> ValueRef { let signed; let val; + debug!("trans_get_discr r: {}", r); match *r { CEnum(ity, min, max) => { val = load_discr(bcx, ity, scrutinee, min, max); @@ -671,7 +664,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, ptrfield: Pointer scrutinee: ValueRef) -> ValueRef { let llptrptr = match ptrfield { ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]), - FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair]) + FatPointer(field) => GEPi(bcx, scrutinee, [0, field, slice_elt_base]) }; let llptr = Load(bcx, llptrptr); let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; @@ -767,8 +760,8 @@ pub fn trans_set_discr(bcx: Block, r: &Repr, val: ValueRef, discr: Disr) { ThinPointer(field) => (GEPi(bcx, val, [0, field]), type_of::type_of(bcx.ccx(), nonnull.fields[field])), - FatPointer(field, pair) => { - let v = GEPi(bcx, val, [0, field, pair]); + FatPointer(field) => { + let v = GEPi(bcx, val, [0, field, slice_elt_base]); (v, val_ty(v).element_type()) } }; @@ -1102,7 +1095,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef) StructWrappedNullablePointer { nndiscr, ptrfield, .. } => { let (idx, sub_idx) = match ptrfield { ThinPointer(field) => (field, None), - FatPointer(field, pair) => (field, Some(pair)) + FatPointer(field) => (field, Some(slice_elt_base)) }; if is_null(const_struct_field(ccx, val, idx, sub_idx)) { /* subtraction as uint is ok because nndiscr is either 0 or 1 */ diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ea7f28796f03c..0e752b7974428 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2255,7 +2255,7 @@ impl EnumMemberDescriptionFactory { let null_variant_name = token::get_name((*self.variants)[null_variant_index].name); let discrfield = match ptrfield { adt::ThinPointer(field) => format!("{}", field), - adt::FatPointer(field, pair) => format!("{}${}", field, pair) + adt::FatPointer(field) => format!("{}", field) }; let union_member_name = format!("RUST$ENCODED$ENUM${}${}", discrfield, diff --git a/src/librustc_back/abi.rs b/src/librustc_back/abi.rs index 19dd6b8459f04..335317be4b419 100644 --- a/src/librustc_back/abi.rs +++ b/src/librustc_back/abi.rs @@ -14,6 +14,9 @@ pub const box_field_refcnt: uint = 0u; pub const box_field_drop_glue: uint = 1u; pub const box_field_body: uint = 4u; +// FIXME(18590) although we have three different layouts here, the compiler relies on +// them being the same. We should replace them with one set of constants. + // The two halves of a closure: code and environment. pub const fn_field_code: uint = 0u; pub const fn_field_box: uint = 1u;