mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 06:47:34 +00:00
Move inference-related fields/methods from fn_ctxt to infer_ctxt.
This commit is contained in:
parent
251a0a38d7
commit
7f45ba4744
@ -53,6 +53,7 @@ import middle::ty;
|
||||
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 std::list;
|
||||
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 @@ type fn_ctxt =
|
||||
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 check_fn(ccx: @crate_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 @@ impl of ast_conv for @fn_ctxt {
|
||||
}
|
||||
|
||||
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 @@ impl methods for @fn_ctxt {
|
||||
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_expr_with_unifier(fcx: @fn_ctxt,
|
||||
} else {
|
||||
"s were"
|
||||
}]);
|
||||
fcx.next_ty_vars(supplied_arg_count)
|
||||
fcx.infcx.next_ty_vars(supplied_arg_count)
|
||||
}
|
||||
}
|
||||
|
||||
@ -875,7 +848,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
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_expr_with_unifier(fcx: @fn_ctxt,
|
||||
// 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_expr_with_unifier(fcx: @fn_ctxt,
|
||||
}
|
||||
|
||||
(_, _) 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_with_unifier(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_with_unifier(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_with_unifier(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 check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
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) }
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
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 {
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* 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 @@ impl methods for lookup {
|
||||
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
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
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 @@ export mk_assignty;
|
||||
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 @@ type fres<T> = result::result<T, fixup_err>;
|
||||
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 @@ impl methods for infer_ctxt {
|
||||
}
|
||||
}
|
||||
|
||||
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>(
|
||||
|
Loading…
Reference in New Issue
Block a user