From 7f45ba4744cec88bfac0b1672b13409aa5ebb42f Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Thu, 17 May 2012 11:07:24 -0700 Subject: [PATCH] Move inference-related fields/methods from fn_ctxt to infer_ctxt. --- src/rustc/middle/typeck.rs | 2 + src/rustc/middle/typeck/check.rs | 73 ++++++-------------- src/rustc/middle/typeck/check/alt.rs | 6 +- src/rustc/middle/typeck/check/method.rs | 7 +- src/rustc/middle/typeck/check/regionmanip.rs | 4 +- src/rustc/middle/typeck/infer.rs | 36 +++++++++- 6 files changed, 68 insertions(+), 60 deletions(-) diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index b8f0eb4152a..a1b16471b1d 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -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; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 02e0f48012c..069fc7fab7d 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -86,8 +86,6 @@ type fn_ctxt = proto: ast::proto, infcx: infer::infer_ctxt, locals: hashmap, - 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) { - 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 { - result::ok(self.next_region_var()) + result::ok(self.infcx.next_region_var()) } fn named_region(id: str) -> result { 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 { 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) } }; diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs index ef9c574ccd2..dc43214d669 100644 --- a/src/rustc/middle/typeck/check/alt.rs +++ b/src/rustc/middle/typeck/check/alt.rs @@ -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 { diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index 18ea67e2ad4..27bbe5f9167 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -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 } diff --git a/src/rustc/middle/typeck/check/regionmanip.rs b/src/rustc/middle/typeck/check/regionmanip.rs index 7fb4409d970..8f8472ec5b4 100644 --- a/src/rustc/middle/typeck/check/regionmanip.rs +++ b/src/rustc/middle/typeck/check/regionmanip.rs @@ -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)]; diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs index dc37dfc56c8..c9fbad28bbd 100644 --- a/src/rustc/middle/typeck/infer.rs +++ b/src/rustc/middle/typeck/infer.rs @@ -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, rb: vals_and_bindings, + + // 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 = result::result; 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(