about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2013-09-24 14:34:51 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2013-09-24 14:34:51 +0200
commit0e95c3434b848da6fd7b8cd0ff27bec5d51db01c (patch)
treec32c21a8d264ca304113e2632ee2eb4aa168533f /src/librustc
parent4f691cd5bc83311da1b91b6e5da54e5514440749 (diff)
downloadrust-0e95c3434b848da6fd7b8cd0ff27bec5d51db01c.tar.gz
rust-0e95c3434b848da6fd7b8cd0ff27bec5d51db01c.zip
Part of #7081: Fold remainder of typeck's visit env into their visitor structs.
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/middle/typeck/check/_match.rs4
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs130
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs22
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs56
4 files changed, 101 insertions, 111 deletions
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 061921e60e1..606b0255cd7 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -37,12 +37,12 @@ pub fn check_match(fcx: @mut FnCtxt,
     // Typecheck the patterns first, so that we get types for all the
     // bindings.
     for arm in arms.iter() {
-        let pcx = pat_ctxt {
+        let mut pcx = pat_ctxt {
             fcx: fcx,
             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
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 29f087094fb..78c20b54845 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -122,12 +122,13 @@ impl Rcx {
     }
 
     /// Try to resolve the type for the given node.
-    pub fn resolve_node_type(@mut self, id: ast::NodeId) -> ty::t {
-        self.resolve_type(self.fcx.node_ty(id))
+    pub fn resolve_node_type(&mut self, id: ast::NodeId) -> ty::t {
+        let t = self.fcx.node_ty(id);
+        self.resolve_type(t)
     }
 
     /// 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);
         if ty::type_is_error(ty_unadjusted) || ty::type_is_bot(ty_unadjusted) {
             ty_unadjusted
@@ -141,30 +142,28 @@ impl Rcx {
 }
 
 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 };
+    let rcx = &mut rcx;
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        let mut v = regionck_visitor();
-        v.visit_expr(e, rcx);
+        rcx.visit_expr(e, ());
     }
     fcx.infcx().resolve_regions();
 }
 
 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 };
+    let rcx = &mut rcx;
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        let mut v = regionck_visitor();
-        v.visit_block(blk, rcx);
+        rcx.visit_block(blk, ());
     }
     fcx.infcx().resolve_regions();
 }
 
-struct RegionckVisitor;
-
-impl Visitor<@mut Rcx> for RegionckVisitor {
+impl Visitor<()> for Rcx {
     // (*) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
     // However, right now we run into an issue whereby some free
     // 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
     // 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
 
-    fn visit_arm(&mut self, a:&ast::Arm, e:@mut Rcx) { visit_arm(self, a, e); }
-
-    fn visit_local(&mut self, l:@ast::Local, e:@mut Rcx) { visit_local(self, l, e); }
+    fn visit_arm(&mut self, a:&ast::Arm, _:()) { visit_arm(self, a); }
 
-    fn visit_block(&mut self, b:&ast::Block, e:@mut Rcx) { visit_block(self, b, e); }
-}
+    fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(self, l); }
 
-fn regionck_visitor() -> RegionckVisitor {
-    RegionckVisitor
+    fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(self, b); }
 }
 
