Associate names with types introduced by items

Issue #828

This is not a full solution yet. To really get sane error messages,
we'll also have to guess the name to apply to literals, which seems
non-trivial.
This commit is contained in:
Marijn Haverbeke 2011-12-19 13:52:58 +01:00
parent 60acae4df7
commit 619d7c3f72
7 changed files with 128 additions and 184 deletions

View File

@ -107,8 +107,12 @@ fn item_type(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
}
let tp = ebml::get_doc(item, tag_items_data_item_type);
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
ret parse_ty_data(item.data, this_cnum, tp.start, tp.end - tp.start,
def_parser, tcx);
let t = parse_ty_data(item.data, this_cnum, tp.start, tp.end - tp.start,
def_parser, tcx);
if family_names_type(item_family(item)) {
t = ty::mk_named(tcx, t, @item_name(item));
}
t
}
fn item_ty_param_kinds(item: ebml::doc) -> [ast::kind] {
@ -307,6 +311,10 @@ fn family_has_type_params(fam_ch: u8) -> bool {
};
}
fn family_names_type(fam_ch: u8) -> bool {
alt fam_ch as char { 'y' | 't' { true } _ { false } }
}
fn read_path(d: ebml::doc) -> {path: str, pos: uint} {
let desc = ebml::doc_data(d);
let pos = ebml::be_uint_from_bytes(@desc, 0u, 4u);

View File

@ -314,6 +314,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_family(ebml_w, 'y' as u8);
encode_type_param_kinds(ebml_w, tps);
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
encode_name(ebml_w, item.ident);
ebml::end_tag(ebml_w);
}
item_tag(variants, tps) {
@ -322,6 +323,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_family(ebml_w, 't' as u8);
encode_type_param_kinds(ebml_w, tps);
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
encode_name(ebml_w, item.ident);
for v: variant in variants {
encode_variant_id(ebml_w, local_def(v.node.id));
}
@ -336,6 +338,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_family(ebml_w, 'y' as u8);
encode_type_param_kinds(ebml_w, tps);
encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
encode_name(ebml_w, item.ident);
encode_symbol(ecx, ebml_w, item.id);
ebml::end_tag(ebml_w);
@ -356,6 +359,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
encode_family(ebml_w, 'y' as u8);
encode_type_param_kinds(ebml_w, tps);
encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
encode_name(ebml_w, item.ident);
ebml::end_tag(ebml_w);
index += [{val: ctor_id, pos: ebml_w.writer.tell()}];

View File

@ -1712,7 +1712,6 @@ fn find_impls_in_item(i: @ast::item, &impls: [@_impl],
}
}
// FIXME[impl] we should probably cache this
fn find_impls_in_mod(e: env, m: def, &impls: [@_impl],
name: option::t<ident>) {
alt m {

View File

@ -1037,12 +1037,10 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
type get_tydesc_result = {kind: tydesc_kind, result: result};
fn get_tydesc(cx: @block_ctxt, orig_t: ty::t, escapes: bool,
fn get_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
storage: ty_param_storage, &static_ti: option::t<@tydesc_info>)
-> get_tydesc_result {
let t = ty::strip_cname(bcx_tcx(cx), orig_t);
// Is the supplied type a type param? If so, return the passed-in tydesc.
alt ty::type_param(bcx_tcx(cx), t) {
some(id) {
@ -1051,8 +1049,8 @@ fn get_tydesc(cx: @block_ctxt, orig_t: ty::t, escapes: bool,
} else {
bcx_tcx(cx).sess.span_bug(cx.sp,
"Unbound typaram in get_tydesc: " +
"orig_t = " +
ty_to_str(bcx_tcx(cx), orig_t) +
"t = " +
ty_to_str(bcx_tcx(cx), t) +
" ty_param = " +
uint::str(id));
}
@ -1071,11 +1069,8 @@ fn get_tydesc(cx: @block_ctxt, orig_t: ty::t, escapes: bool,
ret {kind: tk_static, result: rslt(cx, info.tydesc)};
}
fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint],
fn get_static_tydesc(cx: @block_ctxt, t: ty::t, ty_params: [uint],
is_obj_body: bool) -> @tydesc_info {
let t = ty::strip_cname(bcx_tcx(cx), orig_t);
alt bcx_ccx(cx).tydescs.find(t) {
some(info) { ret info; }
none. {

View File

@ -90,19 +90,18 @@ export mk_uint;
export mk_uniq;
export mk_var;
export mk_opaque_closure;
export mk_named;
export gen_ty;
export mode;
export mt;
export node_type_table;
export pat_ty;
export cname;
export rename;
export ret_ty_of_fn;
export sequence_element_type;
export struct;
export ty_name;
export sort_methods;
export stmt_node_id;
export strip_cname;
export sty;
export substitute_type_params;
export t;
@ -142,6 +141,7 @@ export ty_send_type;
export ty_uint;
export ty_uniq;
export ty_var;
export ty_named;
export ty_var_id;
export ty_param_substs_opt_and_ty_to_monotype;
export ty_fn_args;
@ -222,13 +222,9 @@ tag cast_type {
}
type ctxt =
// constr_table fn_constrs,
// We need the ext_map just for printing the types of tags defined in
// other crates. Once we get cnames back it should go.
@{ts: @type_store,
sess: session::session,
def_map: resolve::def_map,
ext_map: resolve::ext_map,
cast_map: hashmap<ast::node_id, cast_type>,
node_types: node_type_table,
items: ast_map::map,
@ -253,12 +249,10 @@ fn method_ty_to_fn_ty(cx: ctxt, m: method) -> t {
// Never construct these manually. These are interned.
type raw_t =
{struct: sty,
cname: option::t<str>,
hash: uint,
has_params: bool,
has_vars: bool};
type raw_t = {struct: sty,
hash: uint,
has_params: bool,
has_vars: bool};
type t = uint;
@ -298,6 +292,7 @@ tag sty {
ty_native(def_id);
ty_constr(t, [@type_constr]);
ty_opaque_closure; // type of a captured environment.
ty_named(t, @str);
}
// In the middle end, constraints have a def_id attached, referring
@ -380,27 +375,27 @@ type node_type_table =
@smallintmap::smallintmap<ty::ty_param_substs_opt_and_ty>;
fn populate_type_store(cx: ctxt) {
intern(cx, ty_nil, none);
intern(cx, ty_bool, none);
intern(cx, ty_int(ast::ty_i), none);
intern(cx, ty_float(ast::ty_f), none);
intern(cx, ty_uint(ast::ty_u), none);
intern(cx, ty_int(ast::ty_i8), none);
intern(cx, ty_int(ast::ty_i16), none);
intern(cx, ty_int(ast::ty_i32), none);
intern(cx, ty_int(ast::ty_i64), none);
intern(cx, ty_uint(ast::ty_u8), none);
intern(cx, ty_uint(ast::ty_u16), none);
intern(cx, ty_uint(ast::ty_u32), none);
intern(cx, ty_uint(ast::ty_u64), none);
intern(cx, ty_float(ast::ty_f32), none);
intern(cx, ty_float(ast::ty_f64), none);
intern(cx, ty_int(ast::ty_char), none);
intern(cx, ty_str, none);
intern(cx, ty_type, none);
intern(cx, ty_send_type, none);
intern(cx, ty_bot, none);
intern(cx, ty_opaque_closure, none);
intern(cx, ty_nil);
intern(cx, ty_bool);
intern(cx, ty_int(ast::ty_i));
intern(cx, ty_float(ast::ty_f));
intern(cx, ty_uint(ast::ty_u));
intern(cx, ty_int(ast::ty_i8));
intern(cx, ty_int(ast::ty_i16));
intern(cx, ty_int(ast::ty_i32));
intern(cx, ty_int(ast::ty_i64));
intern(cx, ty_uint(ast::ty_u8));
intern(cx, ty_uint(ast::ty_u16));
intern(cx, ty_uint(ast::ty_u32));
intern(cx, ty_uint(ast::ty_u64));
intern(cx, ty_float(ast::ty_f32));
intern(cx, ty_float(ast::ty_f64));
intern(cx, ty_int(ast::ty_char));
intern(cx, ty_str);
intern(cx, ty_type);
intern(cx, ty_send_type);
intern(cx, ty_bot);
intern(cx, ty_opaque_closure);
assert (vec::len(cx.ts.vect) == idx_first_others);
}
@ -417,7 +412,7 @@ fn mk_rcache() -> creader_cache {
fn mk_ctxt(s: session::session, dm: resolve::def_map,
em: hashmap<def_id, [ident]>, amap: ast_map::map,
_em: hashmap<def_id, [ident]>, amap: ast_map::map,
freevars: freevars::freevar_map) -> ctxt {
let ntt: node_type_table =
@smallintmap::mk::<ty::ty_param_substs_opt_and_ty>();
@ -427,7 +422,6 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map,
@{ts: ts,
sess: s,
def_map: dm,
ext_map: em,
cast_map: ast_util::new_node_hash(),
node_types: ntt,
items: amap,
@ -446,9 +440,8 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map,
// Type constructors
fn mk_raw_ty(cx: ctxt, st: sty, _in_cname: option::t<str>) -> @raw_t {
let cname: option::t<str> = none;
let h = hash_type_info(st, cname);
fn mk_raw_ty(cx: ctxt, st: sty) -> @raw_t {
let h = hash_type_structure(st);
let has_params: bool = false;
let has_vars: bool = false;
fn derive_flags_t(cx: ctxt, &has_params: bool, &has_vars: bool, tt: t) {
@ -505,28 +498,26 @@ fn mk_raw_ty(cx: ctxt, st: sty, _in_cname: option::t<str>) -> @raw_t {
derive_flags_t(cx, has_params, has_vars, tt);
for tt: t in tps { derive_flags_t(cx, has_params, has_vars, tt); }
}
ty_constr(tt, _) { derive_flags_t(cx, has_params, has_vars, tt); }
ty_constr(tt, _) | ty_named(tt, _) {
derive_flags_t(cx, has_params, has_vars, tt);
}
}
ret @{struct: st,
cname: cname,
hash: h,
has_params: has_params,
has_vars: has_vars};
}
fn intern(cx: ctxt, st: sty, cname: option::t<str>) {
interner::intern(*cx.ts, mk_raw_ty(cx, st, cname));
fn intern(cx: ctxt, st: sty) {
interner::intern(*cx.ts, mk_raw_ty(cx, st));
}
fn gen_ty_full(cx: ctxt, st: sty, cname: option::t<str>) -> t {
let raw_type = mk_raw_ty(cx, st, cname);
ret interner::intern(*cx.ts, raw_type);
}
// These are private constructors to this module. External users should always
// use the mk_foo() functions below.
fn gen_ty(cx: ctxt, st: sty) -> t { ret gen_ty_full(cx, st, none); }
fn gen_ty(cx: ctxt, st: sty) -> t {
let raw_type = mk_raw_ty(cx, st);
ret interner::intern(*cx.ts, raw_type);
}
fn mk_nil(_cx: ctxt) -> t { ret idx_nil; }
@ -637,13 +628,23 @@ fn mk_opaque_closure(_cx: ctxt) -> t {
ret idx_opaque_closure;
}
fn mk_named(cx: ctxt, base: t, name: @str) -> t {
gen_ty(cx, ty_named(base, name))
}
// Returns the one-level-deep type structure of the given type.
pure fn struct(cx: ctxt, typ: t) -> sty { interner::get(*cx.ts, typ).struct }
pure fn struct(cx: ctxt, typ: t) -> sty {
alt interner::get(*cx.ts, typ).struct {
ty_named(t, _) { struct(cx, t) }
s { s }
}
}
// Returns the canonical name of the given type.
fn cname(cx: ctxt, typ: t) -> option::t<str> {
ret interner::get(*cx.ts, typ).cname;
pure fn ty_name(cx: ctxt, typ: t) -> option::t<@str> {
alt interner::get(*cx.ts, typ).struct {
ty_named(_, n) { some(n) }
_ { none }
}
}
@ -705,7 +706,7 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
fm_param(_) { if !type_contains_params(cx, ty) { ret ty; } }
fm_general(_) {/* no fast path */ }
}
alt struct(cx, ty) {
alt interner::get(*cx.ts, ty).struct {
ty_nil. | ty_bot. | ty_bool. | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_str. | ty_send_type. | ty_type. | ty_native(_) | ty_opaque_closure. {
/* no-op */
@ -716,6 +717,9 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
ty_uniq(tm) {
ty = mk_uniq(cx, {ty: fold_ty(cx, fld, tm.ty), mut: tm.mut});
}
ty_named(t, nm) {
ty = mk_named(cx, fold_ty(cx, fld, t), nm);
}
ty_ptr(tm) {
ty = mk_ptr(cx, {ty: fold_ty(cx, fld, tm.ty), mut: tm.mut});
}
@ -725,7 +729,7 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
ty_tag(tid, subtys) {
let new_subtys: [t] = [];
for subty: t in subtys { new_subtys += [fold_ty(cx, fld, subty)]; }
ty = copy_cname(cx, mk_tag(cx, tid, new_subtys), ty);
ty = mk_tag(cx, tid, new_subtys);
}
ty_rec(fields) {
let new_fields: [field] = [];
@ -734,12 +738,12 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
let new_mt = {ty: new_ty, mut: fl.mt.mut};
new_fields += [{ident: fl.ident, mt: new_mt}];
}
ty = copy_cname(cx, mk_rec(cx, new_fields), ty);
ty = mk_rec(cx, new_fields);
}
ty_tup(ts) {
let new_ts = [];
for tt in ts { new_ts += [fold_ty(cx, fld, tt)]; }
ty = copy_cname(cx, mk_tup(cx, new_ts), ty);
ty = mk_tup(cx, new_ts);
}
ty_fn(proto, args, ret_ty, cf, constrs) {
let new_args: [arg] = [];
@ -747,8 +751,8 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
let new_ty = fold_ty(cx, fld, a.ty);
new_args += [{mode: a.mode, ty: new_ty}];
}
ty = copy_cname(cx, mk_fn(cx, proto, new_args,
fold_ty(cx, fld, ret_ty), cf, constrs), ty);
ty = mk_fn(cx, proto, new_args, fold_ty(cx, fld, ret_ty), cf,
constrs);
}
ty_native_fn(args, ret_ty) {
let new_args: [arg] = [];
@ -756,8 +760,7 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
let new_ty = fold_ty(cx, fld, a.ty);
new_args += [{mode: a.mode, ty: new_ty}];
}
ty = copy_cname(cx, mk_native_fn(cx, new_args,
fold_ty(cx, fld, ret_ty)), ty);
ty = mk_native_fn(cx, new_args, fold_ty(cx, fld, ret_ty));
}
ty_obj(methods) {
let new_methods: [method] = [];
@ -774,14 +777,12 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
cf: m.cf,
constrs: m.constrs}];
}
ty = copy_cname(cx, mk_obj(cx, new_methods), ty);
ty = mk_obj(cx, new_methods);
}
ty_res(did, subty, tps) {
let new_tps = [];
for tp: t in tps { new_tps += [fold_ty(cx, fld, tp)]; }
ty =
copy_cname(cx, mk_res(cx, did, fold_ty(cx, fld, subty), new_tps),
ty);
ty = mk_res(cx, did, fold_ty(cx, fld, subty), new_tps);
}
ty_var(id) {
alt fld { fm_var(folder) { ty = folder(id); } _ {/* no-op */ } }
@ -798,20 +799,6 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
// Type utilities
fn rename(cx: ctxt, typ: t, new_cname: str) -> t {
ret gen_ty_full(cx, struct(cx, typ), some(new_cname));
}
fn strip_cname(cx: ctxt, typ: t) -> t {
ret gen_ty_full(cx, struct(cx, typ), none);
}
// Returns a type with the structural part taken from `struct_ty` and the
// canonical name from `cname_ty`.
fn copy_cname(cx: ctxt, struct_ty: t, cname_ty: t) -> t {
ret gen_ty_full(cx, struct(cx, struct_ty), cname(cx, cname_ty));
}
fn type_is_nil(cx: ctxt, ty: t) -> bool {
alt struct(cx, ty) { ty_nil. { ret true; } _ { ret false; } }
}
@ -1367,25 +1354,17 @@ fn hash_type_structure(st: sty) -> uint {
ret hash_subtys(h, tps);
}
ty_constr(t, cs) {
let h = 36u;
let h = hash_subty(36u, t);
for c: @type_constr in cs { h += (h << 5u) + hash_type_constr(h, c); }
ret h;
}
ty_uniq(mt) { ret hash_subty(37u, mt.ty); }
ty_send_type. { ret 38u; }
ty_opaque_closure. { ret 39u; }
ty_named(t, name) { (str::hash(*name) << 5u) + hash_subty(40u, t) }
}
}
fn hash_type_info(st: sty, cname_opt: option::t<str>) -> uint {
let h = hash_type_structure(st);
alt cname_opt {
none. {/* no-op */ }
some(s) { h += (h << 5u) + str::hash(s); }
}
ret h;
}
fn hash_raw_ty(&&rt: @raw_t) -> uint { ret rt.hash; }
fn hash_ty(&&typ: t) -> uint { ret typ; }
@ -1435,32 +1414,15 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool {
ret true;
}
// An expensive type equality function. This function is private to this
// module.
// This function is private to this module.
fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool {
// Check hashes (fast path).
if a.hash != b.hash { ret false; }
// Check canonical names.
alt a.cname {
none. { alt b.cname { none. {/* ok */ } _ { ret false; } } }
some(s_a) {
alt b.cname {
some(s_b) { if !str::eq(s_a, s_b) { ret false; } }
_ { ret false; }
}
}
}
// Check structures.
ret a.struct == b.struct;
ret a.hash == b.hash && a.struct == b.struct;
}
// This is the equality function the public should use. It works as long as
// the types are interned.
fn eq_ty(&&a: t, &&b: t) -> bool { ret a == b; }
fn eq_ty(&&a: t, &&b: t) -> bool { a == b }
// Convert type to machine type
@ -1491,8 +1453,11 @@ fn ty_to_machine_ty(cx: ctxt, ty: t) -> t {
// machine independent primitive types by their machine type equivalents
// for the current target architecture
fn triv_eq_ty(cx: ctxt, &&a: t, &&b: t) -> bool {
ret eq_ty(a, b)
|| eq_ty(ty_to_machine_ty(cx, a), ty_to_machine_ty(cx, b));
let a = alt interner::get(*cx.ts, a).struct
{ ty_named(t, _) { t } _ { a } };
let b = alt interner::get(*cx.ts, b).struct
{ ty_named(t, _) { t } _ { b } };
a == b || ty_to_machine_ty(cx, a) == ty_to_machine_ty(cx, b)
}
// Type lookups
@ -1855,13 +1820,6 @@ mod unify {
ret ures_ok(typ);
}
// Wraps the given type in an appropriate cname.
//
// TODO: This doesn't do anything yet. We should carry the cname up from
// the expected and/or actual types when unification results in a type
// identical to one or both of the two. The precise algorithm for this is
// something we'll probably need to develop over time.
// Simple structural type comparison.
fn struct_cmp(cx: @ctxt, expected: t, actual: t) -> result {
if struct(cx.tcx, expected) == struct(cx.tcx, actual) {

View File

@ -301,7 +301,6 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
ret typ;
}
let typ;
let cname = none::<str>;
alt ast_ty.node {
ast::ty_nil. { typ = ty::mk_nil(tcx); }
ast::ty_bot. { typ = ty::mk_bot(tcx); }
@ -362,7 +361,6 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
tcx.sess.span_fatal(ast_ty.span, "internal error in instantiate");
}
}
cname = some(path_to_str(path));
}
ast::ty_obj(meths) {
let tmeths: [ty::method] = [];
@ -403,10 +401,6 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
}
}
}
alt cname {
none. {/* no-op */ }
some(cname_str) { typ = ty::rename(tcx, typ, cname_str); }
}
tcx.ast_ty_to_ty_cache.insert(ast_ty, some(typ));
ret typ;
}
@ -436,25 +430,25 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
}
// Tell ast_ty_to_ty() that we want to perform a recursive
// call to resolve any named types.
let typ = ast_ty_to_ty(tcx, mode, t);
let typ = ty::mk_named(tcx, ast_ty_to_ty(tcx, mode, t), @it.ident);
let tpt = {kinds: ty_param_kinds(tps), ty: typ};
tcx.tcache.insert(local_def(it.id), tpt);
ret tpt;
}
ast::item_res(f, _, tps, _) {
let t_arg = ty_of_arg(tcx, mode, f.decl.inputs[0]);
let t_res =
{kinds: ty_param_kinds(tps),
ty: ty::mk_res(tcx, local_def(it.id), t_arg.ty,
mk_ty_params(tcx, tps))};
let t = ty::mk_named(tcx, ty::mk_res(tcx, local_def(it.id), t_arg.ty,
mk_ty_params(tcx, tps)),
@it.ident);
let t_res = {kinds: ty_param_kinds(tps), ty: t};
tcx.tcache.insert(local_def(it.id), t_res);
ret t_res;
}
ast::item_tag(_, tps) {
// Create a new generic polytype.
let subtys: [ty::t] = mk_ty_params(tcx, tps);
let t = ty::mk_tag(tcx, local_def(it.id), subtys);
let t = ty::mk_named(tcx, ty::mk_tag(tcx, local_def(it.id), subtys),
@it.ident);
let tpt = {kinds: ty_param_kinds(tps), ty: t};
tcx.tcache.insert(local_def(it.id), tpt);
ret tpt;
@ -534,8 +528,8 @@ fn ty_of_method(tcx: ty::ctxt, mode: mode, m: @ast::method) -> ty::method {
fn ty_of_obj(tcx: ty::ctxt, mode: mode, id: ast::ident, ob: ast::_obj,
ty_params: [ast::ty_param]) -> ty::ty_param_kinds_and_ty {
let methods = ty_of_obj_methods(tcx, mode, ob);
let t_obj = ty::mk_obj(tcx, ty::sort_methods(methods));
t_obj = ty::rename(tcx, t_obj, id);
let t_obj = ty::mk_named(tcx, ty::mk_obj(tcx, ty::sort_methods(methods)),
@id);
ret {kinds: ty_param_kinds(ty_params), ty: t_obj};
}
fn ty_of_obj_methods(tcx: ty::ctxt, mode: mode, object: ast::_obj)
@ -655,19 +649,17 @@ fn ty_param_kinds(tps: [ast::ty_param]) -> [ast::kind] {
mod collect {
type ctxt = {tcx: ty::ctxt};
fn get_tag_variant_types(cx: @ctxt, tag_id: ast::def_id,
fn get_tag_variant_types(cx: @ctxt, tag_ty: ty::t,
variants: [ast::variant],
ty_params: [ast::ty_param]) {
// Create a set of parameter types shared among all the variants.
let ty_param_tys: [ty::t] = mk_ty_params(cx.tcx, ty_params);
for variant: ast::variant in variants {
// Nullary tag constructors get turned into constants; n-ary tag
// constructors get turned into functions.
let result_ty;
if vec::len::<ast::variant_arg>(variant.node.args) == 0u {
result_ty = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
let result_ty = if vec::len(variant.node.args) == 0u {
tag_ty
} else {
// As above, tell ast_ty_to_ty() that trans_ty_item_to_ty()
// should be called to resolve named types.
@ -676,13 +668,11 @@ mod collect {
let arg_ty = ast_ty_to_ty(cx.tcx, m_collect, va.ty);
args += [{mode: ast::by_copy, ty: arg_ty}];
}
let tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
// FIXME: this will be different for constrained types
result_ty =
ty::mk_fn(cx.tcx, ast::proto_shared(ast::sugar_normal),
args, tag_t,
ast::return_val, []);
}
ty::mk_fn(cx.tcx, ast::proto_shared(ast::sugar_normal),
args, tag_ty,
ast::return_val, [])
};
let tpt = {kinds: ty_param_kinds(ty_params), ty: result_ty};
cx.tcx.tcache.insert(local_def(variant.node.id), tpt);
write::ty_only(cx.tcx, variant.node.id, result_ty);
@ -695,7 +685,7 @@ mod collect {
ast::item_tag(variants, ty_params) {
let tpt = ty_of_item(cx.tcx, m_collect, it);
write::ty_only(cx.tcx, it.id, tpt.ty);
get_tag_variant_types(cx, local_def(it.id), variants, ty_params);
get_tag_variant_types(cx, tpt.ty, variants, ty_params);
}
ast::item_impl(_, selfty, ms) {
for m in ms {

View File

@ -27,20 +27,6 @@ fn fn_ident_to_string(id: ast::node_id, i: ast::fn_ident) -> str {
ret alt i { none. { "anon" + int::str(id) } some(s) { s } };
}
fn get_id_ident(cx: ctxt, id: ast::def_id) -> str {
if id.crate != ast::local_crate {
alt cx.ext_map.find(id) {
some(j) { str::connect(j, "::") }
none. { "<#" + int::str(id.crate) + ":" + int::str(id.node) + ">" }
}
} else {
alt cx.items.find(id.node) {
some(ast_map::node_item(it)) { it.ident }
_ { fail "get_id_ident: can't find item in ast_map" }
}
}
}
fn ty_to_str(cx: ctxt, typ: t) -> str {
fn fn_input_to_str(cx: ctxt, input: {mode: middle::ty::mode, ty: t}) ->
str {
@ -83,7 +69,21 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
}
ret mstr + ty_to_str(cx, m.ty);
}
alt cname(cx, typ) { some(cs) { ret cs; } _ { } }
alt ty_name(cx, typ) {
some(cs) {
alt struct(cx, typ) {
ty_tag(_, tps) | ty_res(_, _, tps) {
if vec::len(tps) > 0u {
let strs = vec::map(tps, {|t| ty_to_str(cx, t)});
ret *cs + "<" + str::connect(strs, ",") + ">";
}
}
_ {}
}
ret *cs;
}
_ { }
}
ret alt struct(cx, typ) {
ty_native(_) { "native" }
ty_nil. { "()" }
@ -111,15 +111,6 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
for elem in elems { strs += [ty_to_str(cx, elem)]; }
"(" + str::connect(strs, ",") + ")"
}
ty_tag(id, tps) {
let s = get_id_ident(cx, id);
if vec::len::<t>(tps) > 0u {
let strs: [str] = [];
for typ: t in tps { strs += [ty_to_str(cx, typ)]; }
s += "<" + str::connect(strs, ",") + ">";
}
s
}
ty_fn(proto, inputs, output, cf, constrs) {
fn_to_str(cx, proto, none, inputs, output, cf, constrs)
}
@ -132,7 +123,6 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
for m: method in meths { strs += [method_to_str(cx, m)]; }
"obj {\n\t" + str::connect(strs, "\n\t") + "\n}"
}
ty_res(id, _, _) { get_id_ident(cx, id) }
ty_var(v) { "<T" + int::str(v) + ">" }
ty_param(id, _) {
"'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)])