diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index e7c5e47ffb0..e61a1e9543a 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2243,8 +2243,7 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id)-> lval_maybe_callee { // Nullary variant. let enum_ty = node_id_type(cx, id); let llenumblob = alloc_ty(cx, enum_ty); - // FIXME: This pointer cast probably isn't necessary - let llenumty = type_of(ccx, enum_ty); + let llenumty = type_of_enum(ccx, tid, enum_ty); let llenumptr = PointerCast(cx, llenumblob, T_ptr(llenumty)); let lldiscrimptr = GEPi(cx, llenumptr, [0, 0]); let lldiscrim_gv = lookup_discriminant(ccx, vid); diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index 954cefebd7a..7f11108edde 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -7,11 +7,6 @@ import std::map::hashmap; import ty::*; -export type_of; -export type_of_explicit_args; -export type_of_fn_from_ty; -export type_of_fn; - fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] { vec::map(inputs) {|arg| let arg_ty = arg.ty; @@ -44,149 +39,93 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef { fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { assert !ty::type_has_vars(t); - - #debug("type_of %?: %?", t, ty::get(t)); - // Check the cache. + if cx.lltypes.contains_key(t) { ret cx.lltypes.get(t); } + let llty = alt ty::get(t).struct { + ty::ty_nil | ty::ty_bot { T_nil() } + ty::ty_bool { T_bool() } + ty::ty_int(t) { T_int_ty(cx, t) } + ty::ty_uint(t) { T_uint_ty(cx, t) } + ty::ty_float(t) { T_float_ty(cx, t) } + ty::ty_estr(ty::vstore_uniq) | + ty::ty_str { T_ptr(T_vec(cx, T_i8())) } + ty::ty_enum(did, _) { type_of_enum(cx, did, t) } + ty::ty_estr(ty::vstore_box) { T_ptr(T_box(cx, T_i8())) } + ty::ty_evec(mt, ty::vstore_box) | + ty::ty_box(mt) { T_ptr(T_box(cx, type_of(cx, mt.ty))) } + ty::ty_opaque_box { T_ptr(T_box(cx, T_i8())) } + ty::ty_uniq(mt) { T_ptr(type_of(cx, mt.ty)) } + ty::ty_evec(mt, ty::vstore_uniq) | + ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) } + ty::ty_ptr(mt) { T_ptr(type_of(cx, mt.ty)) } + ty::ty_rptr(_, mt) { T_ptr(type_of(cx, mt.ty)) } - // Replace any typedef'd types with their equivalent non-typedef - // type. This ensures that all LLVM nominal types that contain - // Rust types are defined as the same LLVM types. If we don't do - // this then, e.g. `option<{myfield: bool}>` would be a different - // type than `option`. - let t_norm = ty::normalize_ty(cx.tcx, t); - let llty = if t != t_norm { - type_of(cx, t_norm) - } else { - alt ty::get(t).struct { - ty::ty_nil | ty::ty_bot { T_nil() } - ty::ty_bool { T_bool() } - ty::ty_int(t) { T_int_ty(cx, t) } - ty::ty_uint(t) { T_uint_ty(cx, t) } - ty::ty_float(t) { T_float_ty(cx, t) } - ty::ty_estr(ty::vstore_uniq) | - ty::ty_str { T_ptr(T_vec(cx, T_i8())) } - ty::ty_enum(did, _) { type_of_enum(cx, did, t) } - ty::ty_estr(ty::vstore_box) { T_ptr(T_box(cx, T_i8())) } - ty::ty_evec(mt, ty::vstore_box) | - ty::ty_box(mt) { T_ptr(T_box(cx, type_of(cx, mt.ty))) } - ty::ty_opaque_box { T_ptr(T_box(cx, T_i8())) } - ty::ty_uniq(mt) { T_ptr(type_of(cx, mt.ty)) } - ty::ty_evec(mt, ty::vstore_uniq) | - ty::ty_vec(mt) { T_ptr(T_vec(cx, type_of(cx, mt.ty))) } - ty::ty_ptr(mt) { T_ptr(type_of(cx, mt.ty)) } - ty::ty_rptr(_, mt) { T_ptr(type_of(cx, mt.ty)) } + ty::ty_evec(mt, ty::vstore_slice(_)) { + T_struct([T_ptr(type_of(cx, mt.ty)), + T_uint_ty(cx, ast::ty_u)]) + } - ty::ty_evec(mt, ty::vstore_slice(_)) { - T_struct([T_ptr(type_of(cx, mt.ty)), - T_uint_ty(cx, ast::ty_u)]) - } + ty::ty_estr(ty::vstore_slice(_)) { + T_struct([T_ptr(T_i8()), + T_uint_ty(cx, ast::ty_u)]) + } - ty::ty_estr(ty::vstore_slice(_)) { - T_struct([T_ptr(T_i8()), - T_uint_ty(cx, ast::ty_u)]) - } + ty::ty_estr(ty::vstore_fixed(n)) { + T_array(T_i8(), n + 1u /* +1 for trailing null */) + } - ty::ty_estr(ty::vstore_fixed(n)) { - T_array(T_i8(), n + 1u /* +1 for trailing null */) - } + ty::ty_evec(mt, ty::vstore_fixed(n)) { + T_array(type_of(cx, mt.ty), n) + } - ty::ty_evec(mt, ty::vstore_fixed(n)) { - 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 += [type_of(cx, mt_ty)]; - } - T_struct(tys) - } - ty::ty_fn(_) { T_fn_pair(cx, type_of_fn_from_ty(cx, t)) } - ty::ty_iface(_, _) { T_opaque_iface(cx) } - ty::ty_res(_, sub, substs) { - let sub1 = ty::subst(cx.tcx, substs, sub); - ret T_struct([T_i8(), type_of(cx, sub1)]); - } - ty::ty_param(_, _) { T_typaram(cx.tn) } - ty::ty_type { T_ptr(cx.tydesc_type) } - ty::ty_tup(elts) { - let mut tys = []; - for vec::each(elts) {|elt| - tys += [type_of(cx, elt)]; - } - T_struct(tys) - } - ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) } - ty::ty_constr(subt,_) { type_of(cx, subt) } - ty::ty_class(did, ts) { - // only instance vars are record fields at runtime - let fields = lookup_class_fields(cx.tcx, did); - let tys = vec::map(fields) {|f| - let t = ty::lookup_field_type(cx.tcx, did, f.id, ts); - type_of(cx, t) - }; - T_struct(tys) - } - ty::ty_self(_) { cx.tcx.sess.unimpl("type_of: ty_self \ - not implemented"); } - ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); } + ty::ty_rec(fields) { + let mut tys: [TypeRef] = []; + for vec::each(fields) {|f| + let mt_ty = f.mt.ty; + tys += [type_of(cx, mt_ty)]; } + T_struct(tys) + } + ty::ty_fn(_) { T_fn_pair(cx, type_of_fn_from_ty(cx, t)) } + ty::ty_iface(_, _) { T_opaque_iface(cx) } + ty::ty_res(_, sub, substs) { + let sub1 = ty::subst(cx.tcx, substs, sub); + ret T_struct([T_i8(), type_of(cx, sub1)]); + } + ty::ty_param(_, _) { T_typaram(cx.tn) } + ty::ty_type { T_ptr(cx.tydesc_type) } + ty::ty_tup(elts) { + let mut tys = []; + for vec::each(elts) {|elt| + tys += [type_of(cx, elt)]; + } + T_struct(tys) + } + ty::ty_opaque_closure_ptr(_) { T_opaque_box_ptr(cx) } + ty::ty_constr(subt,_) { type_of(cx, subt) } + ty::ty_class(did, ts) { + // only instance vars are record fields at runtime + let fields = lookup_class_fields(cx.tcx, did); + let tys = vec::map(fields) {|f| + let t = ty::lookup_field_type(cx.tcx, did, f.id, ts); + type_of(cx, t) + }; + T_struct(tys) + } + ty::ty_self(_) { cx.tcx.sess.unimpl("type_of: ty_self \ + not implemented"); } + ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); } }; cx.lltypes.insert(t, llty); ret llty; } -// This should only be called from type_of, above, because it -// creates new llvm named struct types lazily that are then -// cached by type_of fn type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t) -> TypeRef { - - #debug("type_of_enum %?: %?", t, ty::get(t)); - - // Every enum type has a unique name. When we find our roots - // for GC and unwinding we will use this name to rediscover - // the Rust type - let name = llvm_type_name(cx, t); - - let named_llty = common::T_named_struct(name); - - let lltys = { - let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u; - let size = shape::static_size_of_enum(cx, t); - if !degen { - [T_enum_variant(cx), T_array(T_i8(), size)] - } - else if size == 0u { - [T_enum_variant(cx)] - } - else { - [T_array(T_i8(), size)] - } - }; - - common::set_struct_body(named_llty, lltys); - ret named_llty; + let degen = (*ty::enum_variants(cx.tcx, did)).len() == 1u; + let size = shape::static_size_of_enum(cx, t); + if !degen { T_enum(cx, size) } + else if size == 0u { T_struct([T_enum_variant(cx)]) } + else { T_array(T_i8(), size) } } - -fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str { - let (name, did, tps) = alt check ty::get(t).struct { - ty::ty_enum(did, substs) { - ("enum", did, substs.tps) - } - }; - ret #fmt( - "%s %s[#%d]", - name, - util::ppaux::parameterized( - cx.tcx, - ty::item_path_str(cx.tcx, did), - none, - tps), - did.crate - ); -} - diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 909370e008f..68da6e6d734 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -149,7 +149,6 @@ export ast_ty_to_ty_cache_entry; export atttce_unresolved, atttce_resolved; export mach_sty; export ty_sort_str; -export normalize_ty; // Data types @@ -2675,27 +2674,6 @@ fn ty_params_to_tys(tcx: ty::ctxt, tps: [ast::ty_param]) -> [t] { ty::mk_param(tcx, i, ast_util::local_def(tps[i].id)) }) } - -#[doc = " -Returns an equivalent type with all the typedefs and self regions removed -"] -fn normalize_ty(cx: ctxt, t: t) -> t { - let t = alt get(t).struct { - ty_enum(did, r) { - alt r.self_r { - some(_) { - // This enum has a self region. Get rid of it - mk_enum(cx, did, {self_r: none, tps: r.tps }) - } - none { t } - } - } - _ { t } - }; - let sty = fold_sty(get(t).struct) {|t| normalize_ty(cx, t) }; - mk_t(cx, sty) -} - // Local Variables: // mode: rust // fill-column: 78; diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs index 1a27bbdff84..30e20883e52 100644 --- a/src/rustc/util/ppaux.rs +++ b/src/rustc/util/ppaux.rs @@ -128,6 +128,25 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { fn field_to_str(cx: ctxt, f: field) -> str { ret f.ident + ": " + mt_to_str(cx, f.mt); } + fn parameterized(cx: ctxt, + base: str, + self_r: option, + tps: [ty::t]) -> str { + + let r_str = alt self_r { + none { "" } + some(r) { + #fmt["/%s", region_to_str(cx, r)] + } + }; + + if vec::len(tps) > 0u { + let strs = vec::map(tps, {|t| ty_to_str(cx, t)}); + #fmt["%s%s<%s>", base, r_str, str::connect(strs, ",")] + } else { + #fmt["%s%s", base, r_str] + } + } // if there is an id, print that instead of the structural type: alt ty::type_def_id(typ) { @@ -214,26 +233,6 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { } } -fn parameterized(cx: ctxt, - base: str, - self_r: option, - tps: [ty::t]) -> str { - - let r_str = alt self_r { - none { "" } - some(r) { - #fmt["/%s", region_to_str(cx, r)] - } - }; - - if vec::len(tps) > 0u { - let strs = vec::map(tps, {|t| ty_to_str(cx, t)}); - #fmt["%s%s<%s>", base, r_str, str::connect(strs, ",")] - } else { - #fmt["%s%s", base, r_str] - } -} - fn ty_to_short_str(cx: ctxt, typ: t) -> str { let mut s = encoder::encoded_ty(cx, typ); if str::len(s) >= 32u { s = str::slice(s, 0u, 32u); }