Part of #7081: Fold remainder of typeck's visit env into their visitor structs.

This commit is contained in:
Felix S. Klock II 2013-09-24 14:34:51 +02:00
parent 4f691cd5bc
commit 0e95c3434b
4 changed files with 101 additions and 111 deletions

View File

@ -37,12 +37,12 @@ pub fn check_match(fcx: @mut FnCtxt,
// Typecheck the patterns first, so that we get types for all the // Typecheck the patterns first, so that we get types for all the
// bindings. // bindings.
for arm in arms.iter() { for arm in arms.iter() {
let pcx = pat_ctxt { let mut pcx = pat_ctxt {
fcx: fcx, fcx: fcx,
map: pat_id_map(tcx.def_map, arm.pats[0]), map: pat_id_map(tcx.def_map, arm.pats[0]),
}; };
for p in arm.pats.iter() { check_pat(&pcx, *p, discrim_ty);} for p in arm.pats.iter() { check_pat(&mut pcx, *p, discrim_ty);}
} }
// The result of the match is the common supertype of all the // The result of the match is the common supertype of all the

View File

@ -122,12 +122,13 @@ impl Rcx {
} }
/// Try to resolve the type for the given node. /// Try to resolve the type for the given node.
pub fn resolve_node_type(@mut self, id: ast::NodeId) -> ty::t { pub fn resolve_node_type(&mut self, id: ast::NodeId) -> ty::t {
self.resolve_type(self.fcx.node_ty(id)) let t = self.fcx.node_ty(id);
self.resolve_type(t)
} }
/// Try to resolve the type for the given node. /// Try to resolve the type for the given node.
pub fn resolve_expr_type_adjusted(@mut self, expr: @ast::Expr) -> ty::t { pub fn resolve_expr_type_adjusted(&mut self, expr: @ast::Expr) -> ty::t {
let ty_unadjusted = self.resolve_node_type(expr.id); let ty_unadjusted = self.resolve_node_type(expr.id);
if ty::type_is_error(ty_unadjusted) || ty::type_is_bot(ty_unadjusted) { if ty::type_is_error(ty_unadjusted) || ty::type_is_bot(ty_unadjusted) {
ty_unadjusted ty_unadjusted
@ -141,30 +142,28 @@ impl Rcx {
} }
pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::Expr) { pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::Expr) {
let rcx = @mut Rcx { fcx: fcx, errors_reported: 0, let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
repeating_scope: e.id }; repeating_scope: e.id };
let rcx = &mut rcx;
if fcx.err_count_since_creation() == 0 { if fcx.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded // regionck assumes typeck succeeded
let mut v = regionck_visitor(); rcx.visit_expr(e, ());
v.visit_expr(e, rcx);
} }
fcx.infcx().resolve_regions(); fcx.infcx().resolve_regions();
} }
pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::Block) { pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::Block) {
let rcx = @mut Rcx { fcx: fcx, errors_reported: 0, let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
repeating_scope: blk.id }; repeating_scope: blk.id };
let rcx = &mut rcx;
if fcx.err_count_since_creation() == 0 { if fcx.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded // regionck assumes typeck succeeded
let mut v = regionck_visitor(); rcx.visit_block(blk, ());
v.visit_block(blk, rcx);
} }
fcx.infcx().resolve_regions(); fcx.infcx().resolve_regions();
} }
struct RegionckVisitor; impl Visitor<()> for Rcx {
impl Visitor<@mut Rcx> for RegionckVisitor {
// (*) FIXME(#3238) should use visit_pat, not visit_arm/visit_local, // (*) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
// However, right now we run into an issue whereby some free // However, right now we run into an issue whereby some free
// regions are not properly related if they appear within the // regions are not properly related if they appear within the
@ -173,48 +172,44 @@ impl Visitor<@mut Rcx> for RegionckVisitor {
// hierarchy, and in particular the relationships between free // hierarchy, and in particular the relationships between free
// regions, until regionck, as described in #3238. // regions, until regionck, as described in #3238.
fn visit_item(&mut self, i:@ast::item, e:@mut Rcx) { visit_item(self, i, e); } fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(self, i); }
fn visit_expr(&mut self, ex:@ast::Expr, e:@mut Rcx) { visit_expr(self, ex, e); } fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(self, ex); }
//visit_pat: visit_pat, // (*) see above //visit_pat: visit_pat, // (*) see above
fn visit_arm(&mut self, a:&ast::Arm, e:@mut Rcx) { visit_arm(self, a, e); } fn visit_arm(&mut self, a:&ast::Arm, _:()) { visit_arm(self, a); }
fn visit_local(&mut self, l:@ast::Local, e:@mut Rcx) { visit_local(self, l, e); } fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(self, l); }
fn visit_block(&mut self, b:&ast::Block, e:@mut Rcx) { visit_block(self, b, e); } fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(self, b); }
} }
fn regionck_visitor() -> RegionckVisitor { fn visit_item(_rcx: &mut Rcx, _item: @ast::item) {
RegionckVisitor
}
fn visit_item(_v: &mut RegionckVisitor, _item: @ast::item, _rcx: @mut Rcx) {
// Ignore items // Ignore items
} }
fn visit_block(v: &mut RegionckVisitor, b: &ast::Block, rcx: @mut Rcx) { fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id); rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id);
visit::walk_block(v, b, rcx); visit::walk_block(rcx, b, ());
} }
fn visit_arm(v: &mut RegionckVisitor, arm: &ast::Arm, rcx: @mut Rcx) { fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
// see above // see above
for &p in arm.pats.iter() { for &p in arm.pats.iter() {
constrain_bindings_in_pat(p, rcx); constrain_bindings_in_pat(p, rcx);
} }
visit::walk_arm(v, arm, rcx); visit::walk_arm(rcx, arm, ());
} }
fn visit_local(v: &mut RegionckVisitor, l: @ast::Local, rcx: @mut Rcx) { fn visit_local(rcx: &mut Rcx, l: @ast::Local) {
// see above // see above
constrain_bindings_in_pat(l.pat, rcx); constrain_bindings_in_pat(l.pat, rcx);
visit::walk_local(v, l, rcx); visit::walk_local(rcx, l, ());
} }
fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: @mut Rcx) { fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: &mut Rcx) {
let tcx = rcx.fcx.tcx(); let tcx = rcx.fcx.tcx();
debug!("regionck::visit_pat(pat=%s)", pat.repr(tcx)); debug!("regionck::visit_pat(pat=%s)", pat.repr(tcx));
do pat_util::pat_bindings(tcx.def_map, pat) |_, id, span, _| { do pat_util::pat_bindings(tcx.def_map, pat) |_, id, span, _| {
@ -248,7 +243,7 @@ fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: @mut Rcx) {
} }
} }
fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) { fn visit_expr(rcx: &mut Rcx, expr: @ast::Expr) {
debug!("regionck::visit_expr(e=%s, repeating_scope=%?)", debug!("regionck::visit_expr(e=%s, repeating_scope=%?)",
expr.repr(rcx.fcx.tcx()), rcx.repeating_scope); expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
@ -336,13 +331,13 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
constrain_callee(rcx, callee.id, expr, callee); constrain_callee(rcx, callee.id, expr, callee);
constrain_call(rcx, callee.id, expr, None, *args, false); constrain_call(rcx, callee.id, expr, None, *args, false);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprMethodCall(callee_id, arg0, _, _, ref args, _) => { ast::ExprMethodCall(callee_id, arg0, _, _, ref args, _) => {
constrain_call(rcx, callee_id, expr, Some(arg0), *args, false); constrain_call(rcx, callee_id, expr, Some(arg0), *args, false);
visit::walk_expr(v,expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprIndex(callee_id, lhs, rhs) | ast::ExprIndex(callee_id, lhs, rhs) |
@ -354,14 +349,14 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
// should be converted to an adjustment! // should be converted to an adjustment!
constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true); constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprUnary(callee_id, _, lhs) if has_method_map => { ast::ExprUnary(callee_id, _, lhs) if has_method_map => {
// As above. // As above.
constrain_call(rcx, callee_id, expr, Some(lhs), [], true); constrain_call(rcx, callee_id, expr, Some(lhs), [], true);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprUnary(_, ast::UnDeref, base) => { ast::ExprUnary(_, ast::UnDeref, base) => {
@ -369,7 +364,7 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
let base_ty = rcx.resolve_node_type(base.id); let base_ty = rcx.resolve_node_type(base.id);
constrain_derefs(rcx, expr, 1, base_ty); constrain_derefs(rcx, expr, 1, base_ty);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprIndex(_, vec_expr, _) => { ast::ExprIndex(_, vec_expr, _) => {
@ -377,7 +372,7 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
let vec_type = rcx.resolve_expr_type_adjusted(vec_expr); let vec_type = rcx.resolve_expr_type_adjusted(vec_expr);
constrain_index(rcx, expr, vec_type); constrain_index(rcx, expr, vec_type);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprCast(source, _) => { ast::ExprCast(source, _) => {
@ -407,7 +402,7 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
_ => () _ => ()
} }
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprAddrOf(_, base) => { ast::ExprAddrOf(_, base) => {
@ -423,44 +418,43 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
let ty0 = rcx.resolve_node_type(expr.id); let ty0 = rcx.resolve_node_type(expr.id);
constrain_regions_in_type(rcx, ty::re_scope(expr.id), constrain_regions_in_type(rcx, ty::re_scope(expr.id),
infer::AddrOf(expr.span), ty0); infer::AddrOf(expr.span), ty0);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprMatch(discr, ref arms) => { ast::ExprMatch(discr, ref arms) => {
guarantor::for_match(rcx, discr, *arms); guarantor::for_match(rcx, discr, *arms);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
ast::ExprFnBlock(*) => { ast::ExprFnBlock(*) => {
check_expr_fn_block(rcx, expr, v); check_expr_fn_block(rcx, expr);
} }
ast::ExprLoop(ref body, _) => { ast::ExprLoop(ref body, _) => {
let repeating_scope = rcx.set_repeating_scope(body.id); let repeating_scope = rcx.set_repeating_scope(body.id);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
ast::ExprWhile(cond, ref body) => { ast::ExprWhile(cond, ref body) => {
let repeating_scope = rcx.set_repeating_scope(cond.id); let repeating_scope = rcx.set_repeating_scope(cond.id);
v.visit_expr(cond, rcx); rcx.visit_expr(cond, ());
rcx.set_repeating_scope(body.id); rcx.set_repeating_scope(body.id);
v.visit_block(body, rcx); rcx.visit_block(body, ());
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
_ => { _ => {
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
} }
} }
} }
fn check_expr_fn_block(rcx: @mut Rcx, fn check_expr_fn_block(rcx: &mut Rcx,
expr: @ast::Expr, expr: @ast::Expr) {
v: &mut RegionckVisitor) {
let tcx = rcx.fcx.tcx(); let tcx = rcx.fcx.tcx();
match expr.node { match expr.node {
ast::ExprFnBlock(_, ref body) => { ast::ExprFnBlock(_, ref body) => {
@ -489,7 +483,7 @@ fn check_expr_fn_block(rcx: @mut Rcx,
} }
let repeating_scope = rcx.set_repeating_scope(body.id); let repeating_scope = rcx.set_repeating_scope(body.id);
visit::walk_expr(v, expr, rcx); visit::walk_expr(rcx, expr, ());
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
@ -501,7 +495,7 @@ fn check_expr_fn_block(rcx: @mut Rcx,
} }
} }
fn constrain_callee(rcx: @mut Rcx, fn constrain_callee(rcx: &mut Rcx,
callee_id: ast::NodeId, callee_id: ast::NodeId,
call_expr: @ast::Expr, call_expr: @ast::Expr,
callee_expr: @ast::Expr) callee_expr: @ast::Expr)
@ -526,7 +520,7 @@ fn constrain_callee(rcx: @mut Rcx,
} }
} }
fn constrain_call(rcx: @mut Rcx, fn constrain_call(rcx: &mut Rcx,
// might be expr_call, expr_method_call, or an overloaded // might be expr_call, expr_method_call, or an overloaded
// operator // operator
callee_id: ast::NodeId, callee_id: ast::NodeId,
@ -589,7 +583,7 @@ fn constrain_call(rcx: @mut Rcx,
fn_sig.output); fn_sig.output);
} }
fn constrain_derefs(rcx: @mut Rcx, fn constrain_derefs(rcx: &mut Rcx,
deref_expr: @ast::Expr, deref_expr: @ast::Expr,
derefs: uint, derefs: uint,
mut derefd_ty: ty::t) mut derefd_ty: ty::t)
@ -625,7 +619,7 @@ fn constrain_derefs(rcx: @mut Rcx,
} }
} }
pub fn mk_subregion_due_to_derefence(rcx: @mut Rcx, pub fn mk_subregion_due_to_derefence(rcx: &mut Rcx,
deref_span: Span, deref_span: Span,
minimum_lifetime: ty::Region, minimum_lifetime: ty::Region,
maximum_lifetime: ty::Region) { maximum_lifetime: ty::Region) {
@ -634,7 +628,7 @@ pub fn mk_subregion_due_to_derefence(rcx: @mut Rcx,
} }
fn constrain_index(rcx: @mut Rcx, fn constrain_index(rcx: &mut Rcx,
index_expr: @ast::Expr, index_expr: @ast::Expr,
indexed_ty: ty::t) indexed_ty: ty::t)
{ {
@ -659,7 +653,7 @@ fn constrain_index(rcx: @mut Rcx,
} }
} }
fn constrain_free_variables(rcx: @mut Rcx, fn constrain_free_variables(rcx: &mut Rcx,
region: ty::Region, region: ty::Region,
expr: @ast::Expr) { expr: @ast::Expr) {
/*! /*!
@ -681,7 +675,7 @@ fn constrain_free_variables(rcx: @mut Rcx,
} }
fn constrain_regions_in_type_of_node( fn constrain_regions_in_type_of_node(
rcx: @mut Rcx, rcx: &mut Rcx,
id: ast::NodeId, id: ast::NodeId,
minimum_lifetime: ty::Region, minimum_lifetime: ty::Region,
origin: infer::SubregionOrigin) -> bool origin: infer::SubregionOrigin) -> bool
@ -706,7 +700,7 @@ fn constrain_regions_in_type_of_node(
} }
fn constrain_regions_in_type( fn constrain_regions_in_type(
rcx: @mut Rcx, rcx: &mut Rcx,
minimum_lifetime: ty::Region, minimum_lifetime: ty::Region,
origin: infer::SubregionOrigin, origin: infer::SubregionOrigin,
ty: ty::t) -> bool ty: ty::t) -> bool
@ -812,7 +806,7 @@ pub mod guarantor {
use syntax::codemap::Span; use syntax::codemap::Span;
use util::ppaux::{ty_to_str}; use util::ppaux::{ty_to_str};
pub fn for_addr_of(rcx: @mut Rcx, expr: @ast::Expr, base: @ast::Expr) { pub fn for_addr_of(rcx: &mut Rcx, expr: @ast::Expr, base: @ast::Expr) {
/*! /*!
* Computes the guarantor for an expression `&base` and then * Computes the guarantor for an expression `&base` and then
* ensures that the lifetime of the resulting pointer is linked * ensures that the lifetime of the resulting pointer is linked
@ -825,7 +819,7 @@ pub mod guarantor {
link(rcx, expr.span, expr.id, guarantor); link(rcx, expr.span, expr.id, guarantor);
} }
pub fn for_match(rcx: @mut Rcx, discr: @ast::Expr, arms: &[ast::Arm]) { pub fn for_match(rcx: &mut Rcx, discr: @ast::Expr, arms: &[ast::Arm]) {
/*! /*!
* Computes the guarantors for any ref bindings in a match and * Computes the guarantors for any ref bindings in a match and
* then ensures that the lifetime of the resulting pointer is * then ensures that the lifetime of the resulting pointer is
@ -842,7 +836,7 @@ pub mod guarantor {
} }
} }
pub fn for_autoref(rcx: @mut Rcx, pub fn for_autoref(rcx: &mut Rcx,
expr: @ast::Expr, expr: @ast::Expr,
autoderefs: uint, autoderefs: uint,
autoref: &ty::AutoRef) { autoref: &ty::AutoRef) {
@ -882,7 +876,7 @@ pub mod guarantor {
} }
fn maybe_make_subregion( fn maybe_make_subregion(
rcx: @mut Rcx, rcx: &mut Rcx,
expr: @ast::Expr, expr: @ast::Expr,
sub_region: ty::Region, sub_region: ty::Region,
sup_region: Option<ty::Region>) sup_region: Option<ty::Region>)
@ -894,7 +888,7 @@ pub mod guarantor {
} }
} }
pub fn for_by_ref(rcx: @mut Rcx, pub fn for_by_ref(rcx: &mut Rcx,
expr: @ast::Expr, expr: @ast::Expr,
callee_scope: ast::NodeId) { callee_scope: ast::NodeId) {
/*! /*!
@ -917,7 +911,7 @@ pub mod guarantor {
} }
fn link( fn link(
rcx: @mut Rcx, rcx: &mut Rcx,
span: Span, span: Span,
id: ast::NodeId, id: ast::NodeId,
guarantor: Option<ty::Region>) { guarantor: Option<ty::Region>) {
@ -974,7 +968,7 @@ pub mod guarantor {
ty: ty::t ty: ty::t
} }
fn guarantor(rcx: @mut Rcx, expr: @ast::Expr) -> Option<ty::Region> { fn guarantor(rcx: &mut Rcx, expr: @ast::Expr) -> Option<ty::Region> {
/*! /*!
* *
* Computes the guarantor of `expr`, or None if `expr` is * Computes the guarantor of `expr`, or None if `expr` is
@ -1045,7 +1039,7 @@ pub mod guarantor {
} }
} }
fn categorize(rcx: @mut Rcx, expr: @ast::Expr) -> ExprCategorization { fn categorize(rcx: &mut Rcx, expr: @ast::Expr) -> ExprCategorization {
debug!("categorize()"); debug!("categorize()");
let mut expr_ct = categorize_unadjusted(rcx, expr); let mut expr_ct = categorize_unadjusted(rcx, expr);
@ -1096,7 +1090,7 @@ pub mod guarantor {
return expr_ct.cat; return expr_ct.cat;
} }
fn categorize_unadjusted(rcx: @mut Rcx, fn categorize_unadjusted(rcx: &mut Rcx,
expr: @ast::Expr) expr: @ast::Expr)
-> ExprCategorizationType { -> ExprCategorizationType {
debug!("categorize_unadjusted()"); debug!("categorize_unadjusted()");
@ -1120,7 +1114,7 @@ pub mod guarantor {
} }
fn apply_autoderefs( fn apply_autoderefs(
rcx: @mut Rcx, rcx: &mut Rcx,
expr: @ast::Expr, expr: @ast::Expr,
autoderefs: uint, autoderefs: uint,
ct: ExprCategorizationType) ct: ExprCategorizationType)
@ -1198,7 +1192,7 @@ pub mod guarantor {
} }
fn link_ref_bindings_in_pat( fn link_ref_bindings_in_pat(
rcx: @mut Rcx, rcx: &mut Rcx,
pat: @ast::Pat, pat: @ast::Pat,
guarantor: Option<ty::Region>) { guarantor: Option<ty::Region>) {
/*! /*!
@ -1271,7 +1265,7 @@ pub mod guarantor {
} }
} }
fn link_ref_bindings_in_pats(rcx: @mut Rcx, fn link_ref_bindings_in_pats(rcx: &mut Rcx,
pats: &~[@ast::Pat], pats: &~[@ast::Pat],
guarantor: Option<ty::Region>) { guarantor: Option<ty::Region>) {
for pat in pats.iter() { for pat in pats.iter() {

View File

@ -720,11 +720,11 @@ pub fn early_resolve_expr(ex: @ast::Expr,
} }
} }
fn resolve_expr(v: &mut VtableResolveVisitor, fn resolve_expr(fcx: @mut FnCtxt,
ex: @ast::Expr, ex: @ast::Expr) {
fcx: @mut FnCtxt) { let mut fcx = fcx;
early_resolve_expr(ex, fcx, false); early_resolve_expr(ex, fcx, false);
visit::walk_expr(v, ex, fcx); visit::walk_expr(&mut fcx, ex, ());
} }
pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) { pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
@ -771,13 +771,11 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
} }
} }
struct VtableResolveVisitor; impl visit::Visitor<()> for @mut FnCtxt {
fn visit_expr(&mut self, ex:@ast::Expr, _:()) {
impl visit::Visitor<@mut FnCtxt> for VtableResolveVisitor { resolve_expr(*self, ex);
fn visit_expr(&mut self, ex:@ast::Expr, e:@mut FnCtxt) {
resolve_expr(self, ex, e);
} }
fn visit_item(&mut self, _:@ast::item, _:@mut FnCtxt) { fn visit_item(&mut self, _:@ast::item, _:()) {
// no-op // no-op
} }
} }
@ -785,6 +783,6 @@ impl visit::Visitor<@mut FnCtxt> for VtableResolveVisitor {
// Detect points where a trait-bounded type parameter is // Detect points where a trait-bounded type parameter is
// instantiated, resolve the impls for the parameters. // instantiated, resolve the impls for the parameters.
pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) { pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) {
let mut visitor = VtableResolveVisitor; let mut fcx = fcx;
visit::walk_block(&mut visitor, bl, fcx); visit::walk_block(&mut fcx, bl, ());
} }

View File

@ -114,7 +114,7 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: Span, id: ast::NodeId) {
} }
} }
fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: Span, id: ast::NodeId) fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
-> Option<ty::t> { -> Option<ty::t> {
let fcx = wbcx.fcx; let fcx = wbcx.fcx;
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
@ -196,7 +196,7 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: Span, id: ast::NodeId)
} }
} }
fn maybe_resolve_type_vars_for_node(wbcx: @mut WbCtxt, fn maybe_resolve_type_vars_for_node(wbcx: &mut WbCtxt,
sp: Span, sp: Span,
id: ast::NodeId) id: ast::NodeId)
-> Option<ty::t> { -> Option<ty::t> {
@ -215,15 +215,13 @@ struct WbCtxt {
success: bool, success: bool,
} }
struct WbVisitor; fn visit_stmt(s: @ast::Stmt, wbcx: &mut WbCtxt) {
fn visit_stmt(s: @ast::Stmt, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
if !wbcx.success { return; } if !wbcx.success { return; }
resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s)); resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
visit::walk_stmt(v, s, wbcx); visit::walk_stmt(wbcx, s, ());
} }
fn visit_expr(e: @ast::Expr, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) { fn visit_expr(e: @ast::Expr, wbcx: &mut WbCtxt) {
if !wbcx.success { if !wbcx.success {
return; return;
} }
@ -268,19 +266,19 @@ fn visit_expr(e: @ast::Expr, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
_ => () _ => ()
} }
visit::walk_expr(v, e, wbcx); visit::walk_expr(wbcx, e, ());
} }
fn visit_block(b: &ast::Block, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) { fn visit_block(b: &ast::Block, wbcx: &mut WbCtxt) {
if !wbcx.success { if !wbcx.success {
return; return;
} }
resolve_type_vars_for_node(wbcx, b.span, b.id); resolve_type_vars_for_node(wbcx, b.span, b.id);
visit::walk_block(v, b, wbcx); visit::walk_block(wbcx, b, ());
} }
fn visit_pat(p: @ast::Pat, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) { fn visit_pat(p: @ast::Pat, wbcx: &mut WbCtxt) {
if !wbcx.success { if !wbcx.success {
return; return;
} }
@ -291,10 +289,10 @@ fn visit_pat(p: @ast::Pat, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
wbcx.fcx.infcx().ty_to_str( wbcx.fcx.infcx().ty_to_str(
ty::node_id_to_type(wbcx.fcx.ccx.tcx, ty::node_id_to_type(wbcx.fcx.ccx.tcx,
p.id))); p.id)));
visit::walk_pat(v, p, wbcx); visit::walk_pat(wbcx, p, ());
} }
fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) { fn visit_local(l: @ast::Local, wbcx: &mut WbCtxt) {
if !wbcx.success { return; } if !wbcx.success { return; }
let var_ty = wbcx.fcx.local_ty(l.span, l.id); let var_ty = wbcx.fcx.local_ty(l.span, l.id);
match resolve_type(wbcx.fcx.infcx(), var_ty, resolve_all | force_all) { match resolve_type(wbcx.fcx.infcx(), var_ty, resolve_all | force_all) {
@ -314,25 +312,25 @@ fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
wbcx.success = false; wbcx.success = false;
} }
} }
visit::walk_local(v, l, wbcx); visit::walk_local(wbcx, l, ());
} }
fn visit_item(_item: @ast::item, (_wbcx, _v): (@mut WbCtxt, &mut WbVisitor)) { fn visit_item(_item: @ast::item, _wbcx: &mut WbCtxt) {
// Ignore items // Ignore items
} }
impl Visitor<@mut WbCtxt> for WbVisitor { impl Visitor<()> for WbCtxt {
fn visit_item(&mut self, i:@ast::item, e:@mut WbCtxt) { visit_item(i, (e, self)); } fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(i, self); }
fn visit_stmt(&mut self, s:@ast::Stmt, e:@mut WbCtxt) { visit_stmt(s, (e, self)); } fn visit_stmt(&mut self, s:@ast::Stmt, _:()) { visit_stmt(s, self); }
fn visit_expr(&mut self, ex:@ast::Expr, e:@mut WbCtxt) { visit_expr(ex, (e, self)); } fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(ex, self); }
fn visit_block(&mut self, b:&ast::Block, e:@mut WbCtxt) { visit_block(b, (e, self)); } fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(b, self); }
fn visit_pat(&mut self, p:@ast::Pat, e:@mut WbCtxt) { visit_pat(p, (e, self)); } fn visit_pat(&mut self, p:@ast::Pat, _:()) { visit_pat(p, self); }
fn visit_local(&mut self, l:@ast::Local, e:@mut WbCtxt) { visit_local(l, (e, self)); } fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(l, self); }
} }
pub fn resolve_type_vars_in_expr(fcx: @mut FnCtxt, e: @ast::Expr) -> bool { pub fn resolve_type_vars_in_expr(fcx: @mut FnCtxt, e: @ast::Expr) -> bool {
let wbcx = @mut WbCtxt { fcx: fcx, success: true }; let mut wbcx = WbCtxt { fcx: fcx, success: true };
let mut visit = WbVisitor; let wbcx = &mut wbcx;
visit.visit_expr(e, wbcx); wbcx.visit_expr(e, ());
return wbcx.success; return wbcx.success;
} }
@ -340,16 +338,16 @@ pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt,
decl: &ast::fn_decl, decl: &ast::fn_decl,
blk: &ast::Block, blk: &ast::Block,
self_info: Option<SelfInfo>) -> bool { self_info: Option<SelfInfo>) -> bool {
let wbcx = @mut WbCtxt { fcx: fcx, success: true }; let mut wbcx = WbCtxt { fcx: fcx, success: true };
let mut visit = WbVisitor; let wbcx = &mut wbcx;
visit.visit_block(blk, wbcx); wbcx.visit_block(blk, ());
for self_info in self_info.iter() { for self_info in self_info.iter() {
resolve_type_vars_for_node(wbcx, resolve_type_vars_for_node(wbcx,
self_info.span, self_info.span,
self_info.self_id); self_info.self_id);
} }
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
visit.visit_pat(arg.pat, wbcx); wbcx.visit_pat(arg.pat, ());
// Privacy needs the type for the whole pattern, not just each binding // Privacy needs the type for the whole pattern, not just each binding
if !pat_util::pat_is_binding(fcx.tcx().def_map, arg.pat) { if !pat_util::pat_is_binding(fcx.tcx().def_map, arg.pat) {
resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id); resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id);