diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 2b4a9a78206..2381751f899 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -15,6 +15,20 @@ import front.ast.mutability; import front.creader; import middle.metadata; import util.common; + +import util.common.ty_u8; +import util.common.ty_u16; +import util.common.ty_u32; +import util.common.ty_u64; + +import util.common.ty_i8; +import util.common.ty_i16; +import util.common.ty_i32; +import util.common.ty_i64; + +import util.common.ty_f32; +import util.common.ty_f64; + import util.common.new_def_hash; import util.common.span; import util.typestate_ann.ts_ann; @@ -102,13 +116,74 @@ tag type_err { type ty_param_count_and_ty = tup(uint, t); type type_cache = hashmap[ast.def_id,ty_param_count_and_ty]; +type type_store = rec(vec[ty.t] empty_vec_ty, + vec[mutable ty.t] empty_vec_mutable_ty, + ty.t t_nil, + ty.t t_bool, + ty.t t_int, + ty.t t_float, + ty.t t_uint, -type type_store = hashmap[t,t]; + ty.t t_i8, + ty.t t_i16, + ty.t t_i32, + ty.t t_i64, + + ty.t t_u8, + ty.t t_u16, + ty.t t_u32, + ty.t t_u64, + + ty.t t_f32, + ty.t t_f64, + + ty.t t_char, + ty.t t_str, + + ty.t t_native, + ty.t t_type, + + mutable vec[ty.t] t_params, + mutable vec[ty.t] t_bound_params, + mutable vec[ty.t] t_vars, + hashmap[t,t] others); fn mk_type_store() -> @type_store { auto hasher = hash_ty; auto eqer = eq_ty_full; - ret @map.mk_hashmap[t,t](hasher, eqer); + + ret @rec(empty_vec_ty = _vec.empty[ty.t](), + empty_vec_mutable_ty = _vec.empty_mut[ty.t](), + t_nil = mk_ty_full(ty_nil, none[str]), + t_bool = mk_ty_full(ty_bool, none[str]), + t_int = mk_ty_full(ty_int, none[str]), + t_float = mk_ty_full(ty_float, none[str]), + t_uint = mk_ty_full(ty_uint, none[str]), + + t_i8 = mk_ty_full(ty_machine(ty_i8), none[str]), + t_i16 = mk_ty_full(ty_machine(ty_i16), none[str]), + t_i32 = mk_ty_full(ty_machine(ty_i32), none[str]), + t_i64 = mk_ty_full(ty_machine(ty_i64), none[str]), + + t_u8 = mk_ty_full(ty_machine(ty_u8), none[str]), + t_u16 = mk_ty_full(ty_machine(ty_u16), none[str]), + t_u32 = mk_ty_full(ty_machine(ty_u32), none[str]), + t_u64 = mk_ty_full(ty_machine(ty_u64), none[str]), + + t_f32 = mk_ty_full(ty_machine(ty_f32), none[str]), + t_f64 = mk_ty_full(ty_machine(ty_f64), none[str]), + + t_char = mk_ty_full(ty_char, none[str]), + t_str = mk_ty_full(ty_str, none[str]), + + t_native = mk_ty_full(ty_native, none[str]), + t_type = mk_ty_full(ty_type, none[str]), + + mutable t_params = _vec.empty[ty.t](), + mutable t_bound_params = _vec.empty[ty.t](), + mutable t_vars = _vec.empty[ty.t](), + + others=map.mk_hashmap[t,t](hasher, eqer)); } // Type constructors @@ -119,36 +194,53 @@ fn gen_ty(@type_store tystore, &sty st) -> t { ret gen_ty_full(tystore, st, none[str]); } -fn gen_ty_full(@type_store tystore, &sty st, option.t[str] cname) -> t { +fn mk_ty_full(&sty st, option.t[str] cname) -> t { auto h = hash_type_info(st, cname); auto magic = mk_magic(st); - auto new_type = @rec(struct=st, cname=cname, magic=magic, hash=h); + ret @rec(struct=st, cname=cname, magic=magic, hash=h); +} +fn gen_ty_full(@type_store tystore, &sty st, option.t[str] cname) -> t { + auto new_type = mk_ty_full(st, cname); // Is it interned? - alt (tystore.find(new_type)) { + alt (tystore.others.find(new_type)) { case (some[t](?typ)) { ret typ; } case (none[t]) { // Nope. Insert it and return. - tystore.insert(new_type, new_type); + tystore.others.insert(new_type, new_type); ret new_type; } } } -fn mk_nil(@type_store ts) -> t { ret gen_ty(ts, ty_nil); } -fn mk_bool(@type_store ts) -> t { ret gen_ty(ts, ty_bool); } -fn mk_int(@type_store ts) -> t { ret gen_ty(ts, ty_int); } -fn mk_float(@type_store ts) -> t { ret gen_ty(ts, ty_float); } -fn mk_uint(@type_store ts) -> t { ret gen_ty(ts, ty_uint); } +fn mk_nil(@type_store ts) -> t { ret ts.t_nil; } +fn mk_bool(@type_store ts) -> t { ret ts.t_bool; } +fn mk_int(@type_store ts) -> t { ret ts.t_int; } +fn mk_float(@type_store ts) -> t { ret ts.t_float; } +fn mk_uint(@type_store ts) -> t { ret ts.t_uint; } fn mk_mach(@type_store ts, util.common.ty_mach tm) -> t { - ret gen_ty(ts, ty_machine(tm)); + alt (tm) { + case (ty_u8) { ret ts.t_u8; } + case (ty_u16) { ret ts.t_u16; } + case (ty_u32) { ret ts.t_u32; } + case (ty_u64) { ret ts.t_u64; } + + case (ty_i8) { ret ts.t_i8; } + case (ty_i16) { ret ts.t_i16; } + case (ty_i32) { ret ts.t_i32; } + case (ty_i64) { ret ts.t_i64; } + + case (ty_f32) { ret ts.t_f32; } + case (ty_f64) { ret ts.t_f64; } + } + fail; } -fn mk_char(@type_store ts) -> t { ret gen_ty(ts, ty_char); } -fn mk_str(@type_store ts) -> t { ret gen_ty(ts, ty_str); } +fn mk_char(@type_store ts) -> t { ret ts.t_char; } +fn mk_str(@type_store ts) -> t { ret ts.t_str; } fn mk_tag(@type_store ts, ast.def_id did, vec[t] tys) -> t { ret gen_ty(ts, ty_tag(did, tys)); @@ -197,22 +289,39 @@ fn mk_obj(@type_store ts, vec[method] meths) -> t { ret gen_ty(ts, ty_obj(meths)); } -fn mk_var(@type_store ts, int v) -> t { ret gen_ty(ts, ty_var(v)); } +fn mk_var(@type_store ts, int v) -> t { + let int i = _vec.len[t](ts.t_vars) as int; + while (i <= v) { + ts.t_vars += vec(mk_ty_full(ty_var(i), none[str])); + i += 1; + } + ret ts.t_vars.(v); +} fn mk_local(@type_store ts, ast.def_id did) -> t { ret gen_ty(ts, ty_local(did)); } fn mk_param(@type_store ts, uint n) -> t { - ret gen_ty(ts, ty_param(n)); + let uint i = _vec.len[t](ts.t_params); + while (i <= n) { + ts.t_params += vec(mk_ty_full(ty_param(i), none[str])); + i += 1u; + } + ret ts.t_params.(n); } fn mk_bound_param(@type_store ts, uint n) -> t { - ret gen_ty(ts, ty_bound_param(n)); + let uint i = _vec.len[t](ts.t_bound_params); + while (i <= n) { + ts.t_bound_params += vec(mk_ty_full(ty_bound_param(i), none[str])); + i += 1u; + } + ret ts.t_bound_params.(n); } -fn mk_type(@type_store ts) -> t { ret gen_ty(ts, ty_type); } -fn mk_native(@type_store ts) -> t { ret gen_ty(ts, ty_native); } +fn mk_type(@type_store ts) -> t { ret ts.t_type; } +fn mk_native(@type_store ts) -> t { ret ts.t_native; } // Returns the one-level-deep type structure of the given type. diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index f86e2c4f95c..9aef66aaf68 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -106,7 +106,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn) -> ty_param_count_and_ty { alt (defn) { case (ast.def_arg(?id)) { - check (fcx.locals.contains_key(id)); + // check (fcx.locals.contains_key(id)); ret tup(0u, fcx.locals.get(id)); } case (ast.def_local(?id)) { @@ -118,7 +118,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn) ret tup(0u, t); } case (ast.def_obj_field(?id)) { - check (fcx.locals.contains_key(id)); + // check (fcx.locals.contains_key(id)); ret tup(0u, fcx.locals.get(id)); } case (ast.def_fn(?id)) { @@ -138,7 +138,7 @@ fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn) fcx.ccx.type_cache, vid); } case (ast.def_binding(?id)) { - check (fcx.locals.contains_key(id)); + // check (fcx.locals.contains_key(id)); ret tup(0u, fcx.locals.get(id)); } case (ast.def_obj(?id)) { @@ -406,7 +406,7 @@ mod Collect { ret creader.get_type(cx.sess, cx.tystore, id); } - check (cx.id_to_ty_item.contains_key(id)); + // check (cx.id_to_ty_item.contains_key(id)); auto it = cx.id_to_ty_item.get(id); auto tpt; @@ -493,15 +493,17 @@ mod Collect { ret cx.type_cache.get(odid.ty); } - case (ast.item_ty(?ident, ?ty, ?tps, ?def_id, _)) { - if (cx.type_cache.contains_key(def_id)) { - // Avoid repeating work. - ret cx.type_cache.get(def_id); + case (ast.item_ty(?ident, ?t, ?tps, ?def_id, _)) { + alt (cx.type_cache.find(def_id)) { + case (some[ty.ty_param_count_and_ty](?tpt)) { + ret tpt; + } + case (none[ty.ty_param_count_and_ty]) {} } // Tell ast_ty_to_ty() that we want to perform a recursive // call to resolve any named types. - auto typ = convert(ty); + auto typ = convert(t); auto ty_param_count = _vec.len[ast.ty_param](tps); auto tpt = tup(ty_param_count, typ); cx.type_cache.insert(def_id, tpt); @@ -543,9 +545,11 @@ mod Collect { def_id); } case (ast.native_item_ty(_, ?def_id)) { - if (cx.type_cache.contains_key(def_id)) { - // Avoid repeating work. - ret cx.type_cache.get(def_id); + alt (cx.type_cache.find(def_id)) { + case (some[ty.ty_param_count_and_ty](?tpt)) { + ret tpt; + } + case (none[ty.ty_param_count_and_ty]) {} } auto t = ty.mk_native(cx.tystore); @@ -661,7 +665,7 @@ mod Collect { fn fold_item_const(&@env e, &span sp, ast.ident i, @ast.ty t, @ast.expr ex, ast.def_id id, ast.ann a) -> @ast.item { - check (e.cx.type_cache.contains_key(id)); + // check (e.cx.type_cache.contains_key(id)); auto typ = e.cx.type_cache.get(id)._1; auto item = ast.item_const(i, t, ex, id, triv_ann(typ)); ret @fold.respan[ast.item_](sp, item); @@ -670,7 +674,7 @@ mod Collect { fn fold_item_fn(&@env e, &span sp, ast.ident i, &ast._fn f, vec[ast.ty_param] ty_params, ast.def_id id, ast.ann a) -> @ast.item { - check (e.cx.type_cache.contains_key(id)); + // check (e.cx.type_cache.contains_key(id)); auto typ = e.cx.type_cache.get(id)._1; auto item = ast.item_fn(i, f, ty_params, id, triv_ann(typ)); ret @fold.respan[ast.item_](sp, item); @@ -679,7 +683,7 @@ mod Collect { fn fold_native_item_fn(&@env e, &span sp, ast.ident i, option.t[str] ln, &ast.fn_decl d, vec[ast.ty_param] ty_params, ast.def_id id, ast.ann a) -> @ast.native_item { - check (e.cx.type_cache.contains_key(id)); + // check (e.cx.type_cache.contains_key(id)); auto typ = e.cx.type_cache.get(id)._1; auto item = ast.native_item_fn(i, ln, d, ty_params, id, triv_ann(typ)); @@ -710,7 +714,7 @@ mod Collect { fn fold_item_obj(&@env e, &span sp, ast.ident i, &ast._obj ob, vec[ast.ty_param] ty_params, ast.obj_def_ids odid, ast.ann a) -> @ast.item { - check (e.cx.type_cache.contains_key(odid.ctor)); + // check (e.cx.type_cache.contains_key(odid.ctor)); auto t = e.cx.type_cache.get(odid.ctor)._1; let vec[method] meth_tys = get_ctor_obj_methods(e, t); let vec[@ast.method] methods = vec(); @@ -766,7 +770,7 @@ mod Collect { fn fold_item_ty(&@env e, &span sp, ast.ident i, @ast.ty t, vec[ast.ty_param] ty_params, ast.def_id id, ast.ann a) -> @ast.item { - check (e.cx.type_cache.contains_key(id)); + // check (e.cx.type_cache.contains_key(id)); auto typ = e.cx.type_cache.get(id)._1; auto item = ast.item_ty(i, t, ty_params, id, triv_ann(typ)); ret @fold.respan[ast.item_](sp, item); @@ -841,13 +845,16 @@ mod Unify { fn with_params(@fn_ctxt fcx, ty.t expected, ty.t actual, vec[mutable ty.t] param_substs) -> ty.Unify.result { auto cache_key = tup(expected, actual, param_substs); - if (fcx.ccx.unify_cache.contains_key(cache_key)) { - fcx.ccx.cache_hits += 1u; - ret fcx.ccx.unify_cache.get(cache_key); + alt (fcx.ccx.unify_cache.find(cache_key)) { + case (some[ty.Unify.result](?r)) { + fcx.ccx.cache_hits += 1u; + ret r; + } + case (none[ty.Unify.result]) { + fcx.ccx.cache_misses += 1u; + } } - fcx.ccx.cache_misses += 1u; - obj unify_handler(@fn_ctxt fcx, vec[mutable ty.t] param_substs) { fn resolve_local(ast.def_id id) -> option.t[ty.t] { alt (fcx.locals.find(id)) { @@ -1502,11 +1509,18 @@ fn writeback_local(&option.t[@fn_ctxt] env, &span sp, @ast.local local) -> @ast.decl { auto fcx = option.get[@fn_ctxt](env); - if (!fcx.locals.contains_key(local.id)) { - fcx.ccx.sess.span_err(sp, "unable to determine type of local: " - + local.ident); + auto local_ty; + alt (fcx.locals.find(local.id)) { + case (none[ty.t]) { + fcx.ccx.sess.span_err(sp, "unable to determine type of local: " + + local.ident); + fail; + } + case (some[ty.t](?lt)) { + local_ty = lt; + } } - auto local_ty = fcx.locals.get(local.id); + auto local_wb = @rec(ann=triv_ann(local_ty) with *local );