提交 7f45ba47 编写于 作者: L Lindsey Kuper

Move inference-related fields/methods from fn_ctxt to infer_ctxt.

上级 251a0a38
......@@ -53,6 +53,7 @@
import middle::ty::{arg, field, node_type_table, mk_nil,
ty_param_bounds_and_ty, lookup_public_fields};
import middle::ty::{ty_vid, region_vid, vid};
import middle::typeck::infer::{ty_and_region_var_methods};
import util::ppaux::{ty_to_str, tys_to_str, region_to_str,
bound_region_to_str, vstore_to_str};
import std::smallintmap;
......@@ -68,6 +69,7 @@
import list::{list, nil, cons};
export check_crate;
export infer;
export method_map;
export method_origin, serialize_method_origin, deserialize_method_origin;
export vtable_map;
......
......@@ -86,8 +86,6 @@
proto: ast::proto,
infcx: infer::infer_ctxt,
locals: hashmap<ast::node_id, ty_vid>,
ty_var_counter: @mut uint,
region_var_counter: @mut uint,
mut blocks: [ast::node_id], // stack of blocks in scope, may be empty
in_scope_regions: isr_alist,
......@@ -181,13 +179,11 @@ fn check_fn(ccx: @crate_ctxt,
// Create the function context. This is either derived from scratch or,
// in the case of function expressions, based on the outer context.
let fcx: @fn_ctxt = {
let {infcx, locals, tvc, rvc, purity,
node_types, node_type_substs} = alt old_fcx {
let {infcx, locals, purity, node_types, node_type_substs} =
alt old_fcx {
none {
{infcx: infer::new_infer_ctxt(tcx),
locals: int_hash(),
tvc: @mut 0u,
rvc: @mut 0u,
purity: decl.purity,
node_types: smallintmap::mk(),
node_type_substs: map::int_hash()}
......@@ -196,8 +192,6 @@ fn check_fn(ccx: @crate_ctxt,
assert decl.purity == ast::impure_fn;
{infcx: fcx.infcx,
locals: fcx.locals,
tvc: fcx.ty_var_counter,
rvc: fcx.region_var_counter,
purity: fcx.purity,
node_types: fcx.node_types,
node_type_substs: fcx.node_type_substs}
......@@ -219,8 +213,6 @@ fn check_fn(ccx: @crate_ctxt,
proto: proto,
infcx: infcx,
locals: locals,
ty_var_counter: tvc,
region_var_counter: rvc,
mut blocks: [],
in_scope_regions: isr,
node_types: node_types,
......@@ -265,7 +257,7 @@ fn gather_locals(fcx: @fn_ctxt,
let tcx = fcx.ccx.tcx;
let assign = fn@(nid: ast::node_id, ty_opt: option<ty::t>) {
let var_id = fcx.next_ty_var_id();
let var_id = fcx.infcx.next_ty_var_id();
fcx.locals.insert(nid, var_id);
alt ty_opt {
none {/* nothing to do */ }
......@@ -429,13 +421,13 @@ fn get_item_ty(id: ast::def_id) -> ty::ty_param_bounds_and_ty {
}
fn ty_infer(_span: span) -> ty::t {
self.next_ty_var()
self.infcx.next_ty_var()
}
}
impl of region_scope for @fn_ctxt {
fn anon_region() -> result<ty::region, str> {
result::ok(self.next_region_var())
result::ok(self.infcx.next_region_var())
}
fn named_region(id: str) -> result<ty::region, str> {
empty_rscope.named_region(id).chain_err { |_e|
......@@ -522,25 +514,6 @@ fn node_ty_substs(id: ast::node_id) -> ty::substs {
fn opt_node_ty_substs(id: ast::node_id) -> option<ty::substs> {
self.node_type_substs.find(id)
}
fn next_ty_var_id() -> ty_vid {
let id = *self.ty_var_counter;
*self.ty_var_counter += 1u;
ret ty_vid(id);
}
fn next_ty_var() -> ty::t {
ty::mk_var(self.ccx.tcx, self.next_ty_var_id())
}
fn next_ty_vars(n: uint) -> [ty::t] {
vec::from_fn(n) {|_i| self.next_ty_var() }
}
fn next_region_var_id() -> region_vid {
let id = *self.region_var_counter;
*self.region_var_counter += 1u;
ret region_vid(id);
}
fn next_region_var() -> ty::region {
ret ty::re_var(self.next_region_var_id());
}
fn report_mismatched_types(sp: span, e: ty::t, a: ty::t,
err: ty::type_err) {
......@@ -691,7 +664,7 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
rp: rp,
raw_ty: ty::mk_class(tcx, local_def(class_id),
{self_r: alt rp {
ast::rp_self { some(fcx.next_region_var()) }
ast::rp_self { some(fcx.infcx.next_region_var()) }
ast::rp_none { none }},
self_ty: none,
tps: ty::ty_params_to_tys(tcx, ts)})}
......@@ -708,9 +681,9 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
let self_r = alt rp {
ast::rp_none { none }
ast::rp_self { some(fcx.next_region_var()) }
ast::rp_self { some(fcx.infcx.next_region_var()) }
};
let tps = fcx.next_ty_vars(n_tps);
let tps = fcx.infcx.next_ty_vars(n_tps);
let substs = {self_r: self_r, self_ty: none, tps: tps};
let substd_ty = ty::subst(tcx, substs, raw_ty);
......@@ -772,7 +745,7 @@ fn check_call_or_bind(
} else {
"s were"
}]);
fcx.next_ty_vars(supplied_arg_count)
fcx.infcx.next_ty_vars(supplied_arg_count)
}
}
......@@ -875,7 +848,7 @@ fn check_then_else(fcx: @fn_ctxt, thn: ast::blk,
let (if_t, if_bot) =
alt elsopt {
some(els) {
let if_t = fcx.next_ty_var();
let if_t = fcx.infcx.next_ty_var();
let thn_bot = check_block(fcx, thn);
let thn_t = fcx.node_ty(thn.node.id);
demand::suptype(fcx, thn.span, if_t, thn_t);
......@@ -938,7 +911,7 @@ fn check_binop(fcx: @fn_ctxt, expr: @ast::expr,
// result [ML T] where TL <: T and TR <: T. In other words, the
// result type is (generally) the LUB of (TL, TR) and takes the
// mutability from the LHS.
let t_var = fcx.next_ty_var();
let t_var = fcx.infcx.next_ty_var();
let const_vec_t = ty::mk_vec(tcx, {ty: t_var,
mutbl: ast::m_const});
demand::suptype(fcx, lhs.span, const_vec_t, lhs_t);
......@@ -960,7 +933,7 @@ fn check_binop(fcx: @fn_ctxt, expr: @ast::expr,
}
(_, _) if ty::is_binopable(tcx, lhs_t, op) {
let tvar = fcx.next_ty_var();
let tvar = fcx.infcx.next_ty_var();
demand::suptype(fcx, expr.span, tvar, lhs_t);
let rhs_bot = check_expr_with(fcx, rhs, tvar);
let rhs_t = alt op {
......@@ -1087,7 +1060,7 @@ fn check_expr_fn(fcx: @fn_ctxt,
}
ast::expr_vec(args, mutbl) {
let tt = ast_expr_vstore_to_vstore(fcx, ev, vec::len(args), vst);
let t: ty::t = fcx.next_ty_var();
let t: ty::t = fcx.infcx.next_ty_var();
for args.each {|e| bot |= check_expr_with(fcx, e, t); }
ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt)
}
......@@ -1117,7 +1090,7 @@ fn check_expr_fn(fcx: @fn_ctxt,
ast::expr_binary(ast::gt, lhs, rhs) |
ast::expr_binary(ast::ge, lhs, rhs) {
let tcx = fcx.ccx.tcx;
let tvar = fcx.next_ty_var();
let tvar = fcx.infcx.next_ty_var();
bot |= check_expr_with(fcx, lhs, tvar);
bot |= check_expr_with(fcx, rhs, tvar);
fcx.write_ty(id, ty::mk_bool(tcx));
......@@ -1463,7 +1436,7 @@ fn check_expr_fn(fcx: @fn_ctxt,
fcx.write_ty(id, t_1);
}
ast::expr_vec(args, mutbl) {
let t: ty::t = fcx.next_ty_var();
let t: ty::t = fcx.infcx.next_ty_var();
for args.each {|e| bot |= check_expr_with(fcx, e, t); }
let typ = ty::mk_vec(tcx, {ty: t, mutbl: mutbl});
fcx.write_ty(id, typ);
......@@ -1608,7 +1581,7 @@ fn get_node(f: spanned<field>) -> field { f.node }
field, ty_to_str(tcx, t_err)];
tcx.sess.span_err(expr.span, msg);
// NB: Adding a bogus type to allow typechecking to continue
fcx.write_ty(id, fcx.next_ty_var());
fcx.write_ty(id, fcx.infcx.next_ty_var());
}
}
}
......@@ -1836,8 +1809,6 @@ fn check_const(ccx: @crate_ctxt, _sp: span, e: @ast::expr, id: ast::node_id) {
proto: ast::proto_box,
infcx: infer::new_infer_ctxt(ccx.tcx),
locals: int_hash(),
ty_var_counter: @mut 0u,
region_var_counter: @mut 0u,
mut blocks: [],
in_scope_regions: @nil,
node_types: smallintmap::mk(),
......@@ -1878,8 +1849,6 @@ fn check_enum_variants(ccx: @crate_ctxt,
proto: ast::proto_box,
infcx: infer::new_infer_ctxt(ccx.tcx),
locals: int_hash(),
ty_var_counter: @mut 0u,
region_var_counter: @mut 0u,
mut blocks: [],
in_scope_regions: @nil,
node_types: smallintmap::mk(),
......@@ -2148,24 +2117,24 @@ fn instantiate_path(fcx: @fn_ctxt,
// For now, there is no way to explicitly specify the region bound.
// This will have to change eventually.
let self_r = alt tpt.rp {
ast::rp_self { some(fcx.next_region_var()) }
ast::rp_self { some(fcx.infcx.next_region_var()) }
ast::rp_none { none }
};
let tps = if ty_substs_len == 0u {
fcx.next_ty_vars(ty_param_count)
fcx.infcx.next_ty_vars(ty_param_count)
} else if ty_param_count == 0u {
fcx.ccx.tcx.sess.span_err
(sp, "this item does not take type parameters");
fcx.next_ty_vars(ty_param_count)
fcx.infcx.next_ty_vars(ty_param_count)
} else if ty_substs_len > ty_param_count {
fcx.ccx.tcx.sess.span_err
(sp, "too many type parameters provided for this item");
fcx.next_ty_vars(ty_param_count)
fcx.infcx.next_ty_vars(ty_param_count)
} else if ty_substs_len < ty_param_count {
fcx.ccx.tcx.sess.span_err
(sp, "not enough type parameters provided for this item");
fcx.next_ty_vars(ty_param_count)
fcx.infcx.next_ty_vars(ty_param_count)
} else {
pth.types.map { |aty| fcx.to_ty(aty) }
};
......
import middle::typeck::infer::{ty_and_region_var_methods};
fn check_alt(fcx: @fn_ctxt,
expr: @ast::expr,
discrim: @ast::expr,
......@@ -5,7 +7,7 @@ fn check_alt(fcx: @fn_ctxt,
let tcx = fcx.ccx.tcx;
let mut bot = false;
let pattern_ty = fcx.next_ty_var();
let pattern_ty = fcx.infcx.next_ty_var();
bot = check_expr_with(fcx, discrim, pattern_ty);
// Typecheck the patterns first, so that we get types for all the
......@@ -22,7 +24,7 @@ fn check_alt(fcx: @fn_ctxt,
for arm.pats.each {|p| check_pat(pcx, p, pattern_ty);}
}
// Now typecheck the blocks.
let mut result_ty = fcx.next_ty_var();
let mut result_ty = fcx.infcx.next_ty_var();
let mut arm_non_bot = false;
for arms.each {|arm|
alt arm.guard {
......
/* Code to handle method lookups (which can be quite complex) */
import regionmanip::universally_quantify_regions;
import middle::typeck::infer::{ty_and_region_var_methods};
enum lookup = {
fcx: @fn_ctxt,
......@@ -266,18 +267,18 @@ fn write_mty_from_fty(self_substs: ty::substs,
let n_tps_supplied = self.supplied_tps.len();
let m_substs = {
if n_tps_supplied == 0u {
self.fcx.next_ty_vars(n_tps_m)
self.fcx.infcx.next_ty_vars(n_tps_m)
} else if n_tps_m == 0u {
tcx.sess.span_err(
self.expr.span,
"this method does not take type parameters");
self.fcx.next_ty_vars(n_tps_m)
self.fcx.infcx.next_ty_vars(n_tps_m)
} else if n_tps_supplied != n_tps_m {
tcx.sess.span_err(
self.expr.span,
"incorrect number of type \
parameters given for this method");
self.fcx.next_ty_vars(n_tps_m)
self.fcx.infcx.next_ty_vars(n_tps_m)
} else {
self.supplied_tps
}
......
import middle::typeck::infer::{ty_and_region_var_methods};
// Helper functions related to manipulating region types.
// Helper for the other universally_quantify_*() routines. Extracts the bound
......@@ -13,7 +15,7 @@ fn universally_quantify_from_sty(fcx: @fn_ctxt,
indent {||
let tcx = fcx.tcx();
let isr = collect_bound_regions_in_tys(tcx, @nil, bound_tys) { |br|
let rvar = fcx.next_region_var();
let rvar = fcx.infcx.next_region_var();
#debug["Bound region %s maps to %s",
bound_region_to_str(fcx.ccx.tcx, br),
region_to_str(fcx.ccx.tcx, rvar)];
......
......@@ -165,6 +165,7 @@ fn bar() {
export resolve_shallow;
export resolve_deep;
export resolve_deep_var;
export ty_and_region_var_methods;
export compare_tys;
export fixup_err, fixup_err_to_str;
......@@ -195,6 +196,10 @@ enum infer_ctxt = @{
tcx: ty::ctxt,
vb: vals_and_bindings<ty::ty_vid, ty::t>,
rb: vals_and_bindings<ty::region_vid, ty::region>,
// For keeping track of existing type/region variables.
ty_var_counter: @mut uint,
region_var_counter: @mut uint,
};
enum fixup_err {
......@@ -219,8 +224,9 @@ fn fixup_err_to_str(f: fixup_err) -> str {
fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
infer_ctxt(@{tcx: tcx,
vb: {vals: smallintmap::mk(), mut bindings: []},
rb: {vals: smallintmap::mk(), mut bindings: []}})
}
rb: {vals: smallintmap::mk(), mut bindings: []},
ty_var_counter: @mut 0u,
region_var_counter: @mut 0u})}
fn mk_subty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
#debug["mk_subty(%s <: %s)", a.to_str(cx), b.to_str(cx)];
......@@ -423,6 +429,32 @@ fn rollback_to<V:copy vid, T:copy>(
}
}
impl ty_and_region_var_methods for infer_ctxt {
fn next_ty_var_id() -> ty_vid {
let id = *self.ty_var_counter;
*self.ty_var_counter += 1u;
ret ty_vid(id);
}
fn next_ty_var() -> ty::t {
ty::mk_var(self.tcx, self.next_ty_var_id())
}
fn next_ty_vars(n: uint) -> [ty::t] {
vec::from_fn(n) {|_i| self.next_ty_var() }
}
fn next_region_var_id() -> region_vid {
let id = *self.region_var_counter;
*self.region_var_counter += 1u;
ret region_vid(id);
}
fn next_region_var() -> ty::region {
ret ty::re_var(self.next_region_var_id());
}
}
impl unify_methods for infer_ctxt {
fn set<V:copy vid, T:copy to_str>(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册