-fn visit_item(_v: &mut RegionckVisitor, _item: @ast::item, _rcx: @mut Rcx) {
+fn visit_item(_rcx: &mut Rcx, _item: @ast::item) {
     // 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);
-    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
     for &p in arm.pats.iter() {
         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
     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();
     debug!("regionck::visit_pat(pat=%s)", pat.repr(tcx));
     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=%?)",
            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_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, _) => {
             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) |
@@ -354,14 +349,14 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             // should be converted to an adjustment!
             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 => {
             // As above.
             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) => {
@@ -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);
             constrain_derefs(rcx, expr, 1, base_ty);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, 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);
             constrain_index(rcx, expr, vec_type);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         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) => {
@@ -423,44 +418,43 @@ fn visit_expr(v: &mut RegionckVisitor, expr: @ast::Expr, rcx: @mut Rcx) {
             let ty0 = rcx.resolve_node_type(expr.id);
             constrain_regions_in_type(rcx, ty::re_scope(expr.id),
                                       infer::AddrOf(expr.span), ty0);
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprMatch(discr, ref arms) => {
             guarantor::for_match(rcx, discr, *arms);
 
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
         }
 
         ast::ExprFnBlock(*) => {
-            check_expr_fn_block(rcx, expr, v);
+            check_expr_fn_block(rcx, expr);
         }
 
         ast::ExprLoop(ref body, _) => {
             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);
         }
 
         ast::ExprWhile(cond, ref body) => {
             let repeating_scope = rcx.set_repeating_scope(cond.id);
-            v.visit_expr(cond, rcx);
+            rcx.visit_expr(cond, ());
 
             rcx.set_repeating_scope(body.id);
-            v.visit_block(body, rcx);
+            rcx.visit_block(body, ());
 
             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,
-                       expr: @ast::Expr,
-                       v: &mut RegionckVisitor) {
+fn check_expr_fn_block(rcx: &mut Rcx,
+                       expr: @ast::Expr) {
     let tcx = rcx.fcx.tcx();
     match expr.node {
         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);
-            visit::walk_expr(v, expr, rcx);
+            visit::walk_expr(rcx, expr, ());
             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,
                     call_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
                   // operator
                   callee_id: ast::NodeId,
@@ -589,7 +583,7 @@ fn constrain_call(rcx: @mut Rcx,
         fn_sig.output);
 }
 
-fn constrain_derefs(rcx: @mut Rcx,
+fn constrain_derefs(rcx: &mut Rcx,
                     deref_expr: @ast::Expr,
                     derefs: uint,
                     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,
                                      minimum_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,
                    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,
                             expr: @ast::Expr) {
     /*!
@@ -681,7 +675,7 @@ fn constrain_free_variables(rcx: @mut Rcx,
 }
 
 fn constrain_regions_in_type_of_node(
-    rcx: @mut Rcx,
+    rcx: &mut Rcx,
     id: ast::NodeId,
     minimum_lifetime: ty::Region,
     origin: infer::SubregionOrigin) -> bool
@@ -706,7 +700,7 @@ fn constrain_regions_in_type_of_node(
 }
 
 fn constrain_regions_in_type(
-    rcx: @mut Rcx,
+    rcx: &mut Rcx,
     minimum_lifetime: ty::Region,
     origin: infer::SubregionOrigin,
     ty: ty::t) -> bool
@@ -812,7 +806,7 @@ pub mod guarantor {
     use syntax::codemap::Span;
     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
          * ensures that the lifetime of the resulting pointer is linked
@@ -825,7 +819,7 @@ pub mod 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
          * 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,
                        autoderefs: uint,
                        autoref: &ty::AutoRef) {
@@ -882,7 +876,7 @@ pub mod guarantor {
         }
 
         fn maybe_make_subregion(
-            rcx: @mut Rcx,
+            rcx: &mut Rcx,
             expr: @ast::Expr,
             sub_region: 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,
                       callee_scope: ast::NodeId) {
         /*!
@@ -917,7 +911,7 @@ pub mod guarantor {
     }
 
     fn link(
-        rcx: @mut Rcx,
+        rcx: &mut Rcx,
         span: Span,
         id: ast::NodeId,
         guarantor: Option<ty::Region>) {
@@ -974,7 +968,7 @@ pub mod guarantor {
         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
@@ -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()");
 
         let mut expr_ct = categorize_unadjusted(rcx, expr);
@@ -1096,7 +1090,7 @@ pub mod guarantor {
         return expr_ct.cat;
     }
 
-    fn categorize_unadjusted(rcx: @mut Rcx,
+    fn categorize_unadjusted(rcx: &mut Rcx,
                              expr: @ast::Expr)
                           -> ExprCategorizationType {
         debug!("categorize_unadjusted()");
@@ -1120,7 +1114,7 @@ pub mod guarantor {
     }
 
     fn apply_autoderefs(
-        rcx: @mut Rcx,
+        rcx: &mut Rcx,
         expr: @ast::Expr,
         autoderefs: uint,
         ct: ExprCategorizationType)
@@ -1198,7 +1192,7 @@ pub mod guarantor {
     }
 
     fn link_ref_bindings_in_pat(
-        rcx: @mut Rcx,
+        rcx: &mut Rcx,
         pat: @ast::Pat,
         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],
                                  guarantor: Option<ty::Region>) {
         for pat in pats.iter() {
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index b96f85b676b..0e153635720 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -720,11 +720,11 @@ pub fn early_resolve_expr(ex: @ast::Expr,
     }
 }
 
-fn resolve_expr(v: &mut VtableResolveVisitor,
-                ex: @ast::Expr,
-                fcx: @mut FnCtxt) {
+fn resolve_expr(fcx: @mut FnCtxt,
+                ex: @ast::Expr) {
+    let mut fcx = fcx;
     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) {
@@ -771,13 +771,11 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
     }
 }
 
-struct VtableResolveVisitor;
-
-impl visit::Visitor<@mut FnCtxt> for VtableResolveVisitor {
-    fn visit_expr(&mut self, ex:@ast::Expr, e:@mut FnCtxt) {
-        resolve_expr(self, ex, e);
+impl visit::Visitor<()> for @mut FnCtxt {
+    fn visit_expr(&mut self, ex:@ast::Expr, _:()) {
+        resolve_expr(*self, ex);
     }
-    fn visit_item(&mut self, _:@ast::item, _:@mut FnCtxt) {
+    fn visit_item(&mut self, _:@ast::item, _:()) {
         // no-op
     }
 }
@@ -785,6 +783,6 @@ impl visit::Visitor<@mut FnCtxt> for VtableResolveVisitor {
 // Detect points where a trait-bounded type parameter is
 // instantiated, resolve the impls for the parameters.
 pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) {
-    let mut visitor = VtableResolveVisitor;
-    visit::walk_block(&mut visitor, bl, fcx);
+    let mut fcx = fcx;
+    visit::walk_block(&mut fcx, bl, ());
 }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 2f11d9ff2eb..5e9ca576a56 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -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> {
     let fcx = wbcx.fcx;
     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,
                                     id: ast::NodeId)
                                  -> Option<ty::t> {
@@ -215,15 +215,13 @@ struct WbCtxt {
     success: bool,
 }
 
-struct WbVisitor;
-
-fn visit_stmt(s: @ast::Stmt, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
+fn visit_stmt(s: @ast::Stmt, wbcx: &mut WbCtxt) {
     if !wbcx.success { return; }
     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 {
         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 {
         return;
     }
 
     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 {
         return;
     }
@@ -291,10 +289,10 @@ fn visit_pat(p: @ast::Pat, (wbcx, v): (@mut WbCtxt, &mut WbVisitor)) {
            wbcx.fcx.infcx().ty_to_str(
                ty::node_id_to_type(wbcx.fcx.ccx.tcx,
                                    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; }
     let var_ty = wbcx.fcx.local_ty(l.span, l.id);
     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;
         }
     }
-    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
 }
 
-impl Visitor<@mut WbCtxt> for WbVisitor {
-    fn visit_item(&mut self, i:@ast::item, e:@mut WbCtxt) { visit_item(i, (e, self)); }
-    fn visit_stmt(&mut self, s:@ast::Stmt, e:@mut WbCtxt) { visit_stmt(s, (e, self)); }
-    fn visit_expr(&mut self, ex:@ast::Expr, e:@mut WbCtxt) { visit_expr(ex, (e, self)); }
-    fn visit_block(&mut self, b:&ast::Block, e:@mut WbCtxt) { visit_block(b, (e, self)); }
-    fn visit_pat(&mut self, p:@ast::Pat, e:@mut WbCtxt) { visit_pat(p, (e, self)); }
-    fn visit_local(&mut self, l:@ast::Local, e:@mut WbCtxt) { visit_local(l, (e, self)); }
+impl Visitor<()> for WbCtxt {
+    fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(i, self); }
+    fn visit_stmt(&mut self, s:@ast::Stmt, _:()) { visit_stmt(s, self); }
+    fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(ex, self); }
+    fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(b, self); }
+    fn visit_pat(&mut self, p:@ast::Pat, _:()) { visit_pat(p, 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 {
-    let wbcx = @mut WbCtxt { fcx: fcx, success: true };
-    let mut visit = WbVisitor;
-    visit.visit_expr(e, wbcx);
+    let mut wbcx = WbCtxt { fcx: fcx, success: true };
+    let wbcx = &mut wbcx;
+    wbcx.visit_expr(e, ());
     return wbcx.success;
 }
 
@@ -340,16 +338,16 @@ pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt,
                                decl: &ast::fn_decl,
                                blk: &ast::Block,
                                self_info: Option<SelfInfo>) -> bool {
-    let wbcx = @mut WbCtxt { fcx: fcx, success: true };
-    let mut visit = WbVisitor;
-    visit.visit_block(blk, wbcx);
+    let mut wbcx = WbCtxt { fcx: fcx, success: true };
+    let wbcx = &mut wbcx;
+    wbcx.visit_block(blk, ());
     for self_info in self_info.iter() {
         resolve_type_vars_for_node(wbcx,
                                    self_info.span,
                                    self_info.self_id);
     }
     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
         if !pat_util::pat_is_binding(fcx.tcx().def_map, arg.pat) {
             resolve_type_vars_for_node(wbcx, arg.pat.span, arg.pat.id);