diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 3ad021b2f51..2d9f834040a 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2007,6 +2007,11 @@ pub fn trans_enum_variant(ccx: @CrateContext, // XXX is there a better way to reconstruct the ty::t? let repr = adt::represent_type(ccx, enum_ty); + debug!("trans_enum_variant: name=%s tps=%s repr=%? enum_ty=%s", + unsafe { str::raw::from_c_str(llvm::LLVMGetValueName(llfndecl)) }, + ~"[" + str::connect(ty_param_substs.map(|&t| ty_to_str(ccx.tcx, t)), ", ") + ~"]", + repr, ty_to_str(ccx.tcx, enum_ty)); + adt::trans_start_init(bcx, repr, fcx.llretptr.get(), disr); for vec::eachi(args) |i, va| { let lldestptr = adt::trans_field_ptr(bcx, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 3180fb5a4c8..faf7ddd4ff7 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1311,10 +1311,35 @@ pub enum mono_param_id { mono_any, mono_repr(uint /* size */, uint /* align */, - bool /* is_float */, + MonoDataClass, datum::DatumMode), } +#[deriving(Eq)] +pub enum MonoDataClass { + MonoBits, // Anything not treated differently from arbitrary integer data + MonoNonNull, // Non-null pointers (used for optional-pointer optimization) + // FIXME(#3547)---scalars and floats are + // treated differently in most ABIs. But we + // should be doing something more detailed + // here. + MonoFloat +} + +pub fn mono_data_classify(t: ty::t) -> MonoDataClass { + match ty::get(t).sty { + ty::ty_float(_) => MonoFloat, + ty::ty_rptr(*) | ty::ty_uniq(*) | + ty::ty_box(*) | ty::ty_opaque_box(*) | + ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) | + ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) | + ty::ty_bare_fn(*) => MonoNonNull, + // Is that everything? Would closures or slices qualify? + _ => MonoBits + } +} + + #[deriving(Eq)] pub struct mono_id_ { def: ast::def_id, @@ -1338,6 +1363,12 @@ impl to_bytes::IterBytes for mono_param_id { } } +impl to_bytes::IterBytes for MonoDataClass { + fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} + impl to_bytes::IterBytes for mono_id_ { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 52ca8ec49bb..a0fcdf7fde8 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -395,22 +395,14 @@ pub fn make_mono_id(ccx: @CrateContext, let size = machine::llbitsize_of_real(ccx, llty); let align = machine::llalign_of_pref(ccx, llty); let mode = datum::appropriate_mode(subst); - - // FIXME(#3547)---scalars and floats are - // treated differently in most ABIs. But we - // should be doing something more detailed - // here. - let is_float = match ty::get(subst).sty { - ty::ty_float(_) => true, - _ => false - }; + let data_class = mono_data_classify(subst); // Special value for nil to prevent problems // with undef return pointers. if size <= 8u && ty::type_is_nil(subst) { - mono_repr(0u, 0u, is_float, mode) + mono_repr(0u, 0u, data_class, mode) } else { - mono_repr(size, align, is_float, mode) + mono_repr(size, align, data_class, mode) } } else { mono_precise(subst, None)