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:
parent
60acae4df7
commit
619d7c3f72
@ -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);
|
||||
|
@ -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()}];
|
||||
|
@ -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 {
|
||||
|
@ -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. {
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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)])
|
||||
|
Loading…
x
Reference in New Issue
Block a user