diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 26cf91b03e14..1f14a24b0ae3 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -11,6 +11,7 @@ use lib::llvm::llvm; use lib::llvm::{TypeRef}; +use middle::trans::adt; use middle::trans::base; use middle::trans::common::*; use middle::trans::common; @@ -143,32 +144,12 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef { ty::ty_unboxed_vec(mt) => T_vec(cx, sizing_type_of(cx, mt.ty)), - ty::ty_tup(ref elems) => { - T_struct(elems.map(|&t| sizing_type_of(cx, t))) + ty::ty_tup(*) | ty::ty_rec(*) | ty::ty_struct(*) + | ty::ty_enum(*) => { + let repr = adt::represent_type(cx, t); + T_struct(adt::sizing_fields_of(cx, &repr)) } - ty::ty_rec(ref fields) => { - T_struct(fields.map(|f| sizing_type_of(cx, f.mt.ty))) - } - - ty::ty_struct(def_id, ref substs) => { - let fields = ty::lookup_struct_fields(cx.tcx, def_id); - let lltype = T_struct(fields.map(|field| { - let field_type = ty::lookup_field_type(cx.tcx, - def_id, - field.id, - substs); - sizing_type_of(cx, field_type) - })); - if ty::ty_dtor(cx.tcx, def_id).is_present() { - T_struct(~[lltype, T_i8()]) - } else { - lltype - } - } - - ty::ty_enum(def_id, _) => T_struct(enum_body_types(cx, def_id, t)), - ty::ty_self | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => { cx.tcx.sess.bug( fmt!("fictitious type %? in sizing_type_of()", @@ -257,28 +238,13 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { T_array(type_of(cx, mt.ty), n) } - ty::ty_rec(fields) => { - let mut tys: ~[TypeRef] = ~[]; - for vec::each(fields) |f| { - let mt_ty = f.mt.ty; - tys.push(type_of(cx, mt_ty)); - } - - // n.b.: introduce an extra layer of indirection to match - // structs - T_struct(~[T_struct(tys)]) - } - ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)), ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)), ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore), ty::ty_type => T_ptr(cx.tydesc_type), - ty::ty_tup(elts) => { - let mut tys = ~[]; - for vec::each(elts) |elt| { - tys.push(type_of(cx, *elt)); - } - T_struct(tys) + ty::ty_tup(*) | ty::ty_rec(*) => { + let repr = adt::represent_type(cx, t); + T_struct(adt::fields_of(cx, &repr)) } ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx), ty::ty_struct(did, ref substs) => { @@ -301,24 +267,9 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { // If this was an enum or struct, fill in the type now. match ty::get(t).sty { - ty::ty_enum(did, _) => { - fill_type_of_enum(cx, did, t, llty); - } - ty::ty_struct(did, ref substs) => { - // Only instance vars are record fields at runtime. - let fields = ty::lookup_struct_fields(cx.tcx, did); - let mut tys = do vec::map(fields) |f| { - let t = ty::lookup_field_type(cx.tcx, did, f.id, substs); - type_of(cx, t) - }; - - // include a byte flag if there is a dtor so that we know when we've - // been dropped - if ty::ty_dtor(cx.tcx, did).is_present() { - common::set_struct_body(llty, ~[T_struct(tys), T_i8()]); - } else { - common::set_struct_body(llty, ~[T_struct(tys)]); - } + ty::ty_enum(*) | ty::ty_struct(*) => { + let repr = adt::represent_type(cx, t); + common::set_struct_body(llty, adt::fields_of(cx, &repr)); } _ => () } @@ -326,34 +277,6 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { return llty; } -pub fn enum_body_types(cx: @CrateContext, did: ast::def_id, t: ty::t) - -> ~[TypeRef] { - let univar = ty::enum_is_univariant(cx.tcx, did); - if !univar { - let size = machine::static_size_of_enum(cx, t); - ~[T_enum_discrim(cx), T_array(T_i8(), size)] - } - else { - // Use the actual fields, so we get the alignment right. - match ty::get(t).sty { - ty::ty_enum(_, ref substs) => { - do ty::enum_variants(cx.tcx, did)[0].args.map |&field_ty| { - sizing_type_of(cx, ty::subst(cx.tcx, substs, field_ty)) - } - } - _ => cx.sess.bug(~"enum is not an enum") - } - } -} - -pub fn fill_type_of_enum(cx: @CrateContext, - did: ast::def_id, - t: ty::t, - llty: TypeRef) { - debug!("type_of_enum %?: %?", t, ty::get(t)); - common::set_struct_body(llty, enum_body_types(cx, did, t)); -} - // Want refinements! (Or case classes, I guess pub enum named_ty { a_struct, an_enum }