diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/driver/rustc.rs | 6 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 104 | ||||
| -rw-r--r-- | src/comp/middle/ty.rs | 63 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 199 |
4 files changed, 218 insertions, 154 deletions
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index dcb12e9b..5d5ba1d5 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -103,8 +103,9 @@ fn compile_input(session::session sess, auto typeck_result = time[typeck::typecheck_result](time_passes, "typechecking", bind typeck::check_crate(ty_cx, crate)); - crate = typeck_result._0; + auto node_type_table = typeck_result._0; auto type_cache = typeck_result._1; + crate = typeck_result._2; if (sess.get_opts().run_typestate) { crate = time(time_passes, "typestate checking", @@ -112,7 +113,8 @@ fn compile_input(session::session sess, } auto llmod = time[llvm::ModuleRef](time_passes, "translation", - bind trans::trans_crate(sess, crate, ty_cx, type_cache, output)); + bind trans::trans_crate(sess, crate, ty_cx, node_type_table, + type_cache, output)); time[()](time_passes, "LLVM passes", bind Link::Write::run_passes(sess, llmod, output)); diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 09156cab..7a55be10 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -19,6 +19,7 @@ import back::x86; import back::abi; import back::upcall; +import middle::ty::node_type_table; import middle::ty::pat_ty; import util::common; @@ -128,7 +129,8 @@ state type crate_ctxt = rec(session::session sess, hashmap[ty::t, str] type_short_names, ty::ctxt tcx, stats stats, - @upcall::upcalls upcalls); + @upcall::upcalls upcalls, + node_type_table node_types); type local_ctxt = rec(vec[str] path, vec[str] module_path, @@ -3270,7 +3272,7 @@ fn target_type(&@crate_ctxt cx, &ty::t t) -> ty::t { // Converts an annotation to a type fn node_ann_type(&@crate_ctxt cx, &ast::ann a) -> ty::t { - ret target_type(cx, ty::ann_to_monotype(cx.tcx, a)); + ret target_type(cx, ty::ann_to_monotype(cx.tcx, cx.node_types, a)); } fn node_ann_ty_params(&ast::ann a) -> vec[ty::t] { @@ -3299,22 +3301,25 @@ fn trans_unary(&@block_ctxt cx, ast::unop op, &@ast::expr e, &ast::ann a) -> result { auto sub = trans_expr(cx, e); - auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); + auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, e); alt (op) { case (ast::bitnot) { sub = autoderef(sub.bcx, sub.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, e)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e)); ret res(sub.bcx, sub.bcx.build.Not(sub.val)); } case (ast::not) { sub = autoderef(sub.bcx, sub.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, e)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e)); ret res(sub.bcx, sub.bcx.build.Not(sub.val)); } case (ast::neg) { sub = autoderef(sub.bcx, sub.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, e)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e)); if(ty::struct(cx.fcx.lcx.ccx.tcx, e_ty) == ty::ty_float) { ret res(sub.bcx, sub.bcx.build.FNeg(sub.val)); } @@ -3323,7 +3328,8 @@ fn trans_unary(&@block_ctxt cx, ast::unop op, } } case (ast::box(_)) { - auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); + auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e); auto e_val = sub.val; auto box_ty = node_ann_type(sub.bcx.fcx.lcx.ccx, a); sub = trans_malloc_boxed(sub.bcx, e_ty); @@ -3579,12 +3585,14 @@ fn trans_binary(&@block_ctxt cx, ast::binop op, // Lazy-eval and auto lhs_res = trans_expr(cx, a); lhs_res = autoderef(lhs_res.bcx, lhs_res.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, a)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, a)); auto rhs_cx = new_scope_block_ctxt(cx, "rhs"); auto rhs_res = trans_expr(rhs_cx, b); rhs_res = autoderef(rhs_res.bcx, rhs_res.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, b)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, b)); auto lhs_false_cx = new_scope_block_ctxt(cx, "lhs false"); auto lhs_false_res = res(lhs_false_cx, C_bool(false)); @@ -3601,12 +3609,14 @@ fn trans_binary(&@block_ctxt cx, ast::binop op, // Lazy-eval or auto lhs_res = trans_expr(cx, a); lhs_res = autoderef(lhs_res.bcx, lhs_res.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, a)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, a)); auto rhs_cx = new_scope_block_ctxt(cx, "rhs"); auto rhs_res = trans_expr(rhs_cx, b); rhs_res = autoderef(rhs_res.bcx, rhs_res.val, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, b)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, b)); auto lhs_true_cx = new_scope_block_ctxt(cx, "lhs true"); auto lhs_true_res = res(lhs_true_cx, C_bool(true)); @@ -3622,10 +3632,12 @@ fn trans_binary(&@block_ctxt cx, ast::binop op, case (_) { // Remaining cases are eager: auto lhs = trans_expr(cx, a); - auto lhty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, a); + auto lhty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, a); lhs = autoderef(lhs.bcx, lhs.val, lhty); auto rhs = trans_expr(lhs.bcx, b); - auto rhty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, b); + auto rhty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, b); rhs = autoderef(rhs.bcx, rhs.val, rhty); ret trans_eager_binop(rhs.bcx, op, autoderefed_ty(cx.fcx.lcx.ccx, lhty), lhs.val, rhs.val); @@ -3702,7 +3714,8 @@ fn trans_if(&@block_ctxt cx, &@ast::expr cond, // If we have an else expression, then the entire // if expression can have a non-nil type. // FIXME: This isn't quite right, particularly re: dynamic types - auto expr_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, elexpr); + auto expr_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, elexpr); if (ty::type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, expr_ty)) { expr_llty = T_typaram_ptr(cx.fcx.lcx.ccx.tn); } else { @@ -3759,7 +3772,8 @@ fn trans_for(&@block_ctxt cx, } auto next_cx = new_sub_block_ctxt(cx, "next"); - auto seq_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, seq); + auto seq_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, + seq); auto seq_res = trans_expr(cx, seq); auto it = iter_sequence(seq_res.bcx, seq_res.val, seq_ty, bind inner(_, local, _, _, body, next_cx)); @@ -4091,7 +4105,7 @@ fn trans_pat_match(&@block_ctxt cx, &@ast::pat pat, ValueRef llval, case (ast::pat_lit(?lt, ?ann)) { auto lllit = trans_lit(cx.fcx.lcx.ccx, *lt, ann); - auto lltype = ty::ann_to_type(ann); + auto lltype = ty::ann_to_type(cx.fcx.lcx.ccx.node_types, ann); auto lleq = trans_compare(cx, ast::eq, lltype, llval, lllit); auto matched_cx = new_sub_block_ctxt(lleq.bcx, "matched_cx"); @@ -4141,7 +4155,9 @@ fn trans_pat_match(&@block_ctxt cx, &@ast::pat pat, ValueRef llval, matched_cx = rslt.bcx; auto llsubval = load_if_immediate(matched_cx, - llsubvalptr, pat_ty(cx.fcx.lcx.ccx.tcx, subpat)); + llsubvalptr, pat_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, + subpat)); auto subpat_res = trans_pat_match(matched_cx, subpat, llsubval, next_cx); matched_cx = subpat_res.bcx; @@ -4237,7 +4253,7 @@ fn trans_alt(&@block_ctxt cx, &@ast::expr expr, "non-exhaustive match failure"); // FIXME: This isn't quite right, particularly re: dynamic types - auto expr_ty = ty::ann_to_type(ann); + auto expr_ty = ty::ann_to_type(cx.fcx.lcx.ccx.node_types, ann); auto expr_llty; if (ty::type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, expr_ty)) { expr_llty = T_typaram_ptr(cx.fcx.lcx.ccx.tn); @@ -4499,7 +4515,9 @@ fn trans_index(&@block_ctxt cx, &ast::span sp, &@ast::expr base, &@ast::expr idx, &ast::ann ann) -> lval_result { auto lv = trans_expr(cx, base); - lv = autoderef(lv.bcx, lv.val, ty::expr_ty(cx.fcx.lcx.ccx.tcx, base)); + lv = autoderef(lv.bcx, lv.val, ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, + base)); auto ix = trans_expr(lv.bcx, idx); auto v = lv.val; auto bcx = ix.bcx; @@ -4565,7 +4583,8 @@ fn trans_lval(&@block_ctxt cx, &@ast::expr e) -> lval_result { } case (ast::expr_field(?base, ?ident, ?ann)) { auto r = trans_expr(cx, base); - auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, base); + auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, base); ret trans_field(r.bcx, e.span, r.val, t, ident, ann); } case (ast::expr_index(?base, ?idx, ?ann)) { @@ -4626,7 +4645,8 @@ fn trans_cast(&@block_ctxt cx, &@ast::expr e, &ast::ann ann) -> result { if (!ty::type_is_fp(cx.fcx.lcx.ccx.tcx, t)) { // TODO: native-to-native casts if (ty::type_is_native(cx.fcx.lcx.ccx.tcx, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, e))) { + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e))) { e_res.val = e_res.bcx.build.PtrToInt(e_res.val, lldsttype); } else if (ty::type_is_native(cx.fcx.lcx.ccx.tcx, t)) { e_res.val = e_res.bcx.build.IntToPtr(e_res.val, lldsttype); @@ -4716,7 +4736,7 @@ fn trans_bind_thunk(&@local_ctxt cx, // Arg provided at binding time; thunk copies it from closure. case (some[@ast::expr](?e)) { - auto e_ty = ty::expr_ty(cx.ccx.tcx, e); + auto e_ty = ty::expr_ty(cx.ccx.tcx, cx.ccx.node_types, e); auto bound_arg = GEP_tup_like(bcx, closure_ty, llclosure, vec(0, @@ -4812,7 +4832,8 @@ fn trans_bind(&@block_ctxt cx, &@ast::expr f, let vec[ValueRef] lltydescs; alt (f_res.generic) { case (none[generic_info]) { - outgoing_fty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, f); + outgoing_fty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, f); lltydescs = vec(); } case (some[generic_info](?ginfo)) { @@ -4841,7 +4862,8 @@ fn trans_bind(&@block_ctxt cx, &@ast::expr f, _vec::push[ValueRef](bound_vals, arg.val); _vec::push[ty::t](bound_tys, - ty::expr_ty(cx.fcx.lcx.ccx.tcx, e)); + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e)); i += 1u; } @@ -4988,7 +5010,7 @@ fn trans_arg_expr(&@block_ctxt cx, auto val; auto bcx = cx; - auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); + auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, e); if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, e_ty)) { auto re = trans_expr(bcx, e); @@ -5188,13 +5210,13 @@ fn trans_call(&@block_ctxt cx, &@ast::expr f, } case (_) { - fn_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, f); - + fn_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, + f); } } - auto ret_ty = ty::ann_to_type(ann); + auto ret_ty = ty::ann_to_type(cx.fcx.lcx.ccx.node_types, ann); auto args_res = trans_args(f_res.res.bcx, llenv, f_res.llobj, f_res.generic, @@ -5249,7 +5271,8 @@ fn trans_tup(&@block_ctxt cx, &vec[ast::elt] elts, let int i = 0; for (ast::elt e in elts) { - auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e.expr); + auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, + e.expr); auto src_res = trans_expr(bcx, e.expr); bcx = src_res.bcx; auto dst_res = GEP_tup_like(bcx, t, tup_val, vec(0, i)); @@ -5565,7 +5588,7 @@ fn trans_expr(&@block_ctxt cx, &@ast::expr e) -> result { // lval cases fall through to trans_lval and then // possibly load the result (if it's non-structural). - auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); + auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, e); auto sub = trans_lval(cx, e); ret res(sub.res.bcx, load_if_immediate(sub.res.bcx, sub.res.val, t)); } @@ -5626,7 +5649,7 @@ fn trans_log(int lvl, &@block_ctxt cx, &@ast::expr e) -> result { cx.build.CondBr(test, log_cx.llbb, after_cx.llbb); auto sub = trans_expr(log_cx, e); - auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); + auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, cx.fcx.lcx.ccx.node_types, e); auto log_bcx = sub.bcx; if (ty::type_is_fp(cx.fcx.lcx.ccx.tcx, e_ty)) { @@ -5744,7 +5767,8 @@ fn trans_put(&@block_ctxt cx, &option::t[@ast::expr] e) -> result { alt (e) { case (none[@ast::expr]) { } case (some[@ast::expr](?x)) { - auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, x); + auto e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, x); auto arg = rec(mode=ty::mo_alias, ty=e_ty); auto arg_tys = type_of_explicit_args(cx.fcx.lcx.ccx, vec(arg)); auto r = trans_arg_expr(bcx, arg, arg_tys.(0), x); @@ -5804,7 +5828,8 @@ fn trans_ret(&@block_ctxt cx, &option::t[@ast::expr] e) -> result { alt (e) { case (some[@ast::expr](?x)) { - auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, x); + auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, x); auto r = trans_expr(cx, x); bcx = r.bcx; val = r.val; @@ -6192,7 +6217,8 @@ fn trans_block(&@block_ctxt cx, &ast::block b) -> result { if (is_terminated(bcx)) { ret r; } else { - auto r_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e); + auto r_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, + cx.fcx.lcx.ccx.node_types, e); if (!ty::type_is_nil(cx.fcx.lcx.ccx.tcx, r_ty)) { // The value resulting from the block gets copied into an // alloca created in an outer scope and its refcount @@ -6416,7 +6442,7 @@ fn is_terminated(&@block_ctxt cx) -> bool { } fn arg_tys_of_fn(&@crate_ctxt ccx, ast::ann ann) -> vec[ty::arg] { - alt (ty::struct(ccx.tcx, ty::ann_to_type(ann))) { + alt (ty::struct(ccx.tcx, ty::ann_to_type(ccx.node_types, ann))) { case (ty::ty_fn(_, ?arg_tys, _)) { ret arg_tys; } @@ -6435,7 +6461,7 @@ fn ret_ty_of_fn_ty(&@crate_ctxt ccx, ty::t t) -> ty::t { fn ret_ty_of_fn(&@crate_ctxt ccx, ast::ann ann) -> ty::t { - ret ret_ty_of_fn_ty(ccx, ty::ann_to_type(ann)); + ret ret_ty_of_fn_ty(ccx, ty::ann_to_type(ccx.node_types, ann)); } fn populate_fn_ctxt_from_llself(@fn_ctxt fcx, self_vt llself) { @@ -7920,7 +7946,8 @@ fn create_crate_map(&@crate_ctxt ccx) -> ValueRef { } fn trans_crate(&session::session sess, &@ast::crate crate, &ty::ctxt tcx, - &ty::type_cache type_cache, &str output) + &ty::node_type_table node_types, &ty::type_cache type_cache, + &str output) -> ModuleRef { auto llmod = llvm::LLVMModuleCreateWithNameInContext(_str::buf("rust_out"), @@ -7978,7 +8005,8 @@ fn trans_crate(&session::session sess, &@ast::crate crate, &ty::ctxt tcx, mutable n_glues_created = 0u, mutable n_null_glues = 0u, mutable n_real_glues = 0u), - upcalls = upcall::declare_upcalls(tn, llmod)); + upcalls = upcall::declare_upcalls(tn, llmod), + node_types = node_types); auto cx = new_local_ctxt(ccx); create_typedefs(ccx); diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index ad876b38..6e04916a 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -162,6 +162,8 @@ const uint idx_first_others = 20u; type type_store = rec(mutable vec[raw_t] others, hashmap[raw_t,uint] other_structural); +type node_type_table = vec[ty::ty_param_count_and_ty]; + fn mk_type_store() -> @type_store { let vec[raw_t] others = vec(); let hashmap[raw_t,uint] ost = @@ -1431,7 +1433,7 @@ fn eq_raw_ty(&raw_t a, &raw_t b) -> bool { fn eq_ty(&t a, &t b) -> bool { ret a == b; } -fn ann_to_type(&ast::ann ann) -> t { +fn ann_to_type(&node_type_table ntt, &ast::ann ann) -> t { alt (ann) { case (ast::ann_none(_)) { log_err "ann_to_type() called on node with no type"; @@ -1443,7 +1445,7 @@ fn ann_to_type(&ast::ann ann) -> t { } } -fn ann_to_type_params(&ast::ann ann) -> vec[t] { +fn ann_to_type_params(&node_type_table ntt, &ast::ann ann) -> vec[t] { alt (ann) { case (ast::ann_none(_)) { log_err "ann_to_type_params() called on node with no type params"; @@ -1463,7 +1465,7 @@ fn ann_to_type_params(&ast::ann ann) -> vec[t] { // Returns the type of an annotation, with type parameter substitutions // performed if applicable. -fn ann_to_monotype(ctxt cx, ast::ann a) -> t { +fn ann_to_monotype(ctxt cx, &node_type_table ntt, ast::ann a) -> t { // TODO: Refactor to use recursive pattern matching when we're more // confident that it works. alt (a) { @@ -1575,54 +1577,55 @@ fn is_fn_ty(&ctxt cx, &t fty) -> bool { // Given an item, returns the associated type as well as the number of type // parameters it has. -fn native_item_ty(&@ast::native_item it) -> ty_param_count_and_ty { +fn native_item_ty(&node_type_table ntt, &@ast::native_item it) + -> ty_param_count_and_ty { auto ty_param_count; auto result_ty; alt (it.node) { case (ast::native_item_fn(_, _, _, ?tps, _, ?ann)) { ty_param_count = _vec::len[ast::ty_param](tps); - result_ty = ann_to_type(ann); + result_ty = ann_to_type(ntt, ann); } } ret tup(ty_param_count, result_ty); } -fn item_ty(&@ast::item it) -> ty_param_count_and_ty { +fn item_ty(&node_type_table ntt, &@ast::item it) -> ty_param_count_and_ty { auto ty_param_count; auto result_ty; alt (it.node) { case (ast::item_const(_, _, _, _, ?ann)) { ty_param_count = 0u; - result_ty = ann_to_type(ann); + result_ty = ann_to_type(ntt, ann); } case (ast::item_fn(_, _, ?tps, _, ?ann)) { ty_param_count = _vec::len[ast::ty_param](tps); - result_ty = ann_to_type(ann); + result_ty = ann_to_type(ntt, ann); } case (ast::item_mod(_, _, _)) { fail; // modules are typeless } case (ast::item_ty(_, _, ?tps, _, ?ann)) { ty_param_count = _vec::len[ast::ty_param](tps); - result_ty = ann_to_type(ann); + result_ty = ann_to_type(ntt, ann); } case (ast::item_tag(_, _, ?tps, ?did, ?ann)) { ty_param_count = _vec::len[ast::ty_param](tps); - result_ty = ann_to_type(ann); + result_ty = ann_to_type(ntt, ann); } case (ast::item_obj(_, _, ?tps, _, ?ann)) { ty_param_count = _vec::len[ast::ty_param](tps); - result_ty = ann_to_type(ann); + result_ty = ann_to_type(ntt, ann); } } ret tup(ty_param_count, result_ty); } -fn stmt_ty(&ctxt cx, &@ast::stmt s) -> t { +fn stmt_ty(&ctxt cx, &node_type_table ntt, &@ast::stmt s) -> t { alt (s.node) { case (ast::stmt_expr(?e,_)) { - ret expr_ty(cx, e); + ret expr_ty(cx, ntt, e); } case (_) { ret mk_nil(cx); @@ -1630,21 +1633,25 @@ fn stmt_ty(&ctxt cx, &@ast::stmt s) -> t { } } -fn block_ty(&ctxt cx, &ast::block b) -> t { +fn block_ty(&ctxt cx, &node_type_table ntt, &ast::block b) -> t { alt (b.node.expr) { - case (some[@ast::expr](?e)) { ret expr_ty(cx, e); } + case (some[@ast::expr](?e)) { ret expr_ty(cx, ntt, e); } case (none[@ast::expr]) { ret mk_nil(cx); } } } // Returns the type of a pattern as a monotype. Like @expr_ty, this function // doesn't provide type parameter substitutions. -fn pat_ty(&ctxt cx, &@ast::pat pat) -> t { +fn pat_ty(&ctxt cx, &node_type_table ntt, &@ast::pat pat) -> t { alt (pat.node) { - case (ast::pat_wild(?ann)) { ret ann_to_monotype(cx, ann); } - case (ast::pat_lit(_, ?ann)) { ret ann_to_monotype(cx, ann); } - case (ast::pat_bind(_, _, ?ann)) { ret ann_to_monotype(cx, ann); } - case (ast::pat_tag(_, _, ?ann)) { ret ann_to_monotype(cx, ann); } + case (ast::pat_wild(?ann)) { ret ann_to_monotype(cx, ntt, ann); } + case (ast::pat_lit(_, ?ann)) { ret ann_to_monotype(cx, ntt, ann); } + case (ast::pat_bind(_, _, ?ann)) { + ret ann_to_monotype(cx, ntt, ann); + } + case (ast::pat_tag(_, _, ?ann)) { + ret ann_to_monotype(cx, ntt, ann); + } } fail; // not reached } @@ -1768,17 +1775,18 @@ fn expr_ann(&@ast::expr e) -> ast::ann { // ask for the type of "id" in "id(3)", it will return "fn(&int) -> int" // instead of "fn(&T) -> T with T = int". If this isn't what you want, see // expr_ty_params_and_ty() below. -fn expr_ty(&ctxt cx, &@ast::expr expr) -> t { - ret ann_to_monotype(cx, expr_ann(expr)); +fn expr_ty(&ctxt cx, &node_type_table ntt, &@ast::expr expr) -> t { + ret ann_to_monotype(cx, ntt, expr_ann(expr)); } -fn expr_ty_params_and_ty(&ctxt cx, &@ast::expr expr) -> tup(vec[t], t) { +fn expr_ty_params_and_ty(&ctxt cx, &node_type_table ntt, &@ast::expr expr) + -> tup(vec[t], t) { auto a = expr_ann(expr); - ret tup(ann_to_type_params(a), ann_to_type(a)); + ret tup(ann_to_type_params(ntt, a), ann_to_type(ntt, a)); } -fn expr_has_ty_params(&@ast::expr expr) -> bool { +fn expr_has_ty_params(&node_type_table ntt, &@ast::expr expr) -> bool { // FIXME: Rewrite using complex patterns when they're trustworthy. alt (expr_ann(expr)) { case (ast::ann_none(_)) { fail; } @@ -1789,10 +1797,11 @@ fn expr_has_ty_params(&@ast::expr expr) -> bool { } // FIXME: At the moment this works only for call, bind, and path expressions. -fn replace_expr_type(&@ast::expr expr, +fn replace_expr_type(&node_type_table ntt, + &@ast::expr expr, &tup(vec[t], t) new_tyt) -> @ast::expr { auto new_tps; - if (expr_has_ty_params(expr)) { + if (expr_has_ty_params(ntt, expr)) { new_tps = some[vec[t]](new_tyt._0); } else { new_tps = none[vec[t]]; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index fb7634a2..4c21ee53 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -22,6 +22,7 @@ import middle::ty::method; import middle::ty::mo_val; import middle::ty::mo_alias; import middle::ty::mo_either; +import middle::ty::node_type_table; import middle::ty::pat_ty; import middle::ty::path_to_str; import middle::ty::struct; @@ -69,7 +70,8 @@ type crate_ctxt = rec(session::session sess, unify_cache unify_cache, mutable uint cache_hits, mutable uint cache_misses, - ty::ctxt tcx); + ty::ctxt tcx, + mutable node_type_table node_types); type fn_ctxt = rec(ty::t ret_ty, ast::purity purity, @@ -1119,21 +1121,21 @@ mod Pushdown { alt (pat.node) { case (ast::pat_wild(?ann)) { auto t = Demand::simple(fcx, pat.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); p_1 = ast::pat_wild(ast::ann_type(ast::ann_tag(ann), t, none[vec[ty::t]], none[@ts_ann])); } case (ast::pat_lit(?lit, ?ann)) { auto t = Demand::simple(fcx, pat.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); p_1 = ast::pat_lit(lit, ast::ann_type(ast::ann_tag(ann), t, none[vec[ty::t]], none[@ts_ann])); } case (ast::pat_bind(?id, ?did, ?ann)) { auto t = Demand::simple(fcx, pat.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); fcx.locals.insert(did, t); p_1 = ast::pat_bind(id, did, ast::ann_type(ast::ann_tag(ann), t, @@ -1196,7 +1198,7 @@ mod Pushdown { // TODO: enforce mutability auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); let vec[@ast::expr] es_1 = vec(); alt (struct(fcx.ccx.tcx, t)) { case (ty::ty_vec(?mt)) { @@ -1213,7 +1215,7 @@ mod Pushdown { } case (ast::expr_tup(?es_0, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); let vec[ast::elt] elts_1 = vec(); alt (struct(fcx.ccx.tcx, t)) { case (ty::ty_tup(?mts)) { @@ -1237,7 +1239,7 @@ mod Pushdown { auto base_1 = base_0; auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); let vec[ast::field] fields_1 = vec(); alt (struct(fcx.ccx.tcx, t)) { case (ty::ty_rec(?field_mts)) { @@ -1291,7 +1293,7 @@ mod Pushdown { } case (ast::expr_bind(?sube, ?es, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_bind(sube, es, triv_ann(ann, t)); } case (ast::expr_call(?sube, ?es, ?ann)) { @@ -1300,39 +1302,39 @@ mod Pushdown { // produce a box; things like expr_binary or expr_bind can't, // so there's no need. auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); e_1 = ast::expr_call(sube, es, triv_ann(ann, t)); } case (ast::expr_self_method(?id, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_self_method(id, triv_ann(ann, t)); } case (ast::expr_binary(?bop, ?lhs, ?rhs, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_binary(bop, lhs, rhs, triv_ann(ann, t)); } case (ast::expr_unary(?uop, ?sube, ?ann)) { // See note in expr_unary for why we're calling // Demand::autoderef. auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); e_1 = ast::expr_unary(uop, sube, triv_ann(ann, t)); } case (ast::expr_lit(?lit, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_lit(lit, triv_ann(ann, t)); } case (ast::expr_cast(?sube, ?ast_ty, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_cast(sube, ast_ty, triv_ann(ann, t)); } case (ast::expr_if(?cond, ?then_0, ?else_0, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); auto then_1 = pushdown_block(fcx, expected, then_0); auto else_1; @@ -1347,56 +1349,57 @@ mod Pushdown { } case (ast::expr_for(?decl, ?seq, ?bloc, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_for(decl, seq, bloc, triv_ann(ann, t)); } case (ast::expr_for_each(?decl, ?seq, ?bloc, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_for_each(decl, seq, bloc, triv_ann(ann, t)); } case (ast::expr_while(?cond, ?bloc, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_while(cond, bloc, triv_ann(ann, t)); } case (ast::expr_do_while(?bloc, ?cond, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_do_while(bloc, cond, triv_ann(ann, t)); } case (ast::expr_block(?bloc, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); e_1 = ast::expr_block(bloc, triv_ann(ann, t)); } case (ast::expr_assign(?lhs_0, ?rhs_0, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); auto lhs_1 = pushdown_expr(fcx, expected, lhs_0); auto rhs_1 = pushdown_expr(fcx, expected, rhs_0); e_1 = ast::expr_assign(lhs_1, rhs_1, triv_ann(ann, t)); } case (ast::expr_assign_op(?op, ?lhs_0, ?rhs_0, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); auto lhs_1 = pushdown_expr(fcx, expected, lhs_0); auto rhs_1 = pushdown_expr(fcx, expected, rhs_0); e_1 = ast::expr_assign_op(op, lhs_1, rhs_1, triv_ann(ann, t)); } case (ast::expr_field(?lhs, ?rhs, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); e_1 = ast::expr_field(lhs, rhs, triv_ann(ann, t)); } case (ast::expr_index(?base, ?index, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); e_1 = ast::expr_index(base, index, triv_ann(ann, t)); } case (ast::expr_path(?pth, ?ann)) { - auto tp_substs_0 = ty::ann_to_type_params(ann); - auto t_0 = ann_to_type(ann); + auto tp_substs_0 = ty::ann_to_type_params(fcx.ccx.node_types, + ann); + auto t_0 = ann_to_type(fcx.ccx.node_types, ann); auto result_0 = Demand::full(fcx, e.span, expected, t_0, tp_substs_0, adk); @@ -1430,7 +1433,7 @@ mod Pushdown { } case (ast::expr_ext(?p, ?args, ?body, ?expanded, ?ann)) { auto t = Demand::autoderef(fcx, e.span, expected, - ann_to_type(ann), adk); + ann_to_type(fcx.ccx.node_types, ann), adk); e_1 = ast::expr_ext(p, args, body, expanded, triv_ann(ann, t)); } @@ -1447,13 +1450,13 @@ mod Pushdown { case (ast::expr_port(?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); e_1 = ast::expr_port(triv_ann(ann, t)); } case (ast::expr_chan(?es, ?ann)) { auto t = Demand::simple(fcx, e.span, expected, - ann_to_type(ann)); + ann_to_type(fcx.ccx.node_types, ann)); let @ast::expr es_1; alt (struct(fcx.ccx.tcx, t)) { case (ty::ty_chan(?subty)) { @@ -1474,7 +1477,7 @@ mod Pushdown { for (ast::arm arm_0 in arms_0) { auto block_1 = pushdown_block(fcx, expected, arm_0.block); t = Demand::simple(fcx, e.span, t, - block_ty(fcx.ccx.tcx, block_1)); + block_ty(fcx.ccx.tcx, fcx.ccx.node_types, block_1)); auto arm_1 = rec(pat=arm_0.pat, block=block_1); arms_1 += vec(arm_1); } @@ -1484,7 +1487,7 @@ mod Pushdown { case (ast::expr_recv(?lval_0, ?expr_0, ?ann)) { auto lval_1 = pushdown_expr(fcx, next_ty_var(fcx.ccx), lval_0); - auto t = expr_ty(fcx.ccx.tcx, lval_1); + auto t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, lval_1); auto expr_1 = pushdown_expr(fcx, ty::mk_port(fcx.ccx.tcx, t), expr_0); e_1 = ast::expr_recv(lval_1, expr_1, ann); @@ -1493,7 +1496,7 @@ mod Pushdown { case (ast::expr_send(?lval_0, ?expr_0, ?ann)) { auto expr_1 = pushdown_expr(fcx, next_ty_var(fcx.ccx), expr_0); - auto t = expr_ty(fcx.ccx.tcx, expr_1); + auto t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_1); auto lval_1 = pushdown_expr(fcx, ty::mk_chan(fcx.ccx.tcx, t), lval_0); e_1 = ast::expr_send(lval_1, expr_1, ann); @@ -1575,12 +1578,13 @@ fn resolve_local_types_in_annotation(&option::t[@fn_ctxt] env, &ast::ann ann) ret ann; } case (ast::ann_type(?tg, ?typ, ?tps, ?ts_info)) { - auto tt = ann_to_type(ann); + auto tt = ann_to_type(fcx.ccx.node_types, ann); if (!ty::type_contains_locals(fcx.ccx.tcx, tt)) { ret ann; } auto f = bind resolver(fcx, _); - auto new_type = ty::fold_ty(fcx.ccx.tcx, f, ann_to_type(ann)); + auto new_type = ty::fold_ty(fcx.ccx.tcx, f, + ann_to_type(fcx.ccx.node_types, ann)); ret ast::ann_type(tg, new_type, tps, ts_info); } } @@ -1788,7 +1792,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { args_0 += vec(some[@ast::expr](a_0)); auto arg_ty = rec(mode=mo_either, - ty=expr_ty(fcx.ccx.tcx, a_0)); + ty=expr_ty(fcx.ccx.tcx, + fcx.ccx.node_types, a_0)); _vec::push[arg](arg_tys_0, arg_ty); } case (none[@ast::expr]) { @@ -1802,7 +1807,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto rt_0 = next_ty_var(fcx.ccx); auto t_0; - alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, f_0))) { + alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + f_0))) { case (ty::ty_fn(?proto, _, _)) { t_0 = ty::mk_fn(fcx.ccx.tcx, proto, arg_tys_0, rt_0); } @@ -1816,10 +1822,11 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { } // Unify the callee and arguments. - auto tpt_0 = ty::expr_ty_params_and_ty(fcx.ccx.tcx, f_0); + auto tpt_0 = ty::expr_ty_params_and_ty(fcx.ccx.tcx, + fcx.ccx.node_types, f_0); auto tpt_1 = Demand::full(fcx, f.span, tpt_0._1, t_0, tpt_0._0, NO_AUTODEREF); - auto f_1 = ty::replace_expr_type(f_0, tpt_1); + auto f_1 = ty::replace_expr_type(fcx.ccx.node_types, f_0, tpt_1); ret tup(f_1, args_0); } @@ -1830,14 +1837,15 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { -> tup(@ast::expr, @ast::expr, ast::ann) { auto lhs_0 = check_expr(fcx, lhs); auto rhs_0 = check_expr(fcx, rhs); - auto lhs_t0 = expr_ty(fcx.ccx.tcx, lhs_0); - auto rhs_t0 = expr_ty(fcx.ccx.tcx, rhs_0); + auto lhs_t0 = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, lhs_0); + auto rhs_t0 = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, rhs_0); auto lhs_1 = Pushdown::pushdown_expr(fcx, rhs_t0, lhs_0); - auto rhs_1 = Pushdown::pushdown_expr(fcx, expr_ty(fcx.ccx.tcx, lhs_1), - rhs_0); + auto rhs_1 = Pushdown::pushdown_expr(fcx, + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, lhs_1), rhs_0); - auto ann = triv_ann(a, expr_ty(fcx.ccx.tcx, rhs_1)); + auto ann = triv_ann(a, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + rhs_1)); ret tup(lhs_1, rhs_1, ann); } @@ -1873,16 +1881,16 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_binary(?binop, ?lhs, ?rhs, ?a)) { auto lhs_0 = check_expr(fcx, lhs); auto rhs_0 = check_expr(fcx, rhs); - auto lhs_t0 = expr_ty(fcx.ccx.tcx, lhs_0); - auto rhs_t0 = expr_ty(fcx.ccx.tcx, rhs_0); + auto lhs_t0 = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, lhs_0); + auto rhs_t0 = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, rhs_0); // FIXME: Binops have a bit more subtlety than this. auto lhs_1 = Pushdown::pushdown_expr_full(fcx, rhs_t0, lhs_0, AUTODEREF_OK); auto rhs_1 = Pushdown::pushdown_expr_full(fcx, - expr_ty(fcx.ccx.tcx, lhs_1), - rhs_0, AUTODEREF_OK); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, lhs_1), rhs_0, + AUTODEREF_OK); auto t = strip_boxes(fcx.ccx.tcx, lhs_t0); alt (binop) { @@ -1904,7 +1912,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_unary(?unop, ?oper, ?a)) { auto oper_1 = check_expr(fcx, oper); - auto oper_t = expr_ty(fcx.ccx.tcx, oper_1); + auto oper_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, oper_1); alt (unop) { case (ast::box(?mut)) { oper_t = ty::mk_box(fcx.ccx.tcx, @@ -1958,7 +1966,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_ext(?p, ?args, ?body, ?expanded, ?a)) { auto exp_ = check_expr(fcx, expanded); - auto t = expr_ty(fcx.ccx.tcx, exp_); + auto t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, exp_); auto ann = triv_ann(a, t); ret @fold::respan[ast::expr_](expr.span, ast::expr_ext(p, args, body, exp_, @@ -2052,7 +2060,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_check(?e, ?a)) { auto expr_t = check_expr(fcx, e); Demand::simple(fcx, expr.span, ty::mk_bool(fcx.ccx.tcx), - expr_ty(fcx.ccx.tcx, expr_t)); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_t)); /* e must be a call expr where all arguments are either literals or slots */ alt (e.node) { @@ -2094,10 +2102,10 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_assert(?e, ?a)) { auto expr_t = check_expr(fcx, e); Demand::simple(fcx, expr.span, ty::mk_bool(fcx.ccx.tcx), - expr_ty(fcx.ccx.tcx, expr_t)); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_t)); ret @fold::respan[ast::expr_] (expr.span, ast::expr_assert(expr_t, - plain_ann(a, fcx.ccx.tcx))); + plain_ann(a, fcx.ccx.tcx))); } case (ast::expr_assign(?lhs, ?rhs, ?a)) { @@ -2126,12 +2134,13 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto lhs_0 = check_expr(fcx, lhs); auto rhs_0 = check_expr(fcx, rhs); - auto rhs_t = expr_ty(fcx.ccx.tcx, rhs_0); + auto rhs_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, rhs_0); auto chan_t = ty::mk_chan(fcx.ccx.tcx, rhs_t); auto lhs_1 = Pushdown::pushdown_expr(fcx, chan_t, lhs_0); auto item_t; - alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, lhs_1))) { + alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + lhs_1))) { case (ty::ty_chan(?it)) { item_t = it; } @@ -2151,12 +2160,13 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto lhs_0 = check_expr(fcx, lhs); auto rhs_0 = check_expr(fcx, rhs); - auto lhs_t1 = expr_ty(fcx.ccx.tcx, lhs_0); + auto lhs_t1 = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, lhs_0); auto port_t = ty::mk_port(fcx.ccx.tcx, lhs_t1); auto rhs_1 = Pushdown::pushdown_expr(fcx, port_t, rhs_0); auto item_t; - alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, rhs_0))) { + alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + rhs_0))) { case (ty::ty_port(?it)) { item_t = it; } @@ -2178,7 +2188,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { cond_0); auto thn_0 = check_block(fcx, thn); - auto thn_t = block_ty(fcx.ccx.tcx, thn_0); + auto thn_t = block_ty(fcx.ccx.tcx, fcx.ccx.node_types, thn_0); auto elsopt_1; auto elsopt_t; @@ -2187,7 +2197,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto els_0 = check_expr(fcx, els); auto els_1 = Pushdown::pushdown_expr(fcx, thn_t, els_0); elsopt_1 = some[@ast::expr](els_1); - elsopt_t = expr_ty(fcx.ccx.tcx, els_1); + elsopt_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + els_1); } case (none[@ast::expr]) { elsopt_1 = none[@ast::expr]; @@ -2247,7 +2258,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { cond_0); auto body_1 = check_block(fcx, body); - auto ann = triv_ann(a, block_ty(fcx.ccx.tcx, body_1)); + auto ann = triv_ann(a, block_ty(fcx.ccx.tcx, fcx.ccx.node_types, + body_1)); ret @fold::respan[ast::expr_](expr.span, ast::expr_do_while(body_1, cond_1, ann)); @@ -2258,13 +2270,14 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { // Typecheck the patterns first, so that we get types for all the // bindings. - auto pattern_ty = expr_ty(fcx.ccx.tcx, expr_0); + auto pattern_ty = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + expr_0); let vec[@ast::pat] pats_0 = vec(); for (ast::arm arm in arms) { auto pat_0 = check_pat(fcx, arm.pat); pattern_ty = Demand::simple(fcx, pat_0.span, pattern_ty, - pat_ty(fcx.ccx.tcx, pat_0)); + pat_ty(fcx.ccx.tcx, fcx.ccx.node_types, pat_0)); pats_0 += vec(pat_0); } @@ -2280,7 +2293,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { for (ast::arm arm in arms) { auto block_0 = check_block(fcx, arm.block); result_ty = Demand::simple(fcx, block_0.span, result_ty, - block_ty(fcx.ccx.tcx, block_0)); + block_ty(fcx.ccx.tcx, fcx.ccx.node_types, block_0)); blocks_0 += vec(block_0); } @@ -2308,7 +2321,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto ann; alt (b_0.node.expr) { case (some[@ast::expr](?expr)) { - ann = triv_ann(a, expr_ty(fcx.ccx.tcx, expr)); + ann = triv_ann(a, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + expr)); } case (none[@ast::expr]) { ann = triv_ann(a, ty::mk_nil(fcx.ccx.tcx)); @@ -2325,7 +2339,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto proto_1; let vec[ty::arg] arg_tys_1 = vec(); auto rt_1; - alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, result._0))) { + alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + result._0))) { case (ty::ty_fn(?proto, ?arg_tys, ?rt)) { proto_1 = proto; rt_1 = rt; @@ -2369,7 +2384,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { // Pull the return type out of the type of the function. auto rt_1 = ty::mk_nil(fcx.ccx.tcx); // FIXME: typestate botch - alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, f_1))) { + alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + f_1))) { case (ty::ty_fn(_,_,?rt)) { rt_1 = rt; } case (ty::ty_native_fn(_, _, ?rt)) { rt_1 = rt; } case (_) { @@ -2427,7 +2443,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto args_1 = result._1; // Check the return type - alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, f_1))) { + alt (struct(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + f_1))) { case (ty::ty_fn(_,_,?rt)) { alt (struct(fcx.ccx.tcx, rt)) { case (ty::ty_nil) { @@ -2455,11 +2472,13 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto e_1 = check_expr(fcx, e); auto t_1 = ast_ty_to_ty_crate(fcx.ccx, t); // FIXME: there are more forms of cast to support, eventually. - if (! (type_is_scalar(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, e_1)) && - type_is_scalar(fcx.ccx.tcx, t_1))) { + if (! (type_is_scalar(fcx.ccx.tcx, + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, e_1)) && + type_is_scalar(fcx.ccx.tcx, t_1))) { fcx.ccx.sess.span_err(expr.span, "non-scalar cast: " + - ty_to_str(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, e_1)) + + ty_to_str(fcx.ccx.tcx, + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, e_1)) + " as " + ty_to_str(fcx.ccx.tcx, t_1)); } @@ -2476,12 +2495,13 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { t = next_ty_var(fcx.ccx); } else { auto expr_1 = check_expr(fcx, args.(0)); - t = expr_ty(fcx.ccx.tcx, expr_1); + t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_1); } for (@ast::expr e in args) { auto expr_1 = check_expr(fcx, e); - auto expr_t = expr_ty(fcx.ccx.tcx, expr_1); + auto expr_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + expr_1); Demand::simple(fcx, expr.span, t, expr_t); _vec::push[@ast::expr](args_1,expr_1); } @@ -2498,7 +2518,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { for (ast::elt e in elts) { auto expr_1 = check_expr(fcx, e.expr); - auto expr_t = expr_ty(fcx.ccx.tcx, expr_1); + auto expr_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + expr_1); _vec::push[ast::elt](elts_1, rec(expr=expr_1 with e)); elts_mt += vec(rec(ty=expr_t, mut=e.mut)); } @@ -2523,7 +2544,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { for (ast::field f in fields) { auto expr_1 = check_expr(fcx, f.expr); - auto expr_t = expr_ty(fcx.ccx.tcx, expr_1); + auto expr_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + expr_1); _vec::push[ast::field](fields_1, rec(expr=expr_1 with f)); auto expr_mt = rec(ty=expr_t, mut=f.mut); @@ -2539,7 +2561,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (some[@ast::expr](?bexpr)) { auto bexpr_1 = check_expr(fcx, bexpr); - auto bexpr_t = expr_ty(fcx.ccx.tcx, bexpr_1); + auto bexpr_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, + bexpr_1); let vec[field] base_fields = vec(); @@ -2582,7 +2605,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_field(?base, ?field, ?a)) { auto base_1 = check_expr(fcx, base); auto base_t = strip_boxes(fcx.ccx.tcx, - expr_ty(fcx.ccx.tcx, base_1)); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, base_1)); alt (struct(fcx.ccx.tcx, base_t)) { case (ty::ty_tup(?args)) { let uint ix = ty::field_num(fcx.ccx.sess, @@ -2640,10 +2663,10 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_index(?base, ?idx, ?a)) { auto base_1 = check_expr(fcx, base); auto base_t = strip_boxes(fcx.ccx.tcx, - expr_ty(fcx.ccx.tcx, base_1)); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, base_1)); auto idx_1 = check_expr(fcx, idx); - auto idx_t = expr_ty(fcx.ccx.tcx, idx_1); + auto idx_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, idx_1); alt (struct(fcx.ccx.tcx, base_t)) { case (ty::ty_vec(?mt)) { if (! type_is_integral(fcx.ccx.tcx, idx_t)) { @@ -2690,7 +2713,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { case (ast::expr_chan(?x, ?a)) { auto expr_1 = check_expr(fcx, x); - auto port_t = expr_ty(fcx.ccx.tcx, expr_1); + auto port_t = expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_1); alt (struct(fcx.ccx.tcx, port_t)) { case (ty::ty_port(?subtype)) { auto ct = ty::mk_chan(fcx.ccx.tcx, subtype); @@ -2802,8 +2825,7 @@ fn check_stmt(&@fn_ctxt fcx, &@ast::stmt stmt) -> @ast::stmt { case (ast::stmt_expr(?expr,?a)) { auto expr_t = check_expr(fcx, expr); expr_t = Pushdown::pushdown_expr(fcx, - expr_ty(fcx.ccx.tcx, expr_t), - expr_t); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_t), expr_t); ret @fold::respan(stmt.span, ast::stmt_expr(expr_t, plain_ann(a, fcx.ccx.tcx))); @@ -2825,8 +2847,7 @@ fn check_block(&@fn_ctxt fcx, &ast::block block) -> ast::block { case (some[@ast::expr](?e)) { auto expr_t = check_expr(fcx, e); expr_t = Pushdown::pushdown_expr(fcx, - expr_ty(fcx.ccx.tcx, expr_t), - expr_t); + expr_ty(fcx.ccx.tcx, fcx.ccx.node_types, expr_t), expr_t); expr = some[@ast::expr](expr_t); } } @@ -2840,7 +2861,7 @@ fn check_const(&@crate_ctxt ccx, &span sp, &ast::ident ident, &@ast::ty t, &@ast::expr e, &ast::def_id id, &ast::ann ann) -> @ast::item { // FIXME: this is kinda a kludge; we manufacture a fake "function context" // for checking the initializer expression. - auto rty = ann_to_type(ann); + auto rty = ann_to_type(ccx.node_types, ann); let @fn_ctxt fcx = @rec(ret_ty = rty, purity = ast::pure_fn, locals = @common::new_def_hash[ty::t](), @@ -2862,7 +2883,7 @@ fn check_fn(&@crate_ctxt ccx, &ast::fn_decl decl, ast::proto proto, for (ast::obj_field f in ccx.obj_fields) { - auto field_ty = ty::ann_to_type(f.ann); + auto field_ty = ty::ann_to_type(ccx.node_types, f.ann); local_ty_table.insert(f.id, field_ty); } @@ -2986,7 +3007,9 @@ fn mk_fn_purity_table(&@ast::crate crate) -> @fn_purity_table { ret res; } -type typecheck_result = tup(@ast::crate, ty::type_cache); +// TODO: Remove the third element of this tuple; rely solely on the node type +// table. +type typecheck_result = tup(node_type_table, ty::type_cache, @ast::crate); fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result { auto sess = tcx.sess; @@ -3000,6 +3023,7 @@ fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result { map::mk_hashmap[unify_cache_entry,ty::Unify::result](hasher, eqer); auto fpt = mk_fn_purity_table(crate); // use a variation on Collect + let node_type_table node_types = vec(); auto ccx = @rec(sess=sess, type_cache=result._1, @@ -3011,7 +3035,8 @@ fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result { unify_cache=unify_cache, mutable cache_hits=0u, mutable cache_misses=0u, - tcx=tcx); + tcx=tcx, + mutable node_types=node_types); auto fld = fold::new_identity_fold[@crate_ctxt](); @@ -3025,7 +3050,7 @@ fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result { log #fmt("cache hit rate: %u/%u", ccx.cache_hits, ccx.cache_hits + ccx.cache_misses); - ret tup(crate_1, ccx.type_cache); + ret tup(node_types, ccx.type_cache, crate_1); } // |