about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2014-09-12 13:10:30 +0300
committerEduard Burtescu <edy.burt@gmail.com>2014-09-12 14:24:45 +0300
commita09dbf28e64e7ac9b9786320d90a87854615d77a (patch)
tree9c323160b55481f65782469bb7b88ac94c37b159
parent22e749ded10822a3063fa26800aaa3f229e97c4d (diff)
downloadrust-a09dbf28e64e7ac9b9786320d90a87854615d77a.tar.gz
rust-a09dbf28e64e7ac9b9786320d90a87854615d77a.zip
Remove largely unused context from Visitor.
-rw-r--r--src/librustc/front/feature_gate.rs43
-rw-r--r--src/librustc/front/show_span.rs12
-rw-r--r--src/librustc/lint/builtin.rs20
-rw-r--r--src/librustc/lint/context.rs113
-rw-r--r--src/librustc/metadata/creader.rs12
-rw-r--r--src/librustc/metadata/encoder.rs30
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs10
-rw-r--r--src/librustc/middle/borrowck/mod.rs12
-rw-r--r--src/librustc/middle/check_const.rs80
-rw-r--r--src/librustc/middle/check_loop.rs40
-rw-r--r--src/librustc/middle/check_match.rs37
-rw-r--r--src/librustc/middle/check_rvalues.rs7
-rw-r--r--src/librustc/middle/check_static.rs49
-rw-r--r--src/librustc/middle/const_eval.rs10
-rw-r--r--src/librustc/middle/dataflow.rs8
-rw-r--r--src/librustc/middle/dead.rs91
-rw-r--r--src/librustc/middle/effect.rs16
-rw-r--r--src/librustc/middle/entry.rs8
-rw-r--r--src/librustc/middle/freevars.rs70
-rw-r--r--src/librustc/middle/intrinsicck.rs8
-rw-r--r--src/librustc/middle/kind.rs30
-rw-r--r--src/librustc/middle/lang_items.rs8
-rw-r--r--src/librustc/middle/liveness.rs62
-rw-r--r--src/librustc/middle/privacy.rs139
-rw-r--r--src/librustc/middle/reachable.rs16
-rw-r--r--src/librustc/middle/region.rs160
-rw-r--r--src/librustc/middle/resolve.rs101
-rw-r--r--src/librustc/middle/resolve_lifetime.rs158
-rw-r--r--src/librustc/middle/save/mod.rs343
-rw-r--r--src/librustc/middle/stability.rs82
-rw-r--r--src/librustc/middle/trans/base.rs80
-rw-r--r--src/librustc/middle/trans/controlflow.rs4
-rw-r--r--src/librustc/middle/trans/meth.rs4
-rw-r--r--src/librustc/middle/typeck/check/mod.rs52
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs62
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs10
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs36
-rw-r--r--src/librustc/middle/typeck/coherence.rs20
-rw-r--r--src/librustc/middle/typeck/collect.rs20
-rw-r--r--src/librustc/middle/typeck/variance.rs18
-rw-r--r--src/librustc/middle/weak_lang_items.rs8
-rw-r--r--src/librustc/plugin/build.rs8
-rw-r--r--src/librustc/plugin/load.rs8
-rw-r--r--src/librustc/util/common.rs16
-rw-r--r--src/librustc_back/svh.rs109
-rw-r--r--src/libsyntax/ast_util.rs76
-rw-r--r--src/libsyntax/ext/expand.rs45
-rw-r--r--src/libsyntax/visit.rs606
48 files changed, 1451 insertions, 1506 deletions
diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs
index 225fc28cd6d..b3653b5dcff 100644
--- a/src/librustc/front/feature_gate.rs
+++ b/src/librustc/front/feature_gate.rs
@@ -143,15 +143,15 @@ impl<'a> Context<'a> {
     }
 }
 
-impl<'a> Visitor<()> for Context<'a> {
-    fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
+impl<'a> Visitor for Context<'a> {
+    fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
         if !token::get_ident(id).get().is_ascii() {
             self.gate_feature("non_ascii_idents", sp,
                               "non-ascii idents are not fully supported.");
         }
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
+    fn visit_view_item(&mut self, i: &ast::ViewItem) {
         match i.node {
             ast::ViewItemUse(ref path) => {
                 match path.node {
@@ -173,10 +173,10 @@ impl<'a> Visitor<()> for Context<'a> {
                 }
             }
         }
-        visit::walk_view_item(self, i, ())
+        visit::walk_view_item(self, i)
     }
 
-    fn visit_item(&mut self, i: &ast::Item, _:()) {
+    fn visit_item(&mut self, i: &ast::Item) {
         for attr in i.attrs.iter() {
             if attr.name().equiv(&("thread_local")) {
                 self.gate_feature("thread_local", i.span,
@@ -252,10 +252,10 @@ impl<'a> Visitor<()> for Context<'a> {
             _ => {}
         }
 
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
 
-    fn visit_mac(&mut self, macro: &ast::Mac, _: ()) {
+    fn visit_mac(&mut self, macro: &ast::Mac) {
         let ast::MacInvocTT(ref path, _, _) = macro.node;
         let id = path.segments.last().unwrap().identifier;
         let quotes = ["quote_tokens", "quote_expr", "quote_ty",
@@ -299,16 +299,16 @@ impl<'a> Visitor<()> for Context<'a> {
         }
     }
 
-    fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         if attr::contains_name(i.attrs.as_slice(), "linkage") {
             self.gate_feature("linkage", i.span,
                               "the `linkage` attribute is experimental \
                                and not portable across platforms")
         }
-        visit::walk_foreign_item(self, i, ())
+        visit::walk_foreign_item(self, i)
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         match t.node {
             ast::TyClosure(closure) if closure.onceness == ast::Once => {
                 self.gate_feature("once_fns", t.span,
@@ -325,10 +325,10 @@ impl<'a> Visitor<()> for Context<'a> {
             _ => {}
         }
 
-        visit::walk_ty(self, t, ());
+        visit::walk_ty(self, t);
     }
 
-    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
             ast::ExprUnary(ast::UnBox, _) => {
                 self.gate_box(e.span);
@@ -346,10 +346,10 @@ impl<'a> Visitor<()> for Context<'a> {
             }
             _ => {}
         }
-        visit::walk_expr(self, e, ());
+        visit::walk_expr(self, e);
     }
 
-    fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
+    fn visit_generics(&mut self, generics: &ast::Generics) {
         for type_parameter in generics.ty_params.iter() {
             match type_parameter.default {
                 Some(ty) => {
@@ -360,10 +360,10 @@ impl<'a> Visitor<()> for Context<'a> {
                 None => {}
             }
         }
-        visit::walk_generics(self, generics, ());
+        visit::walk_generics(self, generics);
     }
 
-    fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) {
+    fn visit_attribute(&mut self, attr: &ast::Attribute) {
         if attr::contains_name([*attr], "lang") {
             self.gate_feature("lang_items",
                               attr.span,
@@ -371,7 +371,7 @@ impl<'a> Visitor<()> for Context<'a> {
         }
     }
 
-    fn visit_pat(&mut self, pattern: &ast::Pat, (): ()) {
+    fn visit_pat(&mut self, pattern: &ast::Pat) {
         match pattern.node {
             ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
                 self.gate_feature("advanced_slice_patterns",
@@ -382,7 +382,7 @@ impl<'a> Visitor<()> for Context<'a> {
             }
             _ => {}
         }
-        visit::walk_pat(self, pattern, ())
+        visit::walk_pat(self, pattern)
     }
 
     fn visit_fn(&mut self,
@@ -390,8 +390,7 @@ impl<'a> Visitor<()> for Context<'a> {
                 fn_decl: &ast::FnDecl,
                 block: &ast::Block,
                 span: Span,
-                _: NodeId,
-                (): ()) {
+                _: NodeId) {
         match *fn_kind {
             visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => {
                 self.gate_feature("intrinsics",
@@ -400,7 +399,7 @@ impl<'a> Visitor<()> for Context<'a> {
             }
             _ => {}
         }
-        visit::walk_fn(self, fn_kind, fn_decl, block, span, ());
+        visit::walk_fn(self, fn_kind, fn_decl, block, span);
     }
 }
 
@@ -453,7 +452,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
         }
     }
 
-    visit::walk_crate(&mut cx, krate, ());
+    visit::walk_crate(&mut cx, krate);
 
     sess.abort_if_errors();
 
diff --git a/src/librustc/front/show_span.rs b/src/librustc/front/show_span.rs
index 1a59b3603de..2ccba474bfe 100644
--- a/src/librustc/front/show_span.rs
+++ b/src/librustc/front/show_span.rs
@@ -23,18 +23,18 @@ struct ShowSpanVisitor<'a> {
     sess: &'a Session
 }
 
-impl<'a> Visitor<()> for ShowSpanVisitor<'a> {
-    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
+impl<'a> Visitor for ShowSpanVisitor<'a> {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         self.sess.span_note(e.span, "expression");
-        visit::walk_expr(self, e, ());
+        visit::walk_expr(self, e);
     }
 
-    fn visit_mac(&mut self, macro: &ast::Mac, e: ()) {
-        visit::walk_mac(self, macro, e);
+    fn visit_mac(&mut self, macro: &ast::Mac) {
+        visit::walk_mac(self, macro);
     }
 }
 
 pub fn run(sess: &Session, krate: &ast::Crate) {
     let mut v = ShowSpanVisitor { sess: sess };
-    visit::walk_crate(&mut v, krate, ());
+    visit::walk_crate(&mut v, krate);
 }
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 138947e8a87..b1ea8b5d818 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -366,13 +366,13 @@ impl<'a, 'tcx> CTypesVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for CTypesVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
+impl<'a, 'tcx> Visitor for CTypesVisitor<'a, 'tcx> {
+    fn visit_ty(&mut self, ty: &ast::Ty) {
         match ty.node {
             ast::TyPath(_, _, id) => self.check_def(ty.span, ty.id, id),
             _ => (),
         }
-        visit::walk_ty(self, ty, ());
+        visit::walk_ty(self, ty);
     }
 }
 
@@ -386,7 +386,7 @@ impl LintPass for CTypes {
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
         fn check_ty(cx: &Context, ty: &ast::Ty) {
             let mut vis = CTypesVisitor { cx: cx };
-            vis.visit_ty(ty, ());
+            vis.visit_ty(ty);
         }
 
         fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
@@ -500,18 +500,18 @@ struct RawPtrDerivingVisitor<'a, 'tcx: 'a> {
     cx: &'a Context<'a, 'tcx>
 }
 
-impl<'a, 'tcx> Visitor<()> for RawPtrDerivingVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
+impl<'a, 'tcx> Visitor for RawPtrDerivingVisitor<'a, 'tcx> {
+    fn visit_ty(&mut self, ty: &ast::Ty) {
         static MSG: &'static str = "use of `#[deriving]` with a raw pointer";
         match ty.node {
             ast::TyPtr(..) => self.cx.span_lint(RAW_POINTER_DERIVING, ty.span, MSG),
             _ => {}
         }
-        visit::walk_ty(self, ty, ());
+        visit::walk_ty(self, ty);
     }
     // explicit override to a no-op to reduce code bloat
-    fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
-    fn visit_block(&mut self, _: &ast::Block, _: ()) {}
+    fn visit_expr(&mut self, _: &ast::Expr) {}
+    fn visit_block(&mut self, _: &ast::Block) {}
 }
 
 pub struct RawPointerDeriving {
@@ -554,7 +554,7 @@ impl LintPass for RawPointerDeriving {
         match item.node {
             ast::ItemStruct(..) | ast::ItemEnum(..) => {
                 let mut visitor = RawPtrDerivingVisitor { cx: cx };
-                visit::walk_item(&mut visitor, &*item, ());
+                visit::walk_item(&mut visitor, &*item);
             }
             _ => {}
         }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 26ed5cbfb2c..bd7f6296d92 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -492,68 +492,68 @@ impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> {
-    fn visit_item(&mut self, it: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for Context<'a, 'tcx> {
+    fn visit_item(&mut self, it: &ast::Item) {
         self.with_lint_attrs(it.attrs.as_slice(), |cx| {
             run_lints!(cx, check_item, it);
-            cx.visit_ids(|v| v.visit_item(it, ()));
-            visit::walk_item(cx, it, ());
+            cx.visit_ids(|v| v.visit_item(it));
+            visit::walk_item(cx, it);
         })
     }
 
-    fn visit_foreign_item(&mut self, it: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, it: &ast::ForeignItem) {
         self.with_lint_attrs(it.attrs.as_slice(), |cx| {
             run_lints!(cx, check_foreign_item, it);
-            visit::walk_foreign_item(cx, it, ());
+            visit::walk_foreign_item(cx, it);
         })
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
+    fn visit_view_item(&mut self, i: &ast::ViewItem) {
         self.with_lint_attrs(i.attrs.as_slice(), |cx| {
             run_lints!(cx, check_view_item, i);
-            cx.visit_ids(|v| v.visit_view_item(i, ()));
-            visit::walk_view_item(cx, i, ());
+            cx.visit_ids(|v| v.visit_view_item(i));
+            visit::walk_view_item(cx, i);
         })
     }
 
-    fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
+    fn visit_pat(&mut self, p: &ast::Pat) {
         run_lints!(self, check_pat, p);
-        visit::walk_pat(self, p, ());
+        visit::walk_pat(self, p);
     }
 
-    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         run_lints!(self, check_expr, e);
-        visit::walk_expr(self, e, ());
+        visit::walk_expr(self, e);
     }
 
-    fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) {
+    fn visit_stmt(&mut self, s: &ast::Stmt) {
         run_lints!(self, check_stmt, s);
-        visit::walk_stmt(self, s, ());
+        visit::walk_stmt(self, s);
     }
 
     fn visit_fn(&mut self, fk: &FnKind, decl: &ast::FnDecl,
-                body: &ast::Block, span: Span, id: ast::NodeId, _: ()) {
+                body: &ast::Block, span: Span, id: ast::NodeId) {
         match *fk {
             visit::FkMethod(_, _, m) => {
                 self.with_lint_attrs(m.attrs.as_slice(), |cx| {
                     run_lints!(cx, check_fn, fk, decl, body, span, id);
                     cx.visit_ids(|v| {
-                        v.visit_fn(fk, decl, body, span, id, ());
+                        v.visit_fn(fk, decl, body, span, id);
                     });
-                    visit::walk_fn(cx, fk, decl, body, span, ());
+                    visit::walk_fn(cx, fk, decl, body, span);
                 })
             },
             _ => {
                 run_lints!(self, check_fn, fk, decl, body, span, id);
-                visit::walk_fn(self, fk, decl, body, span, ());
+                visit::walk_fn(self, fk, decl, body, span);
             }
         }
     }
 
-    fn visit_ty_method(&mut self, t: &ast::TypeMethod, _: ()) {
+    fn visit_ty_method(&mut self, t: &ast::TypeMethod) {
         self.with_lint_attrs(t.attrs.as_slice(), |cx| {
             run_lints!(cx, check_ty_method, t);
-            visit::walk_ty_method(cx, t, ());
+            visit::walk_ty_method(cx, t);
         })
     }
 
@@ -561,103 +561,102 @@ impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> {
                         s: &ast::StructDef,
                         ident: ast::Ident,
                         g: &ast::Generics,
-                        id: ast::NodeId,
-                        _: ()) {
+                        id: ast::NodeId) {
         run_lints!(self, check_struct_def, s, ident, g, id);
-        visit::walk_struct_def(self, s, ());
+        visit::walk_struct_def(self, s);
         run_lints!(self, check_struct_def_post, s, ident, g, id);
     }
 
-    fn visit_struct_field(&mut self, s: &ast::StructField, _: ()) {
+    fn visit_struct_field(&mut self, s: &ast::StructField) {
         self.with_lint_attrs(s.node.attrs.as_slice(), |cx| {
             run_lints!(cx, check_struct_field, s);
-            visit::walk_struct_field(cx, s, ());
+            visit::walk_struct_field(cx, s);
         })
     }
 
-    fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics, _: ()) {
+    fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
         self.with_lint_attrs(v.node.attrs.as_slice(), |cx| {
             run_lints!(cx, check_variant, v, g);
-            visit::walk_variant(cx, v, g, ());
+            visit::walk_variant(cx, v, g);
         })
     }
 
     // FIXME(#10894) should continue recursing
-    fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         run_lints!(self, check_ty, t);
     }
 
-    fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
+    fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
         run_lints!(self, check_ident, sp, id);
     }
 
-    fn visit_mod(&mut self, m: &ast::Mod, s: Span, n: ast::NodeId, _: ()) {
+    fn visit_mod(&mut self, m: &ast::Mod, s: Span, n: ast::NodeId) {
         run_lints!(self, check_mod, m, s, n);
-        visit::walk_mod(self, m, ());
+        visit::walk_mod(self, m);
     }
 
-    fn visit_local(&mut self, l: &ast::Local, _: ()) {
+    fn visit_local(&mut self, l: &ast::Local) {
         run_lints!(self, check_local, l);
-        visit::walk_local(self, l, ());
+        visit::walk_local(self, l);
     }
 
-    fn visit_block(&mut self, b: &ast::Block, _: ()) {
+    fn visit_block(&mut self, b: &ast::Block) {
         run_lints!(self, check_block, b);
-        visit::walk_block(self, b, ());
+        visit::walk_block(self, b);
     }
 
-    fn visit_arm(&mut self, a: &ast::Arm, _: ()) {
+    fn visit_arm(&mut self, a: &ast::Arm) {
         run_lints!(self, check_arm, a);
-        visit::walk_arm(self, a, ());
+        visit::walk_arm(self, a);
     }
 
-    fn visit_decl(&mut self, d: &ast::Decl, _: ()) {
+    fn visit_decl(&mut self, d: &ast::Decl) {
         run_lints!(self, check_decl, d);
-        visit::walk_decl(self, d, ());
+        visit::walk_decl(self, d);
     }
 
-    fn visit_expr_post(&mut self, e: &ast::Expr, _: ()) {
+    fn visit_expr_post(&mut self, e: &ast::Expr) {
         run_lints!(self, check_expr_post, e);
     }
 
-    fn visit_generics(&mut self, g: &ast::Generics, _: ()) {
+    fn visit_generics(&mut self, g: &ast::Generics) {
         run_lints!(self, check_generics, g);
-        visit::walk_generics(self, g, ());
+        visit::walk_generics(self, g);
     }
 
-    fn visit_trait_item(&mut self, m: &ast::TraitItem, _: ()) {
+    fn visit_trait_item(&mut self, m: &ast::TraitItem) {
         run_lints!(self, check_trait_method, m);
-        visit::walk_trait_item(self, m, ());
+        visit::walk_trait_item(self, m);
     }
 
-    fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>, _: ()) {
+    fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>) {
         run_lints!(self, check_opt_lifetime_ref, sp, lt);
     }
 
-    fn visit_lifetime_ref(&mut self, lt: &ast::Lifetime, _: ()) {
+    fn visit_lifetime_ref(&mut self, lt: &ast::Lifetime) {
         run_lints!(self, check_lifetime_ref, lt);
     }
 
-    fn visit_lifetime_decl(&mut self, lt: &ast::LifetimeDef, _: ()) {
+    fn visit_lifetime_decl(&mut self, lt: &ast::LifetimeDef) {
         run_lints!(self, check_lifetime_decl, lt);
     }
 
-    fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf, _: ()) {
+    fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf) {
         run_lints!(self, check_explicit_self, es);
-        visit::walk_explicit_self(self, es, ());
+        visit::walk_explicit_self(self, es);
     }
 
-    fn visit_mac(&mut self, mac: &ast::Mac, _: ()) {
+    fn visit_mac(&mut self, mac: &ast::Mac) {
         run_lints!(self, check_mac, mac);
-        visit::walk_mac(self, mac, ());
+        visit::walk_mac(self, mac);
     }
 
-    fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId, _: ()) {
+    fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
         run_lints!(self, check_path, p, id);
-        visit::walk_path(self, p, ());
+        visit::walk_path(self, p);
     }
 
-    fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) {
+    fn visit_attribute(&mut self, attr: &ast::Attribute) {
         run_lints!(self, check_attribute, attr);
     }
 }
@@ -719,14 +718,14 @@ pub fn check_crate(tcx: &ty::ctxt,
         cx.visit_id(ast::CRATE_NODE_ID);
         cx.visit_ids(|v| {
             v.visited_outermost = true;
-            visit::walk_crate(v, krate, ());
+            visit::walk_crate(v, krate);
         });
 
         // since the root module isn't visited as an item (because it isn't an
         // item), warn for it here.
         run_lints!(cx, check_crate, krate);
 
-        visit::walk_crate(cx, krate, ());
+        visit::walk_crate(cx, krate);
     });
 
     // If we missed any lints added to the session, then there's a bug somewhere
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 321eee3d5fc..7b8c7a0ab47 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -49,19 +49,19 @@ pub fn read_crates(sess: &Session,
         next_crate_num: sess.cstore.next_crate_num(),
     };
     visit_crate(&e, krate);
-    visit::walk_crate(&mut e, krate, ());
+    visit::walk_crate(&mut e, krate);
     dump_crates(&sess.cstore);
     warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
 }
 
-impl<'a> visit::Visitor<()> for Env<'a> {
-    fn visit_view_item(&mut self, a: &ast::ViewItem, _: ()) {
+impl<'a> visit::Visitor for Env<'a> {
+    fn visit_view_item(&mut self, a: &ast::ViewItem) {
         visit_view_item(self, a);
-        visit::walk_view_item(self, a, ());
+        visit::walk_view_item(self, a);
     }
-    fn visit_item(&mut self, a: &ast::Item, _: ()) {
+    fn visit_item(&mut self, a: &ast::Item) {
         visit_item(self, a);
-        visit::walk_item(self, a, ());
+        visit::walk_item(self, a);
     }
 }
 
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index a105a56a09b..25e80b26a93 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1473,20 +1473,20 @@ struct EncodeVisitor<'a,'b:'a> {
     index: &'a mut Vec<entry<i64>>,
 }
 
-impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> {
-    fn visit_expr(&mut self, ex: &Expr, _: ()) {
-        visit::walk_expr(self, ex, ());
+impl<'a,'b> visit::Visitor for EncodeVisitor<'a,'b> {
+    fn visit_expr(&mut self, ex: &Expr) {
+        visit::walk_expr(self, ex);
         my_visit_expr(ex);
     }
-    fn visit_item(&mut self, i: &Item, _: ()) {
-        visit::walk_item(self, i, ());
+    fn visit_item(&mut self, i: &Item) {
+        visit::walk_item(self, i);
         my_visit_item(i,
                       self.rbml_w_for_visit_item,
                       self.ecx_ptr,
                       self.index);
     }
-    fn visit_foreign_item(&mut self, ni: &ForeignItem, _: ()) {
-        visit::walk_foreign_item(self, ni, ());
+    fn visit_foreign_item(&mut self, ni: &ForeignItem) {
+        visit::walk_foreign_item(self, ni);
         my_visit_foreign_item(ni,
                               self.rbml_w_for_visit_item,
                               self.ecx_ptr,
@@ -1519,7 +1519,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
         index: &mut index,
         ecx_ptr: ecx_ptr,
         rbml_w_for_visit_item: &mut *rbml_w,
-    }, krate, ());
+    }, krate);
 
     rbml_w.end_tag();
     index
@@ -1775,8 +1775,8 @@ fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &Crate) {
         rbml_w: &'a mut Encoder<'b>,
     }
 
-    impl<'a, 'b> Visitor<()> for StructFieldVisitor<'a, 'b> {
-        fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
+    impl<'a, 'b> Visitor for StructFieldVisitor<'a, 'b> {
+        fn visit_struct_field(&mut self, field: &ast::StructField) {
             self.rbml_w.start_tag(tag_struct_field);
             self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
             encode_attributes(self.rbml_w, field.node.attrs.as_slice());
@@ -1787,7 +1787,7 @@ fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &Crate) {
     rbml_w.start_tag(tag_struct_fields);
     visit::walk_crate(&mut StructFieldVisitor {
         rbml_w: rbml_w
-    }, krate, ());
+    }, krate);
     rbml_w.end_tag();
 }
 
@@ -1798,8 +1798,8 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
     rbml_w: &'a mut Encoder<'c>,
 }
 
-impl<'a, 'b, 'c, 'tcx> Visitor<()> for ImplVisitor<'a, 'b, 'c, 'tcx> {
-    fn visit_item(&mut self, item: &Item, _: ()) {
+impl<'a, 'b, 'c, 'tcx> Visitor for ImplVisitor<'a, 'b, 'c, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
         match item.node {
             ItemImpl(_, Some(ref trait_ref), _, _) => {
                 let def_map = &self.ecx.tcx.def_map;
@@ -1817,7 +1817,7 @@ impl<'a, 'b, 'c, 'tcx> Visitor<()> for ImplVisitor<'a, 'b, 'c, 'tcx> {
             }
             _ => {}
         }
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 }
 
@@ -1841,7 +1841,7 @@ fn encode_impls<'a>(ecx: &'a EncodeContext,
             ecx: ecx,
             rbml_w: rbml_w,
         };
-        visit::walk_crate(&mut visitor, krate, ());
+        visit::walk_crate(&mut visitor, krate);
     }
 
     rbml_w.end_tag();
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index 11189390df5..5910aba8116 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -26,7 +26,7 @@ use util::ppaux::{Repr};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::visit;
-use syntax::visit::{Visitor};
+use syntax::visit::Visitor;
 use syntax::ast::{Expr, FnDecl, Block, NodeId, Pat};
 
 mod lifetime;
@@ -471,8 +471,8 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> {
     bccx: &'a BorrowckCtxt<'a, 'tcx>
 }
 
-impl<'a, 'tcx> visit::Visitor<()> for StaticInitializerCtxt<'a, 'tcx> {
-    fn visit_expr(&mut self, ex: &Expr, _: ()) {
+impl<'a, 'tcx> Visitor for StaticInitializerCtxt<'a, 'tcx> {
+    fn visit_expr(&mut self, ex: &Expr) {
         match ex.node {
             ast::ExprAddrOf(mutbl, ref base) => {
                 let base_cmt = self.bccx.cat_expr(&**base);
@@ -486,7 +486,7 @@ impl<'a, 'tcx> visit::Visitor<()> for StaticInitializerCtxt<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_expr(self, ex, ());
+        visit::walk_expr(self, ex);
     }
 }
 
@@ -498,5 +498,5 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::E
         bccx: bccx
     };
 
-    sicx.visit_expr(expr, ());
+    sicx.visit_expr(expr);
 }
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 5969e7e0c42..0c61f96ada6 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -60,13 +60,13 @@ pub struct LoanDataFlowOperator;
 
 pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
 
-impl<'a, 'tcx> Visitor<()> for BorrowckCtxt<'a, 'tcx> {
+impl<'a, 'tcx> Visitor for BorrowckCtxt<'a, 'tcx> {
     fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
-                b: &Block, s: Span, n: NodeId, _: ()) {
+                b: &Block, s: Span, n: NodeId) {
         borrowck_fn(self, fk, fd, b, s, n);
     }
 
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+    fn visit_item(&mut self, item: &ast::Item) {
         borrowck_item(self, item);
     }
 }
@@ -83,7 +83,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         }
     };
 
-    visit::walk_crate(&mut bccx, krate, ());
+    visit::walk_crate(&mut bccx, krate);
 
     if tcx.sess.borrowck_stats() {
         println!("--- borrowck stats ---");
@@ -114,7 +114,7 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
             gather_loans::gather_loans_in_static_initializer(this, &*ex);
         }
         _ => {
-            visit::walk_item(this, item, ());
+            visit::walk_item(this, item);
         }
     }
 }
@@ -142,7 +142,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
     check_loans::check_loans(this, &loan_dfcx, flowed_moves,
                              all_loans.as_slice(), decl, body);
 
-    visit::walk_fn(this, fk, decl, body, sp, ());
+    visit::walk_fn(this, fk, decl, body, sp);
 }
 
 fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index a9a3d94ded8..abe5118734b 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -21,45 +21,61 @@ use syntax::{ast_util, ast_map};
 use syntax::visit::Visitor;
 use syntax::visit;
 
-pub struct CheckCrateVisitor<'a, 'tcx: 'a> {
+struct CheckCrateVisitor<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
+    in_const: bool
 }
 
-impl<'a, 'tcx> Visitor<bool> for CheckCrateVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &Item, env: bool) {
-        check_item(self, i, env);
+impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
+    fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
+        let was_const = self.in_const;
+        self.in_const = in_const;
+        f(self);
+        self.in_const = was_const;
     }
-    fn visit_pat(&mut self, p: &Pat, env: bool) {
-        check_pat(self, p, env);
+    fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
+        self.with_const(true, f);
     }
-    fn visit_expr(&mut self, ex: &Expr, env: bool) {
-        check_expr(self, ex, env);
+    fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
+        self.with_const(false, f);
+    }
+}
+
+impl<'a, 'tcx> Visitor for CheckCrateVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &Item) {
+        check_item(self, i);
+    }
+    fn visit_pat(&mut self, p: &Pat) {
+        check_pat(self, p);
+    }
+    fn visit_expr(&mut self, ex: &Expr) {
+        check_expr(self, ex);
     }
 }
 
 pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) {
-    visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx }, krate, false);
+    visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx, in_const: false }, krate);
     tcx.sess.abort_if_errors();
 }
 
-fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) {
+fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
     match it.node {
         ItemStatic(_, _, ex) => {
-            v.visit_expr(&*ex, true);
+            v.inside_const(|v| v.visit_expr(&*ex));
             check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it);
         }
         ItemEnum(ref enum_definition, _) => {
             for var in (*enum_definition).variants.iter() {
                 for ex in var.node.disr_expr.iter() {
-                    v.visit_expr(&**ex, true);
+                    v.inside_const(|v| v.visit_expr(&**ex));
                 }
             }
         }
-        _ => visit::walk_item(v, it, false)
+        _ => v.outside_const(|v| visit::walk_item(v, it))
     }
 }
 
-fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) {
+fn check_pat(v: &mut CheckCrateVisitor, p: &Pat) {
     fn is_str(e: &Expr) -> bool {
         match e.node {
             ExprBox(_, expr) => {
@@ -72,18 +88,18 @@ fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) {
         }
     }
     match p.node {
-      // Let through plain ~-string literals here
-      PatLit(ref a) => if !is_str(&**a) { v.visit_expr(&**a, true); },
-      PatRange(ref a, ref b) => {
-        if !is_str(&**a) { v.visit_expr(&**a, true); }
-        if !is_str(&**b) { v.visit_expr(&**b, true); }
-      }
-      _ => visit::walk_pat(v, p, false)
+        // Let through plain ~-string literals here
+        PatLit(ref a) => if !is_str(&**a) { v.inside_const(|v| v.visit_expr(&**a)); },
+        PatRange(ref a, ref b) => {
+            if !is_str(&**a) { v.inside_const(|v| v.visit_expr(&**a)); }
+            if !is_str(&**b) { v.inside_const(|v| v.visit_expr(&**b)); }
+        }
+        _ => v.outside_const(|v| visit::walk_pat(v, p))
     }
 }
 
-fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
-    if is_const {
+fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
+    if v.in_const {
         match e.node {
           ExprUnary(UnDeref, _) => { }
           ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
@@ -165,7 +181,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
                 }
             }
             match block.expr {
-                Some(ref expr) => check_expr(v, &**expr, true),
+                Some(ref expr) => check_expr(v, &**expr),
                 None => {}
             }
           }
@@ -195,7 +211,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
           }
         }
     }
-    visit::walk_expr(v, e, is_const);
+    visit::walk_expr(v, e);
 }
 
 struct CheckItemRecursionVisitor<'a> {
@@ -219,32 +235,32 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
         def_map: def_map,
         idstack: Vec::new()
     };
-    visitor.visit_item(it, ());
+    visitor.visit_item(it);
 }
 
-impl<'a> Visitor<()> for CheckItemRecursionVisitor<'a> {
-    fn visit_item(&mut self, it: &Item, _: ()) {
+impl<'a> Visitor for CheckItemRecursionVisitor<'a> {
+    fn visit_item(&mut self, it: &Item) {
         if self.idstack.iter().any(|x| x == &(it.id)) {
             self.sess.span_fatal(self.root_it.span, "recursive constant");
         }
         self.idstack.push(it.id);
-        visit::walk_item(self, it, ());
+        visit::walk_item(self, it);
         self.idstack.pop();
     }
 
-    fn visit_expr(&mut self, e: &Expr, _: ()) {
+    fn visit_expr(&mut self, e: &Expr) {
         match e.node {
             ExprPath(..) => {
                 match self.def_map.borrow().find(&e.id) {
                     Some(&DefStatic(def_id, _)) if
                             ast_util::is_local(def_id) => {
-                        self.visit_item(&*self.ast_map.expect_item(def_id.node), ());
+                        self.visit_item(&*self.ast_map.expect_item(def_id.node));
                     }
                     _ => ()
                 }
             },
             _ => ()
         }
-        visit::walk_expr(self, e, ());
+        visit::walk_expr(self, e);
     }
 }
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index a40294328c7..67c62262dcd 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -22,45 +22,53 @@ enum Context {
 
 struct CheckLoopVisitor<'a> {
     sess: &'a Session,
+    cx: Context
 }
 
 pub fn check_crate(sess: &Session, krate: &ast::Crate) {
-    visit::walk_crate(&mut CheckLoopVisitor { sess: sess }, krate, Normal)
+    visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate)
 }
 
-impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
-    fn visit_item(&mut self, i: &ast::Item, _cx: Context) {
-        visit::walk_item(self, i, Normal);
+impl<'a> Visitor for CheckLoopVisitor<'a> {
+    fn visit_item(&mut self, i: &ast::Item) {
+        self.with_context(Normal, |v| visit::walk_item(v, i));
     }
 
-    fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
             ast::ExprWhile(ref e, ref b, _) => {
-                self.visit_expr(&**e, cx);
-                self.visit_block(&**b, Loop);
+                self.visit_expr(&**e);
+                self.with_context(Loop, |v| v.visit_block(&**b));
             }
             ast::ExprLoop(ref b, _) => {
-                self.visit_block(&**b, Loop);
+                self.with_context(Loop, |v| v.visit_block(&**b));
             }
             ast::ExprForLoop(_, ref e, ref b, _) => {
-                self.visit_expr(&**e, cx);
-                self.visit_block(&**b, Loop);
+                self.visit_expr(&**e);
+                self.with_context(Loop, |v| v.visit_block(&**b));
             }
             ast::ExprFnBlock(_, _, ref b) |
             ast::ExprProc(_, ref b) |
             ast::ExprUnboxedFn(_, _, _, ref b) => {
-                self.visit_block(&**b, Closure);
+                self.with_context(Closure, |v| v.visit_block(&**b));
             }
-            ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
-            ast::ExprAgain(_) => self.require_loop("continue", cx, e.span),
-            _ => visit::walk_expr(self, e, cx)
+            ast::ExprBreak(_) => self.require_loop("break", e.span),
+            ast::ExprAgain(_) => self.require_loop("continue", e.span),
+            _ => visit::walk_expr(self, e)
         }
     }
 }
 
 impl<'a> CheckLoopVisitor<'a> {
-    fn require_loop(&self, name: &str, cx: Context, span: Span) {
-        match cx {
+    fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) {
+        let old_cx = self.cx;
+        self.cx = cx;
+        f(self);
+        self.cx = old_cx;
+    }
+
+    fn require_loop(&self, name: &str, span: Span) {
+        match self.cx {
             Loop => {}
             Closure => {
                 self.sess.span_err(span,
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 6676ea9851d..b0a5e7f1192 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -119,26 +119,26 @@ enum WitnessPreference {
     LeaveOutWitness
 }
 
-impl<'a, 'tcx> Visitor<()> for MatchCheckCtxt<'a, 'tcx> {
-    fn visit_expr(&mut self, ex: &Expr, _: ()) {
+impl<'a, 'tcx> Visitor for MatchCheckCtxt<'a, 'tcx> {
+    fn visit_expr(&mut self, ex: &Expr) {
         check_expr(self, ex);
     }
-    fn visit_local(&mut self, l: &Local, _: ()) {
+    fn visit_local(&mut self, l: &Local) {
         check_local(self, l);
     }
-    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, _: ()) {
+    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
         check_fn(self, fk, fd, b, s);
     }
 }
 
 pub fn check_crate(tcx: &ty::ctxt, krate: &Crate) {
     let mut cx = MatchCheckCtxt { tcx: tcx };
-    visit::walk_crate(&mut cx, krate, ());
+    visit::walk_crate(&mut cx, krate);
     tcx.sess.abort_if_errors();
 }
 
 fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
-    visit::walk_expr(cx, ex, ());
+    visit::walk_expr(cx, ex);
     match ex.node {
         ExprMatch(scrut, ref arms) => {
             // First, check legality of move bindings.
@@ -844,7 +844,7 @@ fn default(cx: &MatchCheckCtxt, r: &[Gc<Pat>]) -> Option<Vec<Gc<Pat>>> {
 }
 
 fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
-    visit::walk_local(cx, loc, ());
+    visit::walk_local(cx, loc);
 
     let name = match loc.source {
         LocalLet => "local",
@@ -872,7 +872,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
             decl: &FnDecl,
             body: &Block,
             sp: Span) {
-    visit::walk_fn(cx, kind, decl, body, sp, ());
+    visit::walk_fn(cx, kind, decl, body, sp);
     for input in decl.inputs.iter() {
         match is_refutable(cx, input.pat) {
             Some(pat) => {
@@ -1014,27 +1014,30 @@ impl<'a, 'tcx> Delegate for MutationChecker<'a, 'tcx> {
 /// because of the way rvalues are handled in the borrow check. (See issue
 /// #14587.)
 fn check_legality_of_bindings_in_at_patterns(cx: &MatchCheckCtxt, pat: &Pat) {
-    let mut visitor = AtBindingPatternVisitor {
-        cx: cx,
-    };
-    visitor.visit_pat(pat, true);
+    AtBindingPatternVisitor { cx: cx, bindings_allowed: true }.visit_pat(pat);
 }
 
 struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> {
     cx: &'a MatchCheckCtxt<'b, 'tcx>,
+    bindings_allowed: bool
 }
 
-impl<'a, 'b, 'tcx> Visitor<bool> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
-    fn visit_pat(&mut self, pat: &Pat, bindings_allowed: bool) {
-        if !bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) {
+impl<'a, 'b, 'tcx> Visitor for AtBindingPatternVisitor<'a, 'b, 'tcx> {
+    fn visit_pat(&mut self, pat: &Pat) {
+        if !self.bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) {
             self.cx.tcx.sess.span_err(pat.span,
                                       "pattern bindings are not allowed \
                                        after an `@`");
         }
 
         match pat.node {
-            PatIdent(_, _, Some(_)) => visit::walk_pat(self, pat, false),
-            _ => visit::walk_pat(self, pat, bindings_allowed),
+            PatIdent(_, _, Some(_)) => {
+                let bindings_were_allowed = self.bindings_allowed;
+                self.bindings_allowed = false;
+                visit::walk_pat(self, pat);
+                self.bindings_allowed = bindings_were_allowed;
+            }
+            _ => visit::walk_pat(self, pat),
         }
     }
 }
diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs
index f851ddbeeac..07ccfb0b27b 100644
--- a/src/librustc/middle/check_rvalues.rs
+++ b/src/librustc/middle/check_rvalues.rs
@@ -23,21 +23,20 @@ use syntax::visit;
 pub fn check_crate(tcx: &ty::ctxt,
                    krate: &ast::Crate) {
     let mut rvcx = RvalueContext { tcx: tcx };
-    visit::walk_crate(&mut rvcx, krate, ());
+    visit::walk_crate(&mut rvcx, krate);
 }
 
 struct RvalueContext<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>
 }
 
-impl<'a, 'tcx> visit::Visitor<()> for RvalueContext<'a, 'tcx> {
+impl<'a, 'tcx> visit::Visitor for RvalueContext<'a, 'tcx> {
     fn visit_fn(&mut self,
                 _: &visit::FnKind,
                 fd: &ast::FnDecl,
                 b: &ast::Block,
                 _: Span,
-                _: ast::NodeId,
-                _: ()) {
+                _: ast::NodeId) {
         let mut euv = euv::ExprUseVisitor::new(self, self.tcx);
         euv.walk_fn(fd, b);
     }
diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs
index ca58b4b6e60..c4a74abed69 100644
--- a/src/librustc/middle/check_static.rs
+++ b/src/librustc/middle/check_static.rs
@@ -27,7 +27,6 @@
 use middle::ty;
 
 use syntax::ast;
-use syntax::codemap::Span;
 use syntax::visit::Visitor;
 use syntax::visit;
 use syntax::print::pprust;
@@ -54,41 +53,42 @@ fn safe_type_for_static_mut(cx: &ty::ctxt, e: &ast::Expr) -> Option<String> {
 
 struct CheckStaticVisitor<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
+    in_const: bool
 }
 
 pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) {
-    visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx }, krate, false)
+    visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx, in_const: false }, krate)
 }
 
 impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
-    fn report_error(&self, span: Span, result: Option<String>) -> bool {
-        match result {
-            None => { false }
-            Some(msg) => {
-                self.tcx.sess.span_err(span, msg.as_slice());
-                true
-            }
-        }
+    fn with_const(&mut self, in_const: bool, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
+        let was_const = self.in_const;
+        self.in_const = in_const;
+        f(self);
+        self.in_const = was_const;
     }
 }
 
-impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
-
-    fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
+impl<'a, 'tcx> Visitor for CheckStaticVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         debug!("visit_item(item={})", pprust::item_to_string(i));
         match i.node {
             ast::ItemStatic(_, mutability, ref expr) => {
                 match mutability {
                     ast::MutImmutable => {
-                        self.visit_expr(&**expr, true);
+                        self.with_const(true, |v| v.visit_expr(&**expr));
                     }
                     ast::MutMutable => {
-                        let safe = safe_type_for_static_mut(self.tcx, &**expr);
-                        self.report_error(expr.span, safe);
+                        match safe_type_for_static_mut(self.tcx, &**expr) {
+                            Some(msg) => {
+                                self.tcx.sess.span_err(expr.span, msg.as_slice());
+                            }
+                            None => {}
+                        }
                     }
                 }
             }
-            _ => { visit::walk_item(self, i, false) }
+            _ => self.with_const(false, |v| visit::walk_item(v, i))
         }
     }
 
@@ -98,17 +98,17 @@ impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
     /// every nested expression. if the expression is not part
     /// of a static item, this method does nothing but walking
     /// down through it.
-    fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         debug!("visit_expr(expr={})", pprust::expr_to_string(e));
 
-        if !is_const {
-            return visit::walk_expr(self, e, is_const);
+        if !self.in_const {
+            return visit::walk_expr(self, e);
         }
 
         match e.node {
             ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) |
             ast::ExprBlock(..) | ast::ExprTup(..)  => {
-                visit::walk_expr(self, e, is_const);
+                visit::walk_expr(self, e);
             }
             ast::ExprAddrOf(ast::MutMutable, _) => {
                 span_err!(self.tcx.sess, e.span, E0020,
@@ -130,15 +130,14 @@ impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
                     ty::ty_struct(did, _) |
                     ty::ty_enum(did, _) => {
                         if ty::has_dtor(self.tcx, did) {
-                            self.report_error(e.span,
-                             Some("static items are not allowed to have \
-                                   destructors".to_string()));
+                            self.tcx.sess.span_err(e.span,
+                                "static items are not allowed to have destructors");
                             return;
                         }
                     }
                     _ => {}
                 }
-                visit::walk_expr(self, e, is_const);
+                visit::walk_expr(self, e);
             }
         }
     }
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 2b4b6756f9f..375678b2a61 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -268,8 +268,8 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
 
 }
 
-impl<'a, 'tcx> Visitor<()> for ConstEvalVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, t: &Ty, _: ()) {
+impl<'a, 'tcx> Visitor for ConstEvalVisitor<'a, 'tcx> {
+    fn visit_ty(&mut self, t: &Ty) {
         match t.node {
             TyFixedLengthVec(_, expr) => {
                 check::check_const_in_type(self.tcx, &*expr, ty::mk_uint());
@@ -277,10 +277,10 @@ impl<'a, 'tcx> Visitor<()> for ConstEvalVisitor<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_ty(self, t, ());
+        visit::walk_ty(self, t);
     }
 
-    fn visit_expr_post(&mut self, e: &Expr, _: ()) {
+    fn visit_expr_post(&mut self, e: &Expr) {
         self.classify(e);
     }
 }
@@ -291,7 +291,7 @@ pub fn process_crate(krate: &ast::Crate,
         tcx: tcx,
         ccache: DefIdMap::new(),
     };
-    visit::walk_crate(&mut v, krate, ());
+    visit::walk_crate(&mut v, krate);
     tcx.sess.abort_if_errors();
 }
 
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index c32f8db2380..c26acedb1b8 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -172,11 +172,11 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
             index: &'a mut NodeMap<CFGIndex>,
         }
         let mut formals = Formals { entry: entry, index: index };
-        visit::walk_fn_decl(&mut formals, decl, ());
-        impl<'a> visit::Visitor<()> for Formals<'a> {
-            fn visit_pat(&mut self, p: &ast::Pat, e: ()) {
+        visit::walk_fn_decl(&mut formals, decl);
+        impl<'a> visit::Visitor for Formals<'a> {
+            fn visit_pat(&mut self, p: &ast::Pat) {
                 self.index.insert(p.id, self.entry);
-                visit::walk_pat(self, p, e)
+                visit::walk_pat(self, p)
             }
         }
     }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index f275c818716..4684e64ed2b 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -51,10 +51,6 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     worklist: Vec<ast::NodeId>,
     tcx: &'a ty::ctxt<'tcx>,
     live_symbols: Box<HashSet<ast::NodeId>>,
-}
-
-#[deriving(Clone)]
-struct MarkSymbolVisitorContext {
     struct_has_extern_repr: bool
 }
 
@@ -65,6 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             worklist: worklist,
             tcx: tcx,
             live_symbols: box HashSet::new(),
+            struct_has_extern_repr: false
         }
     }
 
@@ -199,66 +196,64 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn visit_node(&mut self, node: &ast_map::Node) {
-        let ctxt = MarkSymbolVisitorContext {
-            struct_has_extern_repr: false
-        };
+        let had_extern_repr = self.struct_has_extern_repr;
+        self.struct_has_extern_repr = false;
         match *node {
             ast_map::NodeItem(item) => {
                 match item.node {
                     ast::ItemStruct(..) => {
-                        let has_extern_repr = item.attrs.iter().fold(false, |acc, attr| {
-                            acc || attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
-                                         .iter().any(|&x| x == attr::ReprExtern)
+                        self.struct_has_extern_repr = item.attrs.iter().any(|attr| {
+                            attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
+                                .contains(&attr::ReprExtern)
                         });
 
-                        visit::walk_item(self, &*item, MarkSymbolVisitorContext {
-                            struct_has_extern_repr: has_extern_repr,
-                            ..(ctxt)
-                        });
+                        visit::walk_item(self, &*item);
                     }
                     ast::ItemFn(..)
                     | ast::ItemEnum(..)
                     | ast::ItemTy(..)
                     | ast::ItemStatic(..) => {
-                        visit::walk_item(self, &*item, ctxt);
+                        visit::walk_item(self, &*item);
                     }
                     _ => ()
                 }
             }
             ast_map::NodeTraitItem(trait_method) => {
-                visit::walk_trait_item(self, &*trait_method, ctxt);
+                visit::walk_trait_item(self, &*trait_method);
             }
             ast_map::NodeImplItem(impl_item) => {
                 match *impl_item {
                     ast::MethodImplItem(method) => {
-                        visit::walk_block(self, &*method.pe_body(), ctxt);
+                        visit::walk_block(self, &*method.pe_body());
                     }
                 }
             }
             ast_map::NodeForeignItem(foreign_item) => {
-                visit::walk_foreign_item(self, &*foreign_item, ctxt);
+                visit::walk_foreign_item(self, &*foreign_item);
             }
             _ => ()
         }
+        self.struct_has_extern_repr = had_extern_repr;
     }
 }
 
-impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx> {
+impl<'a, 'tcx> Visitor for MarkSymbolVisitor<'a, 'tcx> {
 
-    fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident, _: &ast::Generics,
-                        _: ast::NodeId, ctxt: MarkSymbolVisitorContext) {
+    fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
+                        _: &ast::Generics, _: ast::NodeId) {
+        let has_extern_repr = self.struct_has_extern_repr;
         let live_fields = def.fields.iter().filter(|f| {
-            ctxt.struct_has_extern_repr || match f.node.kind {
+            has_extern_repr || match f.node.kind {
                 ast::NamedField(_, ast::Public) => true,
                 _ => false
             }
         });
         self.live_symbols.extend(live_fields.map(|f| f.node.id));
 
-        visit::walk_struct_def(self, def, ctxt);
+        visit::walk_struct_def(self, def);
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr, ctxt: MarkSymbolVisitorContext) {
+    fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprMethodCall(..) => {
                 self.lookup_and_handle_method(expr.id, expr.span);
@@ -272,10 +267,10 @@ impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx>
             _ => ()
         }
 
-        visit::walk_expr(self, expr, ctxt);
+        visit::walk_expr(self, expr);
     }
 
-    fn visit_pat(&mut self, pat: &ast::Pat, ctxt: MarkSymbolVisitorContext) {
+    fn visit_pat(&mut self, pat: &ast::Pat) {
         match pat.node {
             ast::PatStruct(_, ref fields, _) => {
                 self.handle_field_pattern_match(pat, fields.as_slice());
@@ -287,15 +282,15 @@ impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx>
             _ => ()
         }
 
-        visit::walk_pat(self, pat, ctxt);
+        visit::walk_pat(self, pat);
     }
 
-    fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, ctxt: MarkSymbolVisitorContext) {
+    fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
         self.lookup_and_handle_definition(&id);
-        visit::walk_path(self, path, ctxt);
+        visit::walk_path(self, path);
     }
 
-    fn visit_item(&mut self, _: &ast::Item, _: MarkSymbolVisitorContext) {
+    fn visit_item(&mut self, _: &ast::Item) {
         // Do not recurse into items. These items will be added to the
         // worklist and recursed into manually if necessary.
     }
@@ -334,8 +329,8 @@ struct LifeSeeder {
     worklist: Vec<ast::NodeId> ,
 }
 
-impl Visitor<()> for LifeSeeder {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl Visitor for LifeSeeder {
+    fn visit_item(&mut self, item: &ast::Item) {
         if has_allow_dead_code_or_lang_attr(item.attrs.as_slice()) {
             self.worklist.push(item.id);
         }
@@ -351,12 +346,12 @@ impl Visitor<()> for LifeSeeder {
             }
             _ => ()
         }
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 
     fn visit_fn(&mut self, fk: &visit::FnKind,
                 _: &ast::FnDecl, block: &ast::Block,
-                _: codemap::Span, id: ast::NodeId, _: ()) {
+                _: codemap::Span, id: ast::NodeId) {
         // Check for method here because methods are not ast::Item
         match *fk {
             visit::FkMethod(_, _, method) => {
@@ -366,7 +361,7 @@ impl Visitor<()> for LifeSeeder {
             }
             _ => ()
         }
-        visit::walk_block(self, block, ());
+        visit::walk_block(self, block);
     }
 }
 
@@ -398,7 +393,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
     let mut life_seeder = LifeSeeder {
         worklist: worklist
     };
-    visit::walk_crate(&mut life_seeder, krate, ());
+    visit::walk_crate(&mut life_seeder, krate);
 
     return life_seeder.worklist;
 }
@@ -504,25 +499,25 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for DeadVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for DeadVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         let ctor_id = get_struct_ctor_id(item);
         if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) {
             self.warn_dead_code(item.id, item.span, item.ident);
         }
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 
-    fn visit_foreign_item(&mut self, fi: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
         if !self.symbol_is_live(fi.id, None) {
             self.warn_dead_code(fi.id, fi.span, fi.ident);
         }
-        visit::walk_foreign_item(self, fi, ());
+        visit::walk_foreign_item(self, fi);
     }
 
     fn visit_fn(&mut self, fk: &visit::FnKind,
                 _: &ast::FnDecl, block: &ast::Block,
-                span: codemap::Span, id: ast::NodeId, _: ()) {
+                span: codemap::Span, id: ast::NodeId) {
         // Have to warn method here because methods are not ast::Item
         match *fk {
             visit::FkMethod(..) => {
@@ -533,22 +528,22 @@ impl<'a, 'tcx> Visitor<()> for DeadVisitor<'a, 'tcx> {
             }
             _ => ()
         }
-        visit::walk_block(self, block, ());
+        visit::walk_block(self, block);
     }
 
-    fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
+    fn visit_struct_field(&mut self, field: &ast::StructField) {
         if self.should_warn_about_field(&field.node) {
             self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
         }
 
-        visit::walk_struct_field(self, field, ());
+        visit::walk_struct_field(self, field);
     }
 
     // Overwrite so that we don't warn the trait method itself.
-    fn visit_trait_item(&mut self, trait_method: &ast::TraitItem, _: ()) {
+    fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
         match *trait_method {
             ast::ProvidedMethod(ref method) => {
-                visit::walk_block(self, &*method.pe_body(), ())
+                visit::walk_block(self, &*method.pe_body())
             }
             ast::RequiredMethod(_) => ()
         }
@@ -562,5 +557,5 @@ pub fn check_crate(tcx: &ty::ctxt,
     let live_symbols = find_live(tcx, exported_items,
                                  reachable_symbols, krate);
     let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 }
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index ec1430edcdd..7ce7a112bdc 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -86,9 +86,9 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
+impl<'a, 'tcx> Visitor for EffectCheckVisitor<'a, 'tcx> {
     fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl,
-                block: &ast::Block, span: Span, _: ast::NodeId, _:()) {
+                block: &ast::Block, span: Span, _: ast::NodeId) {
 
         let (is_item_fn, is_unsafe_fn) = match *fn_kind {
             visit::FkItemFn(_, _, fn_style, _) =>
@@ -105,12 +105,12 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
             self.unsafe_context = SafeContext
         }
 
-        visit::walk_fn(self, fn_kind, fn_decl, block, span, ());
+        visit::walk_fn(self, fn_kind, fn_decl, block, span);
 
         self.unsafe_context = old_unsafe_context
     }
 
-    fn visit_block(&mut self, block: &ast::Block, _:()) {
+    fn visit_block(&mut self, block: &ast::Block) {
         let old_unsafe_context = self.unsafe_context;
         match block.rules {
             ast::DefaultBlock => {}
@@ -136,12 +136,12 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
             }
         }
 
-        visit::walk_block(self, block, ());
+        visit::walk_block(self, block);
 
         self.unsafe_context = old_unsafe_context
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
+    fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprMethodCall(_, _, _) => {
                 let method_call = MethodCall::expr(expr.id);
@@ -193,7 +193,7 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_expr(self, expr, ());
+        visit::walk_expr(self, expr);
     }
 }
 
@@ -203,5 +203,5 @@ pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) {
         unsafe_context: SafeContext,
     };
 
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 }
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 3debdc158fe..cfa96619f19 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -41,8 +41,8 @@ struct EntryContext<'a> {
     non_main_fns: Vec<(NodeId, Span)> ,
 }
 
-impl<'a> Visitor<()> for EntryContext<'a> {
-    fn visit_item(&mut self, item: &Item, _:()) {
+impl<'a> Visitor for EntryContext<'a> {
+    fn visit_item(&mut self, item: &Item) {
         find_item(item, self);
     }
 }
@@ -72,7 +72,7 @@ pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map
         non_main_fns: Vec::new(),
     };
 
-    visit::walk_crate(&mut ctxt, krate, ());
+    visit::walk_crate(&mut ctxt, krate);
 
     configure_main(&mut ctxt);
 }
@@ -118,7 +118,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext) {
         _ => ()
     }
 
-    visit::walk_item(ctxt, item, ());
+    visit::walk_item(ctxt, item);
 }
 
 fn configure_main(this: &mut EntryContext) {
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
index df5a6b6d2a1..7f3691ba5a9 100644
--- a/src/librustc/middle/freevars.rs
+++ b/src/librustc/middle/freevars.rs
@@ -50,18 +50,21 @@ struct CollectFreevarsVisitor<'a> {
     refs: Vec<freevar_entry>,
     def_map: &'a resolve::DefMap,
     capture_mode_map: &'a mut CaptureModeMap,
+    depth: uint
 }
 
-impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
-    fn visit_item(&mut self, _: &ast::Item, _: int) {
+impl<'a> Visitor for CollectFreevarsVisitor<'a> {
+    fn visit_item(&mut self, _: &ast::Item) {
         // ignore_item
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
+    fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprProc(..) => {
                 self.capture_mode_map.insert(expr.id, CaptureByValue);
-                visit::walk_expr(self, expr, depth + 1)
+                self.depth += 1;
+                visit::walk_expr(self, expr);
+                self.depth -= 1;
             }
             ast::ExprFnBlock(_, _, _) => {
                 // NOTE(stage0): After snapshot, change to:
@@ -72,7 +75,9 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
                 //};
                 let capture_mode = CaptureByRef;
                 self.capture_mode_map.insert(expr.id, capture_mode);
-                visit::walk_expr(self, expr, depth + 1)
+                self.depth += 1;
+                visit::walk_expr(self, expr);
+                self.depth -= 1;
             }
             ast::ExprUnboxedFn(capture_clause, _, _, _) => {
                 let capture_mode = match capture_clause {
@@ -80,35 +85,33 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
                     ast::CaptureByRef => CaptureByRef,
                 };
                 self.capture_mode_map.insert(expr.id, capture_mode);
-                visit::walk_expr(self, expr, depth + 1)
+                self.depth += 1;
+                visit::walk_expr(self, expr);
+                self.depth -= 1;
             }
             ast::ExprPath(..) => {
+                let mut def = *self.def_map.borrow().find(&expr.id)
+                                                    .expect("path not found");
                 let mut i = 0;
-                match self.def_map.borrow().find(&expr.id) {
-                    None => fail!("path not found"),
-                    Some(&df) => {
-                        let mut def = df;
-                        while i < depth {
-                            match def {
-                                def::DefUpvar(_, inner, _, _) => { def = *inner; }
-                                _ => break
-                            }
-                            i += 1;
-                        }
-                        if i == depth { // Made it to end of loop
-                            let dnum = def.def_id().node;
-                            if !self.seen.contains(&dnum) {
-                                self.refs.push(freevar_entry {
-                                    def: def,
-                                    span: expr.span,
-                                });
-                                self.seen.insert(dnum);
-                            }
-                        }
+                while i < self.depth {
+                    match def {
+                        def::DefUpvar(_, inner, _, _) => { def = *inner; }
+                        _ => break
+                    }
+                    i += 1;
+                }
+                if i == self.depth { // Made it to end of loop
+                    let dnum = def.def_id().node;
+                    if !self.seen.contains(&dnum) {
+                        self.refs.push(freevar_entry {
+                            def: def,
+                            span: expr.span,
+                        });
+                        self.seen.insert(dnum);
                     }
                 }
             }
-            _ => visit::walk_expr(self, expr, depth)
+            _ => visit::walk_expr(self, expr)
         }
     }
 }
@@ -127,9 +130,10 @@ fn collect_freevars(def_map: &resolve::DefMap,
         refs: Vec::new(),
         def_map: def_map,
         capture_mode_map: &mut *capture_mode_map,
+        depth: 1
     };
 
-    v.visit_block(blk, 1);
+    v.visit_block(blk);
 
     v.refs
 }
@@ -140,14 +144,14 @@ struct AnnotateFreevarsVisitor<'a> {
     capture_mode_map: CaptureModeMap,
 }
 
-impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> {
+impl<'a> Visitor for AnnotateFreevarsVisitor<'a> {
     fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
-                blk: &ast::Block, s: Span, nid: ast::NodeId, _: ()) {
+                blk: &ast::Block, s: Span, nid: ast::NodeId) {
         let vars = collect_freevars(self.def_map,
                                     blk,
                                     &mut self.capture_mode_map);
         self.freevars.insert(nid, vars);
-        visit::walk_fn(self, fk, fd, blk, s, ());
+        visit::walk_fn(self, fk, fd, blk, s);
     }
 }
 
@@ -163,7 +167,7 @@ pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
         freevars: NodeMap::new(),
         capture_mode_map: NodeMap::new(),
     };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 
     let AnnotateFreevarsVisitor {
         freevars,
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 25a8555565c..89e1fb8ae97 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -116,8 +116,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for IntrinsicCheckingVisitor<'a, 'tcx> {
-    fn visit_expr(&mut self, expr: &ast::Expr, (): ()) {
+impl<'a, 'tcx> Visitor for IntrinsicCheckingVisitor<'a, 'tcx> {
+    fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprPath(..) => {
                 match ty::resolve_expr(self.tcx, expr) {
@@ -144,7 +144,7 @@ impl<'a, 'tcx> Visitor<()> for IntrinsicCheckingVisitor<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_expr(self, expr, ());
+        visit::walk_expr(self, expr);
     }
 }
 
@@ -153,6 +153,6 @@ pub fn check_crate(tcx: &ctxt, krate: &ast::Crate) {
         tcx: tcx,
     };
 
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 }
 
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index e8b0afa98c2..88da3abcac3 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -56,29 +56,29 @@ pub struct Context<'a, 'tcx: 'a> {
     parameter_environments: Vec<ParameterEnvironment>,
 }
 
-impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> {
-    fn visit_expr(&mut self, ex: &Expr, _: ()) {
+impl<'a, 'tcx> Visitor for Context<'a, 'tcx> {
+    fn visit_expr(&mut self, ex: &Expr) {
         check_expr(self, ex);
     }
 
     fn visit_fn(&mut self, fk: &visit::FnKind, fd: &FnDecl,
-                b: &Block, s: Span, n: NodeId, _: ()) {
+                b: &Block, s: Span, n: NodeId) {
         check_fn(self, fk, fd, b, s, n);
     }
 
-    fn visit_ty(&mut self, t: &Ty, _: ()) {
+    fn visit_ty(&mut self, t: &Ty) {
         check_ty(self, t);
     }
 
-    fn visit_item(&mut self, i: &Item, _: ()) {
+    fn visit_item(&mut self, i: &Item) {
         check_item(self, i);
     }
 
-    fn visit_pat(&mut self, p: &Pat, _: ()) {
+    fn visit_pat(&mut self, p: &Pat) {
         check_pat(self, p);
     }
 
-    fn visit_local(&mut self, l: &Local, _: ()) {
+    fn visit_local(&mut self, l: &Local) {
         check_local(self, l);
     }
 }
@@ -90,7 +90,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         struct_and_enum_bounds_checked: HashSet::new(),
         parameter_environments: Vec::new(),
     };
-    visit::walk_crate(&mut ctx, krate, ());
+    visit::walk_crate(&mut ctx, krate);
     tcx.sess.abort_if_errors();
 }
 
@@ -265,7 +265,7 @@ fn check_item(cx: &mut Context, item: &Item) {
         }
     }
 
-    visit::walk_item(cx, item, ())
+    visit::walk_item(cx, item)
 }
 
 fn check_local(cx: &mut Context, local: &Local) {
@@ -274,7 +274,7 @@ fn check_local(cx: &mut Context, local: &Local) {
         local.span,
         ty::node_id_to_type(cx.tcx, local.id));
 
-    visit::walk_local(cx, local, ())
+    visit::walk_local(cx, local)
 }
 
 // Yields the appropriate function to check the kind of closed over
@@ -361,7 +361,7 @@ fn check_fn(
             let ty = ty::node_id_to_type(cx.tcx, fn_id);
             check_bounds_on_structs_or_enums_in_type_if_possible(cx, sp, ty);
 
-            visit::walk_fn(cx, fk, decl, body, sp, ())
+            visit::walk_fn(cx, fk, decl, body, sp)
         }
         visit::FkItemFn(..) | visit::FkMethod(..) => {
             let parameter_environment = ParameterEnvironment::for_item(cx.tcx,
@@ -371,7 +371,7 @@ fn check_fn(
             let ty = ty::node_id_to_type(cx.tcx, fn_id);
             check_bounds_on_structs_or_enums_in_type_if_possible(cx, sp, ty);
 
-            visit::walk_fn(cx, fk, decl, body, sp, ());
+            visit::walk_fn(cx, fk, decl, body, sp);
             drop(cx.parameter_environments.pop());
         }
     }
@@ -451,7 +451,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
         None => {}
     }
 
-    visit::walk_expr(cx, e, ());
+    visit::walk_expr(cx, e);
 }
 
 fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) {
@@ -616,7 +616,7 @@ fn check_ty(cx: &mut Context, aty: &Ty) {
         _ => {}
     }
 
-    visit::walk_ty(cx, aty, ());
+    visit::walk_ty(cx, aty);
 }
 
 // Calls "any_missing" if any bounds were missing.
@@ -804,5 +804,5 @@ fn check_pat(cx: &mut Context, pat: &Pat) {
         None => {}
     }
 
-    visit::walk_pat(cx, pat, ());
+    visit::walk_pat(cx, pat);
 }
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 2602ec4920e..6b0eec451a4 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -115,8 +115,8 @@ struct LanguageItemCollector<'a> {
     item_refs: HashMap<&'static str, uint>,
 }
 
-impl<'a> Visitor<()> for LanguageItemCollector<'a> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a> Visitor for LanguageItemCollector<'a> {
+    fn visit_item(&mut self, item: &ast::Item) {
         match extract(item.attrs.as_slice()) {
             Some(value) => {
                 let item_index = self.item_refs.find_equiv(&value).map(|x| *x);
@@ -131,7 +131,7 @@ impl<'a> Visitor<()> for LanguageItemCollector<'a> {
             None => {}
         }
 
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 }
 
@@ -166,7 +166,7 @@ impl<'a> LanguageItemCollector<'a> {
     }
 
     pub fn collect_local_language_items(&mut self, krate: &ast::Crate) {
-        visit::walk_crate(self, krate, ());
+        visit::walk_crate(self, krate);
     }
 
     pub fn collect_external_language_items(&mut self) {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 84fc8ff2c38..121a6d80d01 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -179,18 +179,18 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for IrMaps<'a, 'tcx> {
-    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, _: ()) {
+impl<'a, 'tcx> Visitor for IrMaps<'a, 'tcx> {
+    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId) {
         visit_fn(self, fk, fd, b, s, n);
     }
-    fn visit_local(&mut self, l: &Local, _: ()) { visit_local(self, l); }
-    fn visit_expr(&mut self, ex: &Expr, _: ()) { visit_expr(self, ex); }
-    fn visit_arm(&mut self, a: &Arm, _: ()) { visit_arm(self, a); }
+    fn visit_local(&mut self, l: &Local) { visit_local(self, l); }
+    fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
+    fn visit_arm(&mut self, a: &Arm) { visit_arm(self, a); }
 }
 
 pub fn check_crate(tcx: &ty::ctxt,
                    krate: &Crate) {
-    visit::walk_crate(&mut IrMaps::new(tcx), krate, ());
+    visit::walk_crate(&mut IrMaps::new(tcx), krate);
     tcx.sess.abort_if_errors();
 }
 
@@ -343,17 +343,17 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for Liveness<'a, 'tcx> {
-    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, _: ()) {
+impl<'a, 'tcx> Visitor for Liveness<'a, 'tcx> {
+    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId) {
         check_fn(self, fk, fd, b, s, n);
     }
-    fn visit_local(&mut self, l: &Local, _: ()) {
+    fn visit_local(&mut self, l: &Local) {
         check_local(self, l);
     }
-    fn visit_expr(&mut self, ex: &Expr, _: ()) {
+    fn visit_expr(&mut self, ex: &Expr) {
         check_expr(self, ex);
     }
-    fn visit_arm(&mut self, a: &Arm, _: ()) {
+    fn visit_arm(&mut self, a: &Arm) {
         check_arm(self, a);
     }
 }
@@ -387,7 +387,7 @@ fn visit_fn(ir: &mut IrMaps,
 
     // gather up the various local variables, significant expressions,
     // and so forth:
-    visit::walk_fn(&mut fn_maps, fk, decl, body, sp, ());
+    visit::walk_fn(&mut fn_maps, fk, decl, body, sp);
 
     // Special nodes and variables:
     // - exit_ln represents the end of the fn, either by return or fail
@@ -404,7 +404,7 @@ fn visit_fn(ir: &mut IrMaps,
     let entry_ln = lsets.compute(decl, body);
 
     // check for various error conditions
-    lsets.visit_block(body, ());
+    lsets.visit_block(body);
     lsets.check_ret(id, sp, fk, entry_ln, body);
     lsets.warn_about_unused_args(decl, entry_ln);
 }
@@ -419,7 +419,7 @@ fn visit_local(ir: &mut IrMaps, local: &Local) {
           ident: name
         }));
     });
-    visit::walk_local(ir, local, ());
+    visit::walk_local(ir, local);
 }
 
 fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
@@ -435,7 +435,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
             }));
         })
     }
-    visit::walk_arm(ir, arm, ());
+    visit::walk_arm(ir, arm);
 }
 
 fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
@@ -457,7 +457,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         if moved_variable_node_id_from_def(def).is_some() {
             ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
         }
-        visit::walk_expr(ir, expr, ());
+        visit::walk_expr(ir, expr);
       }
       ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) => {
         // Interesting control flow (for loops can contain labeled
@@ -483,13 +483,13 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         });
         ir.set_captures(expr.id, call_caps);
 
-        visit::walk_expr(ir, expr, ());
+        visit::walk_expr(ir, expr);
       }
 
       // live nodes required for interesting control flow:
       ExprIf(..) | ExprMatch(..) | ExprWhile(..) | ExprLoop(..) => {
         ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
-        visit::walk_expr(ir, expr, ());
+        visit::walk_expr(ir, expr);
       }
       ExprForLoop(ref pat, _, _, _) => {
         pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
@@ -503,11 +503,11 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
             }));
         });
         ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
-        visit::walk_expr(ir, expr, ());
+        visit::walk_expr(ir, expr);
       }
       ExprBinary(op, _, _) if ast_util::lazy_binop(op) => {
         ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
-        visit::walk_expr(ir, expr, ());
+        visit::walk_expr(ir, expr);
       }
 
       // otherwise, live nodes are not required:
@@ -519,7 +519,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
       ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) |
       ExprStruct(..) | ExprRepeat(..) | ExprParen(..) |
       ExprInlineAsm(..) | ExprBox(..) => {
-          visit::walk_expr(ir, expr, ());
+          visit::walk_expr(ir, expr);
       }
     }
 }
@@ -1408,43 +1408,43 @@ fn check_local(this: &mut Liveness, local: &Local) {
         }
     }
 
-    visit::walk_local(this, local, ());
+    visit::walk_local(this, local);
 }
 
 fn check_arm(this: &mut Liveness, arm: &Arm) {
     this.arm_pats_bindings(arm.pats.as_slice(), |this, ln, var, sp, id| {
         this.warn_about_unused(sp, id, ln, var);
     });
-    visit::walk_arm(this, arm, ());
+    visit::walk_arm(this, arm);
 }
 
 fn check_expr(this: &mut Liveness, expr: &Expr) {
     match expr.node {
       ExprAssign(ref l, ref r) => {
         this.check_lvalue(&**l);
-        this.visit_expr(&**r, ());
+        this.visit_expr(&**r);
 
-        visit::walk_expr(this, expr, ());
+        visit::walk_expr(this, expr);
       }
 
       ExprAssignOp(_, ref l, _) => {
         this.check_lvalue(&**l);
 
-        visit::walk_expr(this, expr, ());
+        visit::walk_expr(this, expr);
       }
 
       ExprInlineAsm(ref ia) => {
         for &(_, ref input) in ia.inputs.iter() {
-          this.visit_expr(&**input, ());
+          this.visit_expr(&**input);
         }
 
         // Output operands must be lvalues
         for &(_, ref out, _) in ia.outputs.iter() {
           this.check_lvalue(&**out);
-          this.visit_expr(&**out, ());
+          this.visit_expr(&**out);
         }
 
-        visit::walk_expr(this, expr, ());
+        visit::walk_expr(this, expr);
       }
 
       // no correctness conditions related to liveness
@@ -1456,7 +1456,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
       ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) |
       ExprPath(..) | ExprBox(..) | ExprForLoop(..) => {
-        visit::walk_expr(this, expr, ());
+        visit::walk_expr(this, expr);
       }
     }
 }
@@ -1546,7 +1546,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
           _ => {
             // For other kinds of lvalues, no checks are required,
             // and any embedded expressions are actually rvalues
-            visit::walk_expr(self, expr, ());
+            visit::walk_expr(self, expr);
           }
        }
     }
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index cdb7d114af9..458b1dbc210 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -57,8 +57,8 @@ struct ParentVisitor {
     curparent: ast::NodeId,
 }
 
-impl Visitor<()> for ParentVisitor {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl Visitor for ParentVisitor {
+    fn visit_item(&mut self, item: &ast::Item) {
         self.parents.insert(item.id, self.curparent);
 
         let prev = self.curparent;
@@ -91,28 +91,28 @@ impl Visitor<()> for ParentVisitor {
 
             _ => {}
         }
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
         self.curparent = prev;
     }
 
-    fn visit_foreign_item(&mut self, a: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
         self.parents.insert(a.id, self.curparent);
-        visit::walk_foreign_item(self, a, ());
+        visit::walk_foreign_item(self, a);
     }
 
     fn visit_fn(&mut self, a: &visit::FnKind, b: &ast::FnDecl,
-                c: &ast::Block, d: Span, id: ast::NodeId, _: ()) {
+                c: &ast::Block, d: Span, id: ast::NodeId) {
         // We already took care of some trait methods above, otherwise things
         // like impl methods and pub trait methods are parented to the
         // containing module, not the containing trait.
         if !self.parents.contains_key(&id) {
             self.parents.insert(id, self.curparent);
         }
-        visit::walk_fn(self, a, b, c, d, ());
+        visit::walk_fn(self, a, b, c, d);
     }
 
     fn visit_struct_def(&mut self, s: &ast::StructDef, _: ast::Ident,
-                        _: &ast::Generics, n: ast::NodeId, _: ()) {
+                        _: &ast::Generics, n: ast::NodeId) {
         // Struct constructors are parented to their struct definitions because
         // they essentially are the struct definitions.
         match s.ctor_id {
@@ -125,7 +125,7 @@ impl Visitor<()> for ParentVisitor {
         for field in s.fields.iter() {
             self.parents.insert(field.node.id, self.curparent);
         }
-        visit::walk_struct_def(self, s, ())
+        visit::walk_struct_def(self, s)
     }
 }
 
@@ -180,8 +180,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for EmbargoVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for EmbargoVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         let orig_all_pub = self.prev_public;
         self.prev_public = orig_all_pub && item.vis == ast::Public;
         if self.prev_public {
@@ -323,19 +323,19 @@ impl<'a, 'tcx> Visitor<()> for EmbargoVisitor<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
 
         self.prev_exported = orig_all_exported;
         self.prev_public = orig_all_pub;
     }
 
-    fn visit_foreign_item(&mut self, a: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
         if (self.prev_exported && a.vis == ast::Public) || self.reexports.contains(&a.id) {
             self.exported_items.insert(a.id);
         }
     }
 
-    fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId, _: ()) {
+    fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId) {
         // This code is here instead of in visit_item so that the
         // crate module gets processed as well.
         if self.prev_exported {
@@ -347,7 +347,7 @@ impl<'a, 'tcx> Visitor<()> for EmbargoVisitor<'a, 'tcx> {
                 }
             }
         }
-        visit::walk_mod(self, m, ())
+        visit::walk_mod(self, m)
     }
 }
 
@@ -802,14 +802,14 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for PrivacyVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         let orig_curitem = replace(&mut self.curitem, item.id);
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
         self.curitem = orig_curitem;
     }
 
-    fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
+    fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprField(ref base, ident, _) => {
                 match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
@@ -912,10 +912,10 @@ impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_expr(self, expr, ());
+        visit::walk_expr(self, expr);
     }
 
-    fn visit_view_item(&mut self, a: &ast::ViewItem, _: ()) {
+    fn visit_view_item(&mut self, a: &ast::ViewItem) {
         match a.node {
             ast::ViewItemExternCrate(..) => {}
             ast::ViewItemUse(ref vpath) => {
@@ -949,10 +949,10 @@ impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
                 }
             }
         }
-        visit::walk_view_item(self, a, ());
+        visit::walk_view_item(self, a);
     }
 
-    fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
+    fn visit_pat(&mut self, pattern: &ast::Pat) {
         // Foreign functions do not have their patterns mapped in the def_map,
         // and there's nothing really relevant there anyway, so don't bother
         // checking privacy. If you can name the type then you can pass it to an
@@ -1012,18 +1012,18 @@ impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_pat(self, pattern, ());
+        visit::walk_pat(self, pattern);
     }
 
-    fn visit_foreign_item(&mut self, fi: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
         self.in_foreign = true;
-        visit::walk_foreign_item(self, fi, ());
+        visit::walk_foreign_item(self, fi);
         self.in_foreign = false;
     }
 
-    fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
+    fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
         self.check_path(path.span, id, path);
-        visit::walk_path(self, path, ());
+        visit::walk_path(self, path);
     }
 }
 
@@ -1036,8 +1036,8 @@ struct SanePrivacyVisitor<'a, 'tcx: 'a> {
     in_fn: bool,
 }
 
-impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for SanePrivacyVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         if self.in_fn {
             self.check_all_inherited(item);
         } else {
@@ -1049,19 +1049,19 @@ impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
             ast::ItemMod(..) => false, // modules turn privacy back on
             _ => in_fn,           // otherwise we inherit
         });
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
         self.in_fn = orig_in_fn;
     }
 
     fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
-                b: &ast::Block, s: Span, _: ast::NodeId, _: ()) {
+                b: &ast::Block, s: Span, _: ast::NodeId) {
         // This catches both functions and methods
         let orig_in_fn = replace(&mut self.in_fn, true);
-        visit::walk_fn(self, fk, fd, b, s, ());
+        visit::walk_fn(self, fk, fd, b, s);
         self.in_fn = orig_in_fn;
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
+    fn visit_view_item(&mut self, i: &ast::ViewItem) {
         match i.vis {
             ast::Inherited => {}
             ast::Public => {
@@ -1080,7 +1080,7 @@ impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
                 }
             }
         }
-        visit::walk_view_item(self, i, ());
+        visit::walk_view_item(self, i);
     }
 }
 
@@ -1264,8 +1264,8 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> Visitor<()> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
-    fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
+impl<'a, 'b, 'tcx> Visitor for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
+    fn visit_ty(&mut self, ty: &ast::Ty) {
         match ty.node {
             ast::TyPath(_, _, path_id) => {
                 if self.inner.path_is_private_type(path_id) {
@@ -1280,15 +1280,15 @@ impl<'a, 'b, 'tcx> Visitor<()> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx>
             _ => {}
         }
         self.at_outer_type = false;
-        visit::walk_ty(self, ty, ())
+        visit::walk_ty(self, ty)
     }
 
     // don't want to recurse into [, .. expr]
-    fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
+    fn visit_expr(&mut self, _: &ast::Expr) {}
 }
 
-impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for VisiblePrivateTypesVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         match item.node {
             // contents of a private mod can be reexported, so we need
             // to check internals.
@@ -1320,7 +1320,7 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                         at_outer_type: true,
                         outer_type_is_public_path: false,
                     };
-                    visitor.visit_ty(&*self_, ());
+                    visitor.visit_ty(&*self_);
                     self_contains_private = visitor.contains_private;
                     self_is_public_path = visitor.outer_type_is_public_path;
                 }
@@ -1359,16 +1359,14 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                         not_private_trait &&
                         trait_or_some_public_method {
 
-                    visit::walk_generics(self, g, ());
+                    visit::walk_generics(self, g);
 
                     match *trait_ref {
                         None => {
                             for impl_item in impl_items.iter() {
                                 match *impl_item {
                                     ast::MethodImplItem(method) => {
-                                        visit::walk_method_helper(self,
-                                                                  &*method,
-                                                                  ())
+                                        visit::walk_method_helper(self, &*method)
                                     }
                                 }
                             }
@@ -1386,7 +1384,7 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                             //
                             // Those in 2. are warned via walk_generics and this
                             // call here.
-                            visit::walk_trait_ref_helper(self, tr, ())
+                            visit::walk_trait_ref_helper(self, tr)
                         }
                     }
                 } else if trait_ref.is_none() && self_is_public_path {
@@ -1401,15 +1399,13 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                                         self.exported_items
                                             .contains(&method.id) {
                                     found_pub_static = true;
-                                    visit::walk_method_helper(self,
-                                                              &*method,
-                                                              ());
+                                    visit::walk_method_helper(self, &*method);
                                 }
                             }
                         }
                     }
                     if found_pub_static {
-                        visit::walk_generics(self, g, ())
+                        visit::walk_generics(self, g)
                     }
                 }
                 return
@@ -1429,25 +1425,24 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
         // any `visit_ty`'s will be called on things that are in
         // public signatures, i.e. things that we're interested in for
         // this visitor.
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 
-    fn visit_foreign_item(&mut self, item: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
         if self.exported_items.contains(&item.id) {
-            visit::walk_foreign_item(self, item, ())
+            visit::walk_foreign_item(self, item)
         }
     }
 
-    fn visit_fn(&mut self,
-                fk: &visit::FnKind, fd: &ast::FnDecl, b: &ast::Block, s: Span, id: ast::NodeId,
-                _: ()) {
+    fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
+                b: &ast::Block, s: Span, id: ast::NodeId) {
         // needs special handling for methods.
         if self.exported_items.contains(&id) {
-            visit::walk_fn(self, fk, fd, b, s, ());
+            visit::walk_fn(self, fk, fd, b, s);
         }
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         match t.node {
             ast::TyPath(ref p, _, path_id) => {
                 if self.path_is_private_type(path_id) {
@@ -1460,19 +1455,19 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
             }
             _ => {}
         }
-        visit::walk_ty(self, t, ())
+        visit::walk_ty(self, t)
     }
 
-    fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics, _: ()) {
+    fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
         if self.exported_items.contains(&v.node.id) {
-            visit::walk_variant(self, v, g, ());
+            visit::walk_variant(self, v, g);
         }
     }
 
-    fn visit_struct_field(&mut self, s: &ast::StructField, _: ()) {
+    fn visit_struct_field(&mut self, s: &ast::StructField) {
         match s.node.kind {
             ast::NamedField(_, ast::Public)  => {
-                visit::walk_struct_field(self, s, ());
+                visit::walk_struct_field(self, s);
             }
             _ => {}
         }
@@ -1484,9 +1479,9 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
     // things, and neither do view_items. (Making them no-ops stops us
     // from traversing the whole AST without having to be super
     // careful about our `walk_...` calls above.)
-    fn visit_view_item(&mut self, _: &ast::ViewItem, _: ()) {}
-    fn visit_block(&mut self, _: &ast::Block, _: ()) {}
-    fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
+    fn visit_view_item(&mut self, _: &ast::ViewItem) {}
+    fn visit_block(&mut self, _: &ast::Block) {}
+    fn visit_expr(&mut self, _: &ast::Expr) {}
 }
 
 pub fn check_crate(tcx: &ty::ctxt,
@@ -1499,7 +1494,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         parents: NodeMap::new(),
         curparent: ast::DUMMY_NODE_ID,
     };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 
     // Use the parent map to check the privacy of everything
     let mut visitor = PrivacyVisitor {
@@ -1510,7 +1505,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         external_exports: external_exports,
         last_private_map: last_private_map,
     };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 
     // Sanity check to make sure that all privacy usage and controls are
     // reasonable.
@@ -1518,7 +1513,7 @@ pub fn check_crate(tcx: &ty::ctxt,
         in_fn: false,
         tcx: tcx,
     };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 
     tcx.sess.abort_if_errors();
 
@@ -1535,7 +1530,7 @@ pub fn check_crate(tcx: &ty::ctxt,
     };
     loop {
         let before = visitor.exported_items.len();
-        visit::walk_crate(&mut visitor, krate, ());
+        visit::walk_crate(&mut visitor, krate);
         if before == visitor.exported_items.len() {
             break
         }
@@ -1549,7 +1544,7 @@ pub fn check_crate(tcx: &ty::ctxt,
             exported_items: &exported_items,
             public_items: &public_items
         };
-        visit::walk_crate(&mut visitor, krate, ());
+        visit::walk_crate(&mut visitor, krate);
     }
     return (exported_items, public_items);
 }
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 7ba5144985e..c27c7b3096a 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -101,9 +101,9 @@ struct ReachableContext<'a, 'tcx: 'a> {
     any_library: bool,
 }
 
-impl<'a, 'tcx> Visitor<()> for ReachableContext<'a, 'tcx> {
+impl<'a, 'tcx> Visitor for ReachableContext<'a, 'tcx> {
 
-    fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
+    fn visit_expr(&mut self, expr: &ast::Expr) {
 
         match expr.node {
             ast::ExprPath(_) => {
@@ -155,10 +155,10 @@ impl<'a, 'tcx> Visitor<()> for ReachableContext<'a, 'tcx> {
             _ => {}
         }
 
-        visit::walk_expr(self, expr, ())
+        visit::walk_expr(self, expr)
     }
 
-    fn visit_item(&mut self, _item: &ast::Item, _: ()) {
+    fn visit_item(&mut self, _item: &ast::Item) {
         // Do not recurse into items. These items will be added to the worklist
         // and recursed into manually if necessary.
     }
@@ -291,7 +291,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 match item.node {
                     ast::ItemFn(_, _, _, _, ref search_block) => {
                         if item_might_be_inlined(&*item) {
-                            visit::walk_block(self, &**search_block, ())
+                            visit::walk_block(self, &**search_block)
                         }
                     }
 
@@ -303,7 +303,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                                 item.attrs.as_slice()) {
                             self.reachable_symbols.remove(&search_item);
                         }
-                        visit::walk_expr(self, &**init, ());
+                        visit::walk_expr(self, &**init);
                     }
 
                     // These are normal, nothing reachable about these
@@ -327,7 +327,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                         // Keep going, nothing to get exported
                     }
                     ast::ProvidedMethod(ref method) => {
-                        visit::walk_block(self, &*method.pe_body(), ())
+                        visit::walk_block(self, &*method.pe_body())
                     }
                 }
             }
@@ -336,7 +336,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     ast::MethodImplItem(method) => {
                         let did = self.tcx.map.get_parent_did(search_item);
                         if method_might_be_inlined(self.tcx, &*method, did) {
-                            visit::walk_block(self, &*method.pe_body(), ())
+                            visit::walk_block(self, &*method.pe_body())
                         }
                     }
                 }
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 0db3864a06b..7de8aab371e 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -84,7 +84,6 @@ pub struct RegionMaps {
     terminating_scopes: RefCell<HashSet<ast::NodeId>>,
 }
 
-#[deriving(Clone)]
 pub struct Context {
     var_parent: Option<ast::NodeId>,
 
@@ -97,6 +96,8 @@ struct RegionResolutionVisitor<'a> {
 
     // Generated maps:
     region_maps: &'a RegionMaps,
+
+    cx: Context
 }
 
 
@@ -370,20 +371,21 @@ impl RegionMaps {
 
 /// Records the current parent (if any) as the parent of `child_id`.
 fn record_superlifetime(visitor: &mut RegionResolutionVisitor,
-                        cx: Context,
                         child_id: ast::NodeId,
                         _sp: Span) {
-    for &parent_id in cx.parent.iter() {
-        visitor.region_maps.record_encl_scope(child_id, parent_id);
+    match visitor.cx.parent {
+        Some(parent_id) => {
+            visitor.region_maps.record_encl_scope(child_id, parent_id);
+        }
+        None => {}
     }
 }
 
 /// Records the lifetime of a local variable as `cx.var_parent`
 fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
-                       cx: Context,
                        var_id: ast::NodeId,
                        _sp: Span) {
-    match cx.var_parent {
+    match visitor.cx.var_parent {
         Some(parent_id) => {
             visitor.region_maps.record_var_scope(var_id, parent_id);
         }
@@ -395,13 +397,11 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
     }
 }
 
-fn resolve_block(visitor: &mut RegionResolutionVisitor,
-                 blk: &ast::Block,
-                 cx: Context) {
+fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
     debug!("resolve_block(blk.id={})", blk.id);
 
     // Record the parent of this block.
-    record_superlifetime(visitor, cx, blk.id, blk.span);
+    record_superlifetime(visitor, blk.id, blk.span);
 
     // We treat the tail expression in the block (if any) somewhat
     // differently from the statements. The issue has to do with
@@ -412,13 +412,13 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor,
     //   }
     //
 
-    let subcx = Context {var_parent: Some(blk.id), parent: Some(blk.id)};
-    visit::walk_block(visitor, blk, subcx);
+    let prev_cx = visitor.cx;
+    visitor.cx = Context {var_parent: Some(blk.id), parent: Some(blk.id)};
+    visit::walk_block(visitor, blk);
+    visitor.cx = prev_cx;
 }
 
-fn resolve_arm(visitor: &mut RegionResolutionVisitor,
-               arm: &ast::Arm,
-               cx: Context) {
+fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
     visitor.region_maps.mark_as_terminating_scope(arm.body.id);
 
     match arm.guard {
@@ -428,48 +428,44 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor,
         None => { }
     }
 
-    visit::walk_arm(visitor, arm, cx);
+    visit::walk_arm(visitor, arm);
 }
 
-fn resolve_pat(visitor: &mut RegionResolutionVisitor,
-               pat: &ast::Pat,
-               cx: Context) {
-    record_superlifetime(visitor, cx, pat.id, pat.span);
+fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
+    record_superlifetime(visitor, pat.id, pat.span);
 
     // If this is a binding (or maybe a binding, I'm too lazy to check
     // the def map) then record the lifetime of that binding.
     match pat.node {
         ast::PatIdent(..) => {
-            record_var_lifetime(visitor, cx, pat.id, pat.span);
+            record_var_lifetime(visitor, pat.id, pat.span);
         }
         _ => { }
     }
 
-    visit::walk_pat(visitor, pat, cx);
+    visit::walk_pat(visitor, pat);
 }
 
-fn resolve_stmt(visitor: &mut RegionResolutionVisitor,
-                stmt: &ast::Stmt,
-                cx: Context) {
+fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
     let stmt_id = stmt_id(stmt);
     debug!("resolve_stmt(stmt.id={})", stmt_id);
 
     visitor.region_maps.mark_as_terminating_scope(stmt_id);
-    record_superlifetime(visitor, cx, stmt_id, stmt.span);
+    record_superlifetime(visitor, stmt_id, stmt.span);
 
-    let subcx = Context {parent: Some(stmt_id), ..cx};
-    visit::walk_stmt(visitor, stmt, subcx);
+    let prev_parent = visitor.cx.parent;
+    visitor.cx.parent = Some(stmt_id);
+    visit::walk_stmt(visitor, stmt);
+    visitor.cx.parent = prev_parent;
 }
 
-fn resolve_expr(visitor: &mut RegionResolutionVisitor,
-                expr: &ast::Expr,
-                cx: Context) {
+fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
     debug!("resolve_expr(expr.id={})", expr.id);
 
-    record_superlifetime(visitor, cx, expr.id, expr.span);
+    record_superlifetime(visitor, expr.id, expr.span);
 
-    let mut new_cx = cx;
-    new_cx.parent = Some(expr.id);
+    let prev_cx = visitor.cx;
+    visitor.cx.parent = Some(expr.id);
     match expr.node {
         // Conditional or repeating scopes are always terminating
         // scopes, meaning that temporaries cannot outlive them.
@@ -506,11 +502,11 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
 
             // The variable parent of everything inside (most importantly, the
             // pattern) is the body.
-            new_cx.var_parent = Some(body.id);
+            visitor.cx.var_parent = Some(body.id);
         }
 
         ast::ExprMatch(..) => {
-            new_cx.var_parent = Some(expr.id);
+            visitor.cx.var_parent = Some(expr.id);
         }
 
         ast::ExprAssignOp(..) | ast::ExprIndex(..) |
@@ -538,17 +534,15 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
         _ => {}
     };
 
-
-    visit::walk_expr(visitor, expr, new_cx);
+    visit::walk_expr(visitor, expr);
+    visitor.cx = prev_cx;
 }
 
-fn resolve_local(visitor: &mut RegionResolutionVisitor,
-                 local: &ast::Local,
-                 cx: Context) {
+fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
     debug!("resolve_local(local.id={},local.init={})",
            local.id,local.init.is_some());
 
-    let blk_id = match cx.var_parent {
+    let blk_id = match visitor.cx.var_parent {
         Some(id) => id,
         None => {
             visitor.sess.span_bug(
@@ -635,7 +629,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
         None => { }
     }
 
-    visit::walk_local(visitor, local, cx);
+    visit::walk_local(visitor, local);
 
     fn is_binding_pat(pat: &ast::Pat) -> bool {
         /*!
@@ -793,12 +787,12 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
     }
 }
 
-fn resolve_item(visitor: &mut RegionResolutionVisitor,
-                item: &ast::Item,
-                cx: Context) {
+fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
     // Items create a new outer block scope as far as we're concerned.
-    let new_cx = Context {var_parent: None, parent: None, ..cx};
-    visit::walk_item(visitor, item, new_cx);
+    let prev_cx = visitor.cx;
+    visitor.cx = Context {var_parent: None, parent: None};
+    visit::walk_item(visitor, item);
+    visitor.cx = prev_cx;
 }
 
 fn resolve_fn(visitor: &mut RegionResolutionVisitor,
@@ -806,8 +800,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
               decl: &ast::FnDecl,
               body: &ast::Block,
               sp: Span,
-              id: ast::NodeId,
-              cx: Context) {
+              id: ast::NodeId) {
     debug!("region::resolve_fn(id={}, \
                                span={:?}, \
                                body.id={}, \
@@ -815,20 +808,24 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
            id,
            visitor.sess.codemap().span_to_string(sp),
            body.id,
-           cx.parent);
+           visitor.cx.parent);
 
     visitor.region_maps.mark_as_terminating_scope(body.id);
 
+    let outer_cx = visitor.cx;
+
     // The arguments and `self` are parented to the body of the fn.
-    let decl_cx = Context {parent: Some(body.id),
-                           var_parent: Some(body.id)};
-    visit::walk_fn_decl(visitor, decl, decl_cx);
+    visitor.cx = Context { parent: Some(body.id),
+                           var_parent: Some(body.id) };
+    visit::walk_fn_decl(visitor, decl);
 
     // The body of the fn itself is either a root scope (top-level fn)
     // or it continues with the inherited scope (closures).
-    let body_cx = match *fk {
+    match *fk {
         visit::FkItemFn(..) | visit::FkMethod(..) => {
-            Context {parent: None, var_parent: None, ..cx}
+            visitor.cx = Context { parent: None, var_parent: None };
+            visitor.visit_block(body);
+            visitor.cx = outer_cx;
         }
         visit::FkFnBlock(..) => {
             // FIXME(#3696) -- at present we are place the closure body
@@ -838,40 +835,40 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
             // but the correct fix is a bit subtle, and I am also not sure
             // that the present approach is unsound -- it may not permit
             // any illegal programs. See issue for more details.
-            cx
+            visitor.cx = outer_cx;
+            visitor.visit_block(body);
         }
-    };
-    visitor.visit_block(body, body_cx);
+    }
 }
 
-impl<'a> Visitor<Context> for RegionResolutionVisitor<'a> {
+impl<'a> Visitor for RegionResolutionVisitor<'a> {
 
-    fn visit_block(&mut self, b: &Block, cx: Context) {
-        resolve_block(self, b, cx);
+    fn visit_block(&mut self, b: &Block) {
+        resolve_block(self, b);
     }
 
-    fn visit_item(&mut self, i: &Item, cx: Context) {
-        resolve_item(self, i, cx);
+    fn visit_item(&mut self, i: &Item) {
+        resolve_item(self, i);
     }
 
     fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
-                b: &Block, s: Span, n: NodeId, cx: Context) {
-        resolve_fn(self, fk, fd, b, s, n, cx);
+                b: &Block, s: Span, n: NodeId) {
+        resolve_fn(self, fk, fd, b, s, n);
     }
-    fn visit_arm(&mut self, a: &Arm, cx: Context) {
-        resolve_arm(self, a, cx);
+    fn visit_arm(&mut self, a: &Arm) {
+        resolve_arm(self, a);
     }
-    fn visit_pat(&mut self, p: &Pat, cx: Context) {
-        resolve_pat(self, p, cx);
+    fn visit_pat(&mut self, p: &Pat) {
+        resolve_pat(self, p);
     }
-    fn visit_stmt(&mut self, s: &Stmt, cx: Context) {
-        resolve_stmt(self, s, cx);
+    fn visit_stmt(&mut self, s: &Stmt) {
+        resolve_stmt(self, s);
     }
-    fn visit_expr(&mut self, ex: &Expr, cx: Context) {
-        resolve_expr(self, ex, cx);
+    fn visit_expr(&mut self, ex: &Expr) {
+        resolve_expr(self, ex);
     }
-    fn visit_local(&mut self, l: &Local, cx: Context) {
-        resolve_local(self, l, cx);
+    fn visit_local(&mut self, l: &Local) {
+        resolve_local(self, l);
     }
 }
 
@@ -886,10 +883,10 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
     {
         let mut visitor = RegionResolutionVisitor {
             sess: sess,
-            region_maps: &maps
+            region_maps: &maps,
+            cx: Context { parent: None, var_parent: None }
         };
-        let cx = Context { parent: None, var_parent: None };
-        visit::walk_crate(&mut visitor, krate, cx);
+        visit::walk_crate(&mut visitor, krate);
     }
     return maps;
 }
@@ -897,12 +894,11 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
 pub fn resolve_inlined_item(sess: &Session,
                             region_maps: &RegionMaps,
                             item: &ast::InlinedItem) {
-    let cx = Context {parent: None,
-                      var_parent: None};
     let mut visitor = RegionResolutionVisitor {
         sess: sess,
         region_maps: region_maps,
+        cx: Context { parent: None, var_parent: None }
     };
-    visit::walk_inlined_item(&mut visitor, item, cx);
+    visit::walk_inlined_item(&mut visitor, item);
 }
 
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 854b8b9ba77..b79db38e129 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -185,23 +185,23 @@ enum NameDefinition {
     ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
 }
 
-impl<'a> Visitor<()> for Resolver<'a> {
-    fn visit_item(&mut self, item: &Item, _: ()) {
+impl<'a> Visitor for Resolver<'a> {
+    fn visit_item(&mut self, item: &Item) {
         self.resolve_item(item);
     }
-    fn visit_arm(&mut self, arm: &Arm, _: ()) {
+    fn visit_arm(&mut self, arm: &Arm) {
         self.resolve_arm(arm);
     }
-    fn visit_block(&mut self, block: &Block, _: ()) {
+    fn visit_block(&mut self, block: &Block) {
         self.resolve_block(block);
     }
-    fn visit_expr(&mut self, expr: &Expr, _: ()) {
+    fn visit_expr(&mut self, expr: &Expr) {
         self.resolve_expr(expr);
     }
-    fn visit_local(&mut self, local: &Local, _: ()) {
+    fn visit_local(&mut self, local: &Local) {
         self.resolve_local(local);
     }
-    fn visit_ty(&mut self, ty: &Ty, _: ()) {
+    fn visit_ty(&mut self, ty: &Ty) {
         self.resolve_type(ty);
     }
 }
@@ -903,32 +903,40 @@ struct Resolver<'a> {
 
 struct BuildReducedGraphVisitor<'a, 'b:'a> {
     resolver: &'a mut Resolver<'b>,
+    parent: ReducedGraphParent
 }
 
-impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
+impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
 
-    fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
-        let p = self.resolver.build_reduced_graph_for_item(item, context);
-        visit::walk_item(self, item, p);
+    fn visit_item(&mut self, item: &Item) {
+        let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
+        let old_parent = replace(&mut self.parent, p);
+        visit::walk_item(self, item);
+        self.parent = old_parent;
     }
 
-    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
-                          context: ReducedGraphParent) {
+    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
+        let parent = self.parent.clone();
         self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
-                                                           context.clone(),
+                                                           parent.clone(),
                                                            |r| {
-            let mut v = BuildReducedGraphVisitor{ resolver: r };
-            visit::walk_foreign_item(&mut v, foreign_item, context.clone());
+            let mut v = BuildReducedGraphVisitor {
+                resolver: r,
+                parent: parent.clone()
+            };
+            visit::walk_foreign_item(&mut v, foreign_item);
         })
     }
 
-    fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
-        self.resolver.build_reduced_graph_for_view_item(view_item, context);
+    fn visit_view_item(&mut self, view_item: &ViewItem) {
+        self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
     }
 
-    fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
-        let np = self.resolver.build_reduced_graph_for_block(block, context);
-        visit::walk_block(self, block, np);
+    fn visit_block(&mut self, block: &Block) {
+        let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
+        let old_parent = replace(&mut self.parent, np);
+        visit::walk_block(self, block);
+        self.parent = old_parent;
     }
 
 }
@@ -937,10 +945,10 @@ struct UnusedImportCheckVisitor<'a, 'b:'a> {
     resolver: &'a mut Resolver<'b>
 }
 
-impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
-    fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
+impl<'a, 'b> Visitor for UnusedImportCheckVisitor<'a, 'b> {
+    fn visit_view_item(&mut self, vi: &ViewItem) {
         self.resolver.check_for_item_unused_imports(vi);
-        visit::walk_view_item(self, vi, ());
+        visit::walk_view_item(self, vi);
     }
 }
 
@@ -1019,11 +1027,12 @@ impl<'a> Resolver<'a> {
 
     /// Constructs the reduced graph for the entire crate.
     fn build_reduced_graph(&mut self, krate: &ast::Crate) {
-        let initial_parent =
-            ModuleReducedGraphParent(self.graph_root.get_module());
-
-        let mut visitor = BuildReducedGraphVisitor { resolver: self, };
-        visit::walk_crate(&mut visitor, krate, initial_parent);
+        let parent = ModuleReducedGraphParent(self.graph_root.get_module());
+        let mut visitor = BuildReducedGraphVisitor {
+            resolver: self,
+            parent: parent
+        };
+        visit::walk_crate(&mut visitor, krate);
     }
 
     /**
@@ -3889,7 +3898,7 @@ impl<'a> Resolver<'a> {
     fn resolve_crate(&mut self, krate: &ast::Crate) {
         debug!("(resolving crate) starting");
 
-        visit::walk_crate(self, krate, ());
+        visit::walk_crate(self, krate);
     }
 
     fn resolve_item(&mut self, item: &Item) {
@@ -3921,7 +3930,7 @@ impl<'a> Resolver<'a> {
                                              |this| {
                     this.resolve_type_parameters(&generics.ty_params);
                     this.resolve_where_clause(&generics.where_clause);
-                    visit::walk_item(this, item, ());
+                    visit::walk_item(this, item);
                 });
             }
 
@@ -3932,7 +3941,7 @@ impl<'a> Resolver<'a> {
                                                                ItemRibKind),
                                              |this| {
                     this.resolve_type_parameters(&generics.ty_params);
-                    visit::walk_item(this, item, ());
+                    visit::walk_item(this, item);
                 });
             }
 
@@ -4048,13 +4057,11 @@ impl<'a> Resolver<'a> {
                                         generics, FnSpace, foreign_item.id,
                                         ItemRibKind),
                                     |this| visit::walk_foreign_item(this,
-                                                                &**foreign_item,
-                                                                ()));
+                                                                    &**foreign_item));
                             }
                             ForeignItemStatic(..) => {
                                 visit::walk_foreign_item(this,
-                                                         &**foreign_item,
-                                                         ());
+                                                         &**foreign_item);
                             }
                         }
                     }
@@ -4074,7 +4081,7 @@ impl<'a> Resolver<'a> {
 
             ItemStatic(..) => {
                 self.with_constant_rib(|this| {
-                    visit::walk_item(this, item, ());
+                    visit::walk_item(this, item);
                 });
             }
 
@@ -4489,7 +4496,7 @@ impl<'a> Resolver<'a> {
                       _name: Ident, id: NodeId) {
         // Write the implementations in scope into the module metadata.
         debug!("(resolving module) resolving module ID {}", id);
-        visit::walk_mod(self, module, ());
+        visit::walk_mod(self, module);
     }
 
     fn resolve_local(&mut self, local: &Local) {
@@ -4586,7 +4593,7 @@ impl<'a> Resolver<'a> {
         // pat_idents are variants
         self.check_consistent_bindings(arm);
 
-        visit::walk_expr_opt(self, arm.guard, ());
+        visit::walk_expr_opt(self, arm.guard);
         self.resolve_expr(&*arm.body);
 
         self.value_ribs.borrow_mut().pop();
@@ -4608,7 +4615,7 @@ impl<'a> Resolver<'a> {
         }
 
         // Descend into the block.
-        visit::walk_block(self, block, ());
+        visit::walk_block(self, block);
 
         // Move back up.
         self.current_module = orig_module;
@@ -4702,12 +4709,12 @@ impl<'a> Resolver<'a> {
             TyClosure(c) | TyProc(c) => {
                 self.resolve_type_parameter_bounds(ty.id, &c.bounds,
                                                    TraitBoundingTypeParameter);
-                visit::walk_ty(self, ty, ());
+                visit::walk_ty(self, ty);
             }
 
             _ => {
                 // Just resolve embedded types.
-                visit::walk_ty(self, ty, ());
+                visit::walk_ty(self, ty);
             }
         }
     }
@@ -5592,7 +5599,7 @@ impl<'a> Resolver<'a> {
                     }
                 }
 
-                visit::walk_expr(self, expr, ());
+                visit::walk_expr(self, expr);
             }
 
             ExprFnBlock(_, fn_decl, block) |
@@ -5618,7 +5625,7 @@ impl<'a> Resolver<'a> {
                     }
                 }
 
-                visit::walk_expr(self, expr, ());
+                visit::walk_expr(self, expr);
             }
 
             ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
@@ -5633,7 +5640,7 @@ impl<'a> Resolver<'a> {
                         rib.bindings.borrow_mut().insert(renamed, def_like);
                     }
 
-                    visit::walk_expr(this, expr, ());
+                    visit::walk_expr(this, expr);
                 })
             }
 
@@ -5697,7 +5704,7 @@ impl<'a> Resolver<'a> {
             }
 
             _ => {
-                visit::walk_expr(self, expr, ());
+                visit::walk_expr(self, expr);
             }
         }
     }
@@ -5847,7 +5854,7 @@ impl<'a> Resolver<'a> {
 
     fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
         let mut visitor = UnusedImportCheckVisitor{ resolver: self };
-        visit::walk_crate(&mut visitor, krate, ());
+        visit::walk_crate(&mut visitor, krate);
     }
 
     fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 1bc37e2f1e4..628174b0f4e 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -52,7 +52,8 @@ fn lifetime_show(lt_name: &ast::Name) -> token::InternedString {
 
 struct LifetimeContext<'a> {
     sess: &'a Session,
-    named_region_map: NamedRegionMap,
+    named_region_map: &'a mut NamedRegionMap,
+    scope: Scope<'a>
 }
 
 enum ScopeChain<'a> {
@@ -70,117 +71,107 @@ enum ScopeChain<'a> {
 
 type Scope<'a> = &'a ScopeChain<'a>;
 
+static ROOT_SCOPE: ScopeChain<'static> = RootScope;
+
 pub fn krate(sess: &Session, krate: &ast::Crate) -> NamedRegionMap {
-    let mut ctxt = LifetimeContext {
+    let mut named_region_map = NodeMap::new();
+    visit::walk_crate(&mut LifetimeContext {
         sess: sess,
-        named_region_map: NodeMap::new()
-    };
-    visit::walk_crate(&mut ctxt, krate, &RootScope);
+        named_region_map: &mut named_region_map,
+        scope: &ROOT_SCOPE
+    }, krate);
     sess.abort_if_errors();
-    ctxt.named_region_map
+    named_region_map
 }
 
-impl<'a, 'b> Visitor<Scope<'a>> for LifetimeContext<'b> {
-    fn visit_item(&mut self,
-                  item: &ast::Item,
-                  _: Scope<'a>) {
-        let root = RootScope;
-        let scope = match item.node {
+impl<'a> Visitor for LifetimeContext<'a> {
+    fn visit_item(&mut self, item: &ast::Item) {
+        let lifetimes = match item.node {
             ast::ItemFn(..) | // fn lifetimes get added in visit_fn below
             ast::ItemMod(..) |
             ast::ItemMac(..) |
             ast::ItemForeignMod(..) |
             ast::ItemStatic(..) => {
-                RootScope
+                self.with(|_, f| f(RootScope), |v| visit::walk_item(v, item));
+                return;
             }
             ast::ItemTy(_, ref generics) |
             ast::ItemEnum(_, ref generics) |
             ast::ItemStruct(_, ref generics) |
             ast::ItemImpl(ref generics, _, _, _) |
-            ast::ItemTrait(ref generics, _, _, _) => {
-                let scope: ScopeChain =
-                    EarlyScope(subst::TypeSpace, &generics.lifetimes, &root);
-                self.check_lifetime_defs(&generics.lifetimes, &scope);
-                scope
-            }
+            ast::ItemTrait(ref generics, _, _, _) => &generics.lifetimes
         };
-        debug!("entering scope {:?}", scope);
-        visit::walk_item(self, item, &scope);
-        debug!("exiting scope {:?}", scope);
+
+        self.with(|_, f| f(EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE)), |v| {
+            debug!("entering scope {:?}", v.scope);
+            v.check_lifetime_defs(lifetimes);
+            visit::walk_item(v, item);
+            debug!("exiting scope {:?}", v.scope);
+        });
     }
 
     fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
-                b: &ast::Block, s: Span, n: ast::NodeId,
-                scope: Scope<'a>) {
+                b: &ast::Block, s: Span, n: ast::NodeId) {
         match *fk {
             visit::FkItemFn(_, generics, _, _) |
             visit::FkMethod(_, generics, _) => {
-                self.visit_fn_decl(
-                    n, generics, scope,
-                    |this, scope1| visit::walk_fn(this, fk, fd, b, s, scope1))
+                self.visit_fn_decl(n, generics, |v| visit::walk_fn(v, fk, fd, b, s))
             }
             visit::FkFnBlock(..) => {
-                visit::walk_fn(self, fk, fd, b, s, scope)
+                visit::walk_fn(self, fk, fd, b, s)
             }
         }
     }
 
-    fn visit_ty(&mut self, ty: &ast::Ty, scope: Scope<'a>) {
-        match ty.node {
-            ast::TyClosure(c) | ast::TyProc(c) => {
-                push_fn_scope(self, ty, scope, &c.lifetimes);
-            }
-            ast::TyBareFn(c) => push_fn_scope(self, ty, scope, &c.lifetimes),
-            _ => visit::walk_ty(self, ty, scope),
-        }
+    fn visit_ty(&mut self, ty: &ast::Ty) {
+        let lifetimes = match ty.node {
+            ast::TyClosure(ref c) | ast::TyProc(ref c) => &c.lifetimes,
+            ast::TyBareFn(ref c) => &c.lifetimes,
+            _ => return visit::walk_ty(self, ty)
+        };
 
-        fn push_fn_scope(this: &mut LifetimeContext,
-                         ty: &ast::Ty,
-                         scope: Scope,
-                         lifetimes: &Vec<ast::LifetimeDef>) {
-            let scope1: ScopeChain = LateScope(ty.id, lifetimes, scope);
-            this.check_lifetime_defs(lifetimes, &scope1);
+        self.with(|scope, f| f(LateScope(ty.id, lifetimes, scope)), |v| {
+            v.check_lifetime_defs(lifetimes);
             debug!("pushing fn scope id={} due to type", ty.id);
-            visit::walk_ty(this, ty, &scope1);
+            visit::walk_ty(v, ty);
             debug!("popping fn scope id={} due to type", ty.id);
-        }
+        });
     }
 
-    fn visit_ty_method(&mut self,
-                       m: &ast::TypeMethod,
-                       scope: Scope<'a>) {
-        self.visit_fn_decl(
-            m.id, &m.generics, scope,
-            |this, scope1| visit::walk_ty_method(this, m, scope1))
+    fn visit_ty_method(&mut self, m: &ast::TypeMethod) {
+        self.visit_fn_decl(m.id, &m.generics, |v| visit::walk_ty_method(v, m))
     }
 
-    fn visit_block(&mut self,
-                   b: &ast::Block,
-                   scope: Scope<'a>) {
-        let scope1 = BlockScope(b.id, scope);
+    fn visit_block(&mut self, b: &ast::Block) {
         debug!("pushing block scope {}", b.id);
-        visit::walk_block(self, b, &scope1);
+        self.with(|scope, f| f(BlockScope(b.id, scope)), |v| visit::walk_block(v, b));
         debug!("popping block scope {}", b.id);
     }
 
-    fn visit_lifetime_ref(&mut self,
-                          lifetime_ref: &ast::Lifetime,
-                          scope: Scope<'a>) {
+    fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
         if lifetime_ref.name == special_idents::static_lifetime.name {
             self.insert_lifetime(lifetime_ref, DefStaticRegion);
             return;
         }
-        self.resolve_lifetime_ref(lifetime_ref, scope);
+        self.resolve_lifetime_ref(lifetime_ref);
     }
 }
 
 impl<'a> LifetimeContext<'a> {
+    fn with(&mut self, wrap_scope: |Scope, |ScopeChain||, f: |&mut LifetimeContext|) {
+        let LifetimeContext { sess, ref mut named_region_map, scope} = *self;
+        wrap_scope(scope, |scope1| f(&mut LifetimeContext {
+            sess: sess,
+            named_region_map: *named_region_map,
+            scope: &scope1
+        }))
+    }
+
     /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
     fn visit_fn_decl(&mut self,
                      n: ast::NodeId,
                      generics: &ast::Generics,
-                     scope: Scope,
-                     walk: |&mut LifetimeContext, Scope|) {
+                     walk: |&mut LifetimeContext|) {
         /*!
          * Handles visiting fns and methods. These are a bit
          * complicated because we must distinguish early- vs late-bound
@@ -210,25 +201,27 @@ impl<'a> LifetimeContext<'a> {
                referenced_idents={:?}",
                n,
                referenced_idents.iter().map(lifetime_show).collect::<Vec<token::InternedString>>());
+        let lifetimes = &generics.lifetimes;
         if referenced_idents.is_empty() {
-            let scope1: ScopeChain = LateScope(n, &generics.lifetimes, scope);
-            self.check_lifetime_defs(&generics.lifetimes, &scope1);
-            walk(self, &scope1);
+            self.with(|scope, f| f(LateScope(n, lifetimes, scope)), |v| {
+                v.check_lifetime_defs(lifetimes);
+                walk(v);
+            });
         } else {
-            let (early, late) = generics.lifetimes.clone().partition(
+            let (early, late) = lifetimes.clone().partition(
                 |l| referenced_idents.iter().any(|&i| i == l.lifetime.name));
 
-            let scope1 = EarlyScope(subst::FnSpace, &early, scope);
-            let scope2: ScopeChain = LateScope(n, &late, &scope1);
-            self.check_lifetime_defs(&generics.lifetimes, &scope2);
-            walk(self, &scope2);
+            self.with(|scope, f| f(EarlyScope(subst::FnSpace, &early, scope)), |v| {
+                v.with(|scope1, f| f(LateScope(n, &late, scope1)), |v| {
+                    v.check_lifetime_defs(lifetimes);
+                    walk(v);
+                });
+            });
         }
         debug!("popping fn scope id={} due to fn item/method", n);
     }
 
-    fn resolve_lifetime_ref(&mut self,
-                            lifetime_ref: &ast::Lifetime,
-                            scope: Scope) {
+    fn resolve_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
         // Walk up the scope chain, tracking the number of fn scopes
         // that we pass through, until we find a lifetime with the
         // given name or we run out of scopes. If we encounter a code
@@ -236,7 +229,7 @@ impl<'a> LifetimeContext<'a> {
         // over to `resolve_free_lifetime_ref()` to complete the
         // search.
         let mut depth = 0;
-        let mut scope = scope;
+        let mut scope = self.scope;
         loop {
             match *scope {
                 BlockScope(id, s) => {
@@ -326,17 +319,14 @@ impl<'a> LifetimeContext<'a> {
 
     }
 
-    fn unresolved_lifetime_ref(&self,
-                               lifetime_ref: &ast::Lifetime) {
+    fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
         self.sess.span_err(
             lifetime_ref.span,
             format!("use of undeclared lifetime name `{}`",
                     token::get_name(lifetime_ref.name)).as_slice());
     }
 
-    fn check_lifetime_defs<'b>(&mut self,
-                               lifetimes: &Vec<ast::LifetimeDef>,
-                               scope: Scope<'b>) {
+    fn check_lifetime_defs(&mut self, lifetimes: &Vec<ast::LifetimeDef>) {
         for i in range(0, lifetimes.len()) {
             let lifetime_i = lifetimes.get(i);
 
@@ -365,7 +355,7 @@ impl<'a> LifetimeContext<'a> {
             }
 
             for bound in lifetime_i.bounds.iter() {
-                self.resolve_lifetime_ref(bound, scope);
+                self.resolve_lifetime_ref(bound);
             }
         }
     }
@@ -434,10 +424,10 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
             FreeLifetimeCollector { early_bound: &mut early_bound,
                                     late_bound: &mut late_bound };
         for ty_param in generics.ty_params.iter() {
-            visit::walk_ty_param_bounds(&mut collector, &ty_param.bounds, ());
+            visit::walk_ty_param_bounds(&mut collector, &ty_param.bounds);
         }
         for predicate in generics.where_clause.predicates.iter() {
-            visit::walk_ty_param_bounds(&mut collector, &predicate.bounds, ());
+            visit::walk_ty_param_bounds(&mut collector, &predicate.bounds);
         }
     }
 
@@ -460,10 +450,8 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
         late_bound: &'a mut Vec<ast::Name>,
     }
 
-    impl<'a> Visitor<()> for FreeLifetimeCollector<'a> {
-        fn visit_lifetime_ref(&mut self,
-                              lifetime_ref: &ast::Lifetime,
-                              _: ()) {
+    impl<'a> Visitor for FreeLifetimeCollector<'a> {
+        fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
             shuffle(self.early_bound, self.late_bound,
                     lifetime_ref.name);
         }
diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs
index 7350413643c..d7be7af3d07 100644
--- a/src/librustc/middle/save/mod.rs
+++ b/src/librustc/middle/save/mod.rs
@@ -83,9 +83,18 @@ struct DxrVisitor<'l, 'tcx: 'l> {
 
     span: SpanUtils<'l>,
     fmt: FmtStrs<'l>,
+
+    cur_scope: NodeId
 }
 
 impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
+    fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
+        let parent_scope = self.cur_scope;
+        self.cur_scope = scope_id;
+        f(self);
+        self.cur_scope = parent_scope;
+    }
+
     fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
         // the current crate
         self.fmt.crate_str(krate.span, name);
@@ -136,19 +145,19 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         result
     }
 
-    fn write_sub_paths(&mut self, path: &ast::Path, scope_id: NodeId) {
+    fn write_sub_paths(&mut self, path: &ast::Path) {
         let sub_paths = self.process_path_prefixes(path);
         for &(ref span, ref qualname) in sub_paths.iter() {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
                                      qualname.as_slice(),
-                                     scope_id);
+                                     self.cur_scope);
         }
     }
 
     // As write_sub_paths, but does not process the last ident in the path (assuming it
     // will be processed elsewhere).
-    fn write_sub_paths_truncated(&mut self, path: &ast::Path, scope_id: NodeId) {
+    fn write_sub_paths_truncated(&mut self, path: &ast::Path) {
         let sub_paths = self.process_path_prefixes(path);
         let len = sub_paths.len();
         if len <= 1 {
@@ -160,13 +169,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
                                      qualname.as_slice(),
-                                     scope_id);
+                                     self.cur_scope);
         }
     }
 
     // As write_sub_paths, but expects a path of the form module_path::trait::method
     // Where trait could actually be a struct too.
-    fn write_sub_path_trait_truncated(&mut self, path: &ast::Path, scope_id: NodeId) {
+    fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
         let sub_paths = self.process_path_prefixes(path);
         let len = sub_paths.len();
         if len <= 1 {
@@ -189,7 +198,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
                                      qualname.as_slice(),
-                                     scope_id);
+                                     self.cur_scope);
         }
     }
 
@@ -243,11 +252,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisitorEnv) {
+    fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str) {
         for arg in formals.iter() {
             assert!(self.collected_paths.len() == 0 && !self.collecting);
             self.collecting = true;
-            self.visit_pat(&*arg.pat, e);
+            self.visit_pat(&*arg.pat);
             self.collecting = false;
             let span_utils = self.span;
             for &(id, ref p, _, _) in self.collected_paths.iter() {
@@ -266,7 +275,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
+    fn process_method(&mut self, method: &ast::Method) {
         if generated_code(method.span) {
             return;
         }
@@ -361,27 +370,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             decl_id,
                             scope_id);
 
-        self.process_formals(&method.pe_fn_decl().inputs, qualname, e);
+        self.process_formals(&method.pe_fn_decl().inputs, qualname);
 
         // walk arg and return types
         for arg in method.pe_fn_decl().inputs.iter() {
-            self.visit_ty(&*arg.ty, e);
+            self.visit_ty(&*arg.ty);
         }
-        self.visit_ty(&*method.pe_fn_decl().output, e);
+        self.visit_ty(&*method.pe_fn_decl().output);
         // walk the fn body
-        self.visit_block(&*method.pe_body(),
-                         DxrVisitorEnv::new_nested(method.id));
+        self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
 
         self.process_generic_params(method.pe_generics(),
                                     method.span,
                                     qualname,
-                                    method.id,
-                                    e);
+                                    method.id);
     }
 
     fn process_trait_ref(&mut self,
                          trait_ref: &ast::TraitRef,
-                         e: DxrVisitorEnv,
                          impl_id: Option<NodeId>) {
         match self.lookup_type_ref(trait_ref.ref_id) {
             Some(id) => {
@@ -390,16 +396,16 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                  trait_ref.path.span,
                                  sub_span,
                                  id,
-                                 e.cur_scope);
+                                 self.cur_scope);
                 match impl_id {
                     Some(impl_id) => self.fmt.impl_str(trait_ref.path.span,
                                                        sub_span,
                                                        impl_id,
                                                        id,
-                                                       e.cur_scope),
+                                                       self.cur_scope),
                     None => (),
                 }
-                visit::walk_path(self, &trait_ref.path, e);
+                visit::walk_path(self, &trait_ref.path);
             },
             None => ()
         }
@@ -436,8 +442,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
     fn process_generic_params(&mut self, generics:&ast::Generics,
                               full_span: Span,
                               prefix: &str,
-                              id: NodeId,
-                              e: DxrVisitorEnv) {
+                              id: NodeId) {
         // We can't only use visit_generics since we don't have spans for param
         // bindings, so we reparse the full_span to get those sub spans.
         // However full span is the entire enum/fn/struct block, so we only want
@@ -456,12 +461,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                  name.as_slice(),
                                  "");
         }
-        self.visit_generics(generics, e);
+        self.visit_generics(generics);
     }
 
     fn process_fn(&mut self,
                   item: &ast::Item,
-                  e: DxrVisitorEnv,
                   decl: ast::P<ast::FnDecl>,
                   ty_params: &ast::Generics,
                   body: ast::P<ast::Block>) {
@@ -472,25 +476,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                         sub_span,
                         item.id,
                         qualname.as_slice(),
-                        e.cur_scope);
+                        self.cur_scope);
 
-        self.process_formals(&decl.inputs, qualname.as_slice(), e);
+        self.process_formals(&decl.inputs, qualname.as_slice());
 
         // walk arg and return types
         for arg in decl.inputs.iter() {
-            self.visit_ty(&*arg.ty, e);
+            self.visit_ty(&*arg.ty);
         }
-        self.visit_ty(&*decl.output, e);
+        self.visit_ty(&*decl.output);
 
         // walk the body
-        self.visit_block(&*body, DxrVisitorEnv::new_nested(item.id));
+        self.nest(item.id, |v| v.visit_block(&*body));
 
-        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
     }
 
     fn process_static(&mut self,
                       item: &ast::Item,
-                      e: DxrVisitorEnv,
                       typ: ast::P<ast::Ty>,
                       mt: ast::Mutability,
                       expr: &ast::Expr)
@@ -511,16 +514,15 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             qualname.as_slice(),
                             value.as_slice(),
                             ty_to_string(&*typ).as_slice(),
-                            e.cur_scope);
+                            self.cur_scope);
 
         // walk type and init value
-        self.visit_ty(&*typ, e);
-        self.visit_expr(expr, e);
+        self.visit_ty(&*typ);
+        self.visit_expr(expr);
     }
 
     fn process_struct(&mut self,
                       item: &ast::Item,
-                      e: DxrVisitorEnv,
                       def: &ast::StructDef,
                       ty_params: &ast::Generics) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@@ -535,20 +537,19 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             item.id,
                             ctor_id,
                             qualname.as_slice(),
-                            e.cur_scope);
+                            self.cur_scope);
 
         // fields
         for field in def.fields.iter() {
             self.process_struct_field_def(field, qualname.as_slice(), item.id);
-            self.visit_ty(&*field.node.ty, e);
+            self.visit_ty(&*field.node.ty);
         }
 
-        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
     }
 
     fn process_enum(&mut self,
                     item: &ast::Item,
-                    e: DxrVisitorEnv,
                     enum_definition: &ast::EnumDef,
                     ty_params: &ast::Generics) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@@ -557,7 +558,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                 Some(sub_span),
                                                 item.id,
                                                 qualname.as_slice(),
-                                                e.cur_scope),
+                                                self.cur_scope),
             None => self.sess.span_bug(item.span,
                                        format!("Could not find subspan for enum {}",
                                                qualname).as_slice()),
@@ -578,7 +579,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                val.as_slice(),
                                                item.id);
                     for arg in args.iter() {
-                        self.visit_ty(&*arg.ty, e);
+                        self.visit_ty(&*arg.ty);
                     }
                 }
                 ast::StructVariantKind(ref struct_def) => {
@@ -597,18 +598,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
 
                     for field in struct_def.fields.iter() {
                         self.process_struct_field_def(field, qualname.as_slice(), variant.node.id);
-                        self.visit_ty(&*field.node.ty, e);
+                        self.visit_ty(&*field.node.ty);
                     }
                 }
             }
         }
 
-        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
     }
 
     fn process_impl(&mut self,
                     item: &ast::Item,
-                    e: DxrVisitorEnv,
                     type_parameters: &ast::Generics,
                     trait_ref: &Option<ast::TraitRef>,
                     typ: ast::P<ast::Ty>,
@@ -622,29 +622,29 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                          path.span,
                                          sub_span,
                                          id,
-                                         e.cur_scope);
+                                         self.cur_scope);
                         self.fmt.impl_str(path.span,
                                           sub_span,
                                           item.id,
                                           id,
-                                          e.cur_scope);
+                                          self.cur_scope);
                     },
                     None => ()
                 }
             },
-            _ => self.visit_ty(&*typ, e),
+            _ => self.visit_ty(&*typ),
         }
 
         match *trait_ref {
-            Some(ref trait_ref) => self.process_trait_ref(trait_ref, e, Some(item.id)),
+            Some(ref trait_ref) => self.process_trait_ref(trait_ref, Some(item.id)),
             None => (),
         }
 
-        self.process_generic_params(type_parameters, item.span, "", item.id, e);
+        self.process_generic_params(type_parameters, item.span, "", item.id);
         for impl_item in impl_items.iter() {
             match *impl_item {
                 ast::MethodImplItem(method) => {
-                    visit::walk_method_helper(self, &*method, e)
+                    visit::walk_method_helper(self, &*method)
                 }
             }
         }
@@ -652,7 +652,6 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
 
     fn process_trait(&mut self,
                      item: &ast::Item,
-                     e: DxrVisitorEnv,
                      generics: &ast::Generics,
                      trait_refs: &OwnedSlice<ast::TyParamBound>,
                      methods: &Vec<ast::TraitItem>) {
@@ -663,7 +662,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                            sub_span,
                            item.id,
                            qualname.as_slice(),
-                           e.cur_scope);
+                           self.cur_scope);
 
         // super-traits
         for super_bound in trait_refs.iter() {
@@ -683,7 +682,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                      trait_ref.path.span,
                                      sub_span,
                                      id,
-                                     e.cur_scope);
+                                     self.cur_scope);
                     self.fmt.inherit_str(trait_ref.path.span,
                                          sub_span,
                                          id,
@@ -694,15 +693,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
 
         // walk generics and methods
-        self.process_generic_params(generics, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(generics, item.span, qualname.as_slice(), item.id);
         for method in methods.iter() {
-            self.visit_trait_item(method, e)
+            self.visit_trait_item(method)
         }
     }
 
     fn process_mod(&mut self,
                    item: &ast::Item,  // The module in question, represented as an item.
-                   e: DxrVisitorEnv,
                    m: &ast::Mod) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
@@ -714,15 +712,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                          sub_span,
                          item.id,
                          qualname.as_slice(),
-                         e.cur_scope,
+                         self.cur_scope,
                          filename.as_slice());
 
-        visit::walk_mod(self, m, DxrVisitorEnv::new_nested(item.id));
+        self.nest(item.id, |v| visit::walk_mod(v, m));
     }
 
     fn process_path(&mut self,
                     ex: &ast::Expr,
-                    e: DxrVisitorEnv,
                     path: &ast::Path) {
         if generated_code(path.span) {
             return
@@ -744,18 +741,18 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                        ex.span,
                                                        sub_span,
                                                        ast_util::local_def(id),
-                                                       e.cur_scope),
+                                                       self.cur_scope),
             def::DefStatic(def_id,_) |
             def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef,
                                                               ex.span,
                                                               sub_span,
                                                               def_id,
-                                                              e.cur_scope),
+                                                              self.cur_scope),
             def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
                                                        ex.span,
                                                        sub_span,
                                                        def_id,
-                                                        e.cur_scope),
+                                                        self.cur_scope),
             def::DefStaticMethod(declid, provenence, _) => {
                 let sub_span = self.span.sub_span_for_meth_name(ex.span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
@@ -806,12 +803,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                        sub_span,
                                        defid,
                                        Some(declid),
-                                       e.cur_scope);
+                                       self.cur_scope);
             },
             def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
                                                           sub_span,
                                                           def_id,
-                                                          e.cur_scope),
+                                                          self.cur_scope),
             _ => self.sess.span_bug(ex.span,
                                     format!("Unexpected def kind while looking up path in '{}'",
                                             self.span.snippet(ex.span)).as_slice()),
@@ -819,22 +816,21 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         // modules or types in the path prefix
         match *def {
             def::DefStaticMethod(_, _, _) => {
-                self.write_sub_path_trait_truncated(path, e.cur_scope);
+                self.write_sub_path_trait_truncated(path);
             },
             def::DefLocal(_, _) |
             def::DefArg(_, _) |
             def::DefStatic(_,_) |
             def::DefStruct(_) |
-            def::DefFn(_, _) => self.write_sub_paths_truncated(path, e.cur_scope),
+            def::DefFn(_, _) => self.write_sub_paths_truncated(path),
             _ => {},
         }
 
-        visit::walk_path(self, path, e);
+        visit::walk_path(self, path);
     }
 
     fn process_struct_lit(&mut self,
                           ex: &ast::Expr,
-                          e: DxrVisitorEnv,
                           path: &ast::Path,
                           fields: &Vec<ast::Field>,
                           base: Option<Gc<ast::Expr>>) {
@@ -851,12 +847,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                  path.span,
                                  sub_span,
                                  id,
-                                 e.cur_scope);
+                                 self.cur_scope);
             },
             None => ()
         }
 
-        self.write_sub_paths_truncated(path, e.cur_scope);
+        self.write_sub_paths_truncated(path);
 
         for field in fields.iter() {
             match struct_def {
@@ -873,21 +869,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                              field.ident.span,
                                              sub_span,
                                              f.id,
-                                             e.cur_scope);
+                                             self.cur_scope);
                         }
                     }
                 }
                 None => {}
             }
 
-            self.visit_expr(&*field.expr, e)
+            self.visit_expr(&*field.expr)
         }
-        visit::walk_expr_opt(self, base, e)
+        visit::walk_expr_opt(self, base)
     }
 
     fn process_method_call(&mut self,
                            ex: &ast::Expr,
-                           e: DxrVisitorEnv,
                            args: &Vec<Gc<ast::Expr>>) {
         let method_map = self.analysis.ty_cx.method_map.borrow();
         let method_callee = method_map.get(&typeck::MethodCall::expr(ex.id));
@@ -941,13 +936,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                sub_span,
                                def_id,
                                decl_id,
-                               e.cur_scope);
+                               self.cur_scope);
 
         // walk receiver and args
-        visit::walk_exprs(self, args.as_slice(), e);
+        visit::walk_exprs(self, args.as_slice());
     }
 
-    fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
+    fn process_pat(&mut self, p:&ast::Pat) {
         if generated_code(p.span) {
             return
         }
@@ -955,7 +950,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         match p.node {
             ast::PatStruct(ref path, ref fields, _) => {
                 self.collected_paths.push((p.id, path.clone(), false, recorder::StructRef));
-                visit::walk_path(self, path, e);
+                visit::walk_path(self, path);
                 let struct_def = match self.lookup_type_ref(p.id) {
                     Some(sd) => sd,
                     None => {
@@ -976,7 +971,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                ).as_slice());
                 }
                 for (field, &span) in fields.iter().zip(field_spans.iter()) {
-                    self.visit_pat(&*field.pat, e);
+                    self.visit_pat(&*field.pat);
                     if span.is_none() {
                         continue;
                     }
@@ -987,7 +982,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                              p.span,
                                              span,
                                              f.id,
-                                             e.cur_scope);
+                                             self.cur_scope);
                             break;
                         }
                     }
@@ -995,7 +990,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             }
             ast::PatEnum(ref path, _) => {
                 self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef));
-                visit::walk_pat(self, p, e);
+                visit::walk_pat(self, p);
             }
             ast::PatIdent(bm, ref path1, ref optional_subpattern) => {
                 let immut = match bm {
@@ -1015,41 +1010,40 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                 self.collected_paths.push((p.id, path, immut, recorder::VarRef));
                 match *optional_subpattern {
                     None => {}
-                    Some(subpattern) => self.visit_pat(&*subpattern, e),
+                    Some(subpattern) => self.visit_pat(&*subpattern),
                 }
             }
-            _ => visit::walk_pat(self, p, e)
+            _ => visit::walk_pat(self, p)
         }
     }
 }
 
-impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
-    fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
+impl<'l, 'tcx> Visitor for DxrVisitor<'l, 'tcx> {
+    fn visit_item(&mut self, item:&ast::Item) {
         if generated_code(item.span) {
             return
         }
 
         match item.node {
             ast::ItemFn(decl, _, _, ref ty_params, body) =>
-                self.process_fn(item, e, decl, ty_params, body),
+                self.process_fn(item, decl, ty_params, body),
             ast::ItemStatic(typ, mt, expr) =>
-                self.process_static(item, e, typ, mt, &*expr),
-            ast::ItemStruct(def, ref ty_params) => self.process_struct(item, e, &*def, ty_params),
-            ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, e, def, ty_params),
+                self.process_static(item, typ, mt, &*expr),
+            ast::ItemStruct(def, ref ty_params) => self.process_struct(item, &*def, ty_params),
+            ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
             ast::ItemImpl(ref ty_params,
                           ref trait_ref,
                           typ,
                           ref impl_items) => {
                 self.process_impl(item,
-                                  e,
                                   ty_params,
                                   trait_ref,
                                   typ,
                                   impl_items)
             }
             ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
-                self.process_trait(item, e, generics, trait_refs, methods),
-            ast::ItemMod(ref m) => self.process_mod(item, e, m),
+                self.process_trait(item, generics, trait_refs, methods),
+            ast::ItemMod(ref m) => self.process_mod(item, m),
             ast::ItemTy(ty, ref ty_params) => {
                 let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
                 let value = ty_to_string(&*ty);
@@ -1060,26 +1054,26 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                      qualname.as_slice(),
                                      value.as_slice());
 
-                self.visit_ty(&*ty, e);
-                self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+                self.visit_ty(&*ty);
+                self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
             },
             ast::ItemMac(_) => (),
-            _ => visit::walk_item(self, item, e),
+            _ => visit::walk_item(self, item),
         }
     }
 
-    fn visit_generics(&mut self, generics: &ast::Generics, e: DxrVisitorEnv) {
+    fn visit_generics(&mut self, generics: &ast::Generics) {
         for param in generics.ty_params.iter() {
             for bound in param.bounds.iter() {
                 match *bound {
                     ast::TraitTyParamBound(ref trait_ref) => {
-                        self.process_trait_ref(trait_ref, e, None);
+                        self.process_trait_ref(trait_ref, None);
                     }
                     _ => {}
                 }
             }
             match param.default {
-                Some(ty) => self.visit_ty(&*ty, e),
+                Some(ty) => self.visit_ty(&*ty),
                 None => (),
             }
         }
@@ -1092,19 +1086,18 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                 fd: &ast::FnDecl,
                 b: &ast::Block,
                 s: Span,
-                _: NodeId,
-                e: DxrVisitorEnv) {
+                _: NodeId) {
         if generated_code(s) {
             return;
         }
 
         match *fk {
-            visit::FkMethod(_, _, method) => self.process_method(method, e),
-            _ => visit::walk_fn(self, fk, fd, b, s, e),
+            visit::FkMethod(_, _, method) => self.process_method(method),
+            _ => visit::walk_fn(self, fk, fd, b, s),
         }
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem, e: DxrVisitorEnv) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
         match *tm {
             ast::RequiredMethod(ref method_type) => {
                 if generated_code(method_type.span) {
@@ -1137,21 +1130,20 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
 
                 // walk arg and return types
                 for arg in method_type.decl.inputs.iter() {
-                    self.visit_ty(&*arg.ty, e);
+                    self.visit_ty(&*arg.ty);
                 }
-                self.visit_ty(&*method_type.decl.output, e);
+                self.visit_ty(&*method_type.decl.output);
 
                 self.process_generic_params(&method_type.generics,
                                             method_type.span,
                                             qualname,
-                                            method_type.id,
-                                            e);
+                                            method_type.id);
             }
-            ast::ProvidedMethod(method) => self.process_method(&*method, e),
+            ast::ProvidedMethod(method) => self.process_method(&*method),
         }
     }
 
-    fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
+    fn visit_view_item(&mut self, i:&ast::ViewItem) {
         if generated_code(i.span) {
             return
         }
@@ -1168,7 +1160,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                                                    path.span,
                                                                    sub_span,
                                                                    def_id,
-                                                                   e.cur_scope),
+                                                                   self.cur_scope),
                                     None => {},
                                 }
                                 Some(def_id)
@@ -1189,11 +1181,11 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                                id,
                                                mod_id,
                                                get_ident(ident).get(),
-                                               e.cur_scope);
-                        self.write_sub_paths_truncated(path, e.cur_scope);
+                                               self.cur_scope);
+                        self.write_sub_paths_truncated(path);
                     }
                     ast::ViewPathGlob(ref path, _) => {
-                        self.write_sub_paths(path, e.cur_scope);
+                        self.write_sub_paths(path);
                     }
                     ast::ViewPathList(ref path, ref list, _) => {
                         for plid in list.iter() {
@@ -1206,7 +1198,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                                     self.fmt.ref_str(
                                                         kind, plid.span,
                                                         Some(plid.span),
-                                                        def_id, e.cur_scope);
+                                                        def_id, self.cur_scope);
                                                 }
                                                 None => ()
                                             },
@@ -1217,7 +1209,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                             }
                         }
 
-                        self.write_sub_paths(path, e.cur_scope);
+                        self.write_sub_paths(path);
                     }
                 }
             },
@@ -1239,12 +1231,12 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                           cnum,
                                           name,
                                           s.as_slice(),
-                                          e.cur_scope);
+                                          self.cur_scope);
             },
         }
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty, e: DxrVisitorEnv) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         if generated_code(t.span) {
             return
         }
@@ -1258,20 +1250,20 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                          t.span,
                                          sub_span,
                                          id,
-                                         e.cur_scope);
+                                         self.cur_scope);
                     },
                     None => ()
                 }
 
-                self.write_sub_paths_truncated(path, e.cur_scope);
+                self.write_sub_paths_truncated(path);
 
-                visit::walk_path(self, path, e);
+                visit::walk_path(self, path);
             },
-            _ => visit::walk_ty(self, t, e),
+            _ => visit::walk_ty(self, t),
         }
     }
 
-    fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
+    fn visit_expr(&mut self, ex: &ast::Expr) {
         if generated_code(ex.span) {
             return
         }
@@ -1280,18 +1272,18 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
             ast::ExprCall(_f, ref _args) => {
                 // Don't need to do anything for function calls,
                 // because just walking the callee path does what we want.
-                visit::walk_expr(self, ex, e);
+                visit::walk_expr(self, ex);
             },
-            ast::ExprPath(ref path) => self.process_path(ex, e, path),
+            ast::ExprPath(ref path) => self.process_path(ex, path),
             ast::ExprStruct(ref path, ref fields, base) =>
-                self.process_struct_lit(ex, e, path, fields, base),
-            ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, e, args),
+                self.process_struct_lit(ex, path, fields, base),
+            ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
             ast::ExprField(sub_ex, ident, _) => {
                 if generated_code(sub_ex.span) {
                     return
                 }
 
-                self.visit_expr(&*sub_ex, e);
+                self.visit_expr(&*sub_ex);
 
                 let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
                 let t_box = ty::get(t);
@@ -1305,7 +1297,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                                  ex.span,
                                                  sub_span,
                                                  f.id,
-                                                 e.cur_scope);
+                                                 self.cur_scope);
                                 break;
                             }
                         }
@@ -1319,7 +1311,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                     return
                 }
 
-                self.visit_expr(&*sub_ex, e);
+                self.visit_expr(&*sub_ex);
 
                 let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
                 let t_box = ty::get(t);
@@ -1333,7 +1325,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                                  ex.span,
                                                  sub_span,
                                                  f.id,
-                                                 e.cur_scope);
+                                                 self.cur_scope);
                                 break;
                             }
                         }
@@ -1348,41 +1340,41 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                 }
 
                 let id = String::from_str("$").append(ex.id.to_string().as_slice());
-                self.process_formals(&decl.inputs, id.as_slice(), e);
+                self.process_formals(&decl.inputs, id.as_slice());
 
                 // walk arg and return types
                 for arg in decl.inputs.iter() {
-                    self.visit_ty(&*arg.ty, e);
+                    self.visit_ty(&*arg.ty);
                 }
-                self.visit_ty(&*decl.output, e);
+                self.visit_ty(&*decl.output);
 
                 // walk the body
-                self.visit_block(&*body, DxrVisitorEnv::new_nested(ex.id));
+                self.nest(ex.id, |v| v.visit_block(&*body));
             },
             _ => {
-                visit::walk_expr(self, ex, e)
+                visit::walk_expr(self, ex)
             },
         }
     }
 
-    fn visit_mac(&mut self, _: &ast::Mac, _: DxrVisitorEnv) {
+    fn visit_mac(&mut self, _: &ast::Mac) {
         // Just stop, macros are poison to us.
     }
 
-    fn visit_pat(&mut self, p: &ast::Pat, e: DxrVisitorEnv) {
-        self.process_pat(p, e);
+    fn visit_pat(&mut self, p: &ast::Pat) {
+        self.process_pat(p);
         if !self.collecting {
             self.collected_paths.clear();
         }
     }
 
-    fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) {
+    fn visit_arm(&mut self, arm: &ast::Arm) {
         assert!(self.collected_paths.len() == 0 && !self.collecting);
         self.collecting = true;
 
         for pattern in arm.pats.iter() {
             // collect paths from the arm's patterns
-            self.visit_pat(&**pattern, e);
+            self.visit_pat(&**pattern);
         }
         self.collecting = false;
         // process collected paths
@@ -1411,26 +1403,26 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
                                                             p.span,
                                                             sub_span,
                                                             id,
-                                                            e.cur_scope),
+                                                            self.cur_scope),
                 // FIXME(nrc) what is this doing here?
                 def::DefStatic(_, _) => {}
                 _ => error!("unexpected defintion kind when processing collected paths: {:?}", *def)
             }
         }
         self.collected_paths.clear();
-        visit::walk_expr_opt(self, arm.guard, e);
-        self.visit_expr(&*arm.body, e);
+        visit::walk_expr_opt(self, arm.guard);
+        self.visit_expr(&*arm.body);
     }
 
-    fn visit_stmt(&mut self, s:&ast::Stmt, e:DxrVisitorEnv) {
+    fn visit_stmt(&mut self, s:&ast::Stmt) {
         if generated_code(s.span) {
             return
         }
 
-        visit::walk_stmt(self, s, e)
+        visit::walk_stmt(self, s)
     }
 
-    fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
+    fn visit_local(&mut self, l:&ast::Local) {
         if generated_code(l.span) {
             return
         }
@@ -1439,7 +1431,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
         // pattern and collect them all.
         assert!(self.collected_paths.len() == 0 && !self.collecting);
         self.collecting = true;
-        self.visit_pat(&*l.pat, e);
+        self.visit_pat(&*l.pat);
         self.collecting = false;
 
         let value = self.span.snippet(l.span);
@@ -1462,22 +1454,8 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
         self.collected_paths.clear();
 
         // Just walk the initialiser and type (don't want to walk the pattern again).
-        self.visit_ty(&*l.ty, e);
-        visit::walk_expr_opt(self, l.init, e);
-    }
-}
-
-#[deriving(Clone)]
-struct DxrVisitorEnv {
-    cur_scope: NodeId,
-}
-
-impl DxrVisitorEnv {
-    fn new() -> DxrVisitorEnv {
-        DxrVisitorEnv{cur_scope: 0}
-    }
-    fn new_nested(new_mod: NodeId) -> DxrVisitorEnv {
-        DxrVisitorEnv{cur_scope: new_mod}
+        self.visit_ty(&*l.ty);
+        visit::walk_expr_opt(self, l.init);
     }
 }
 
@@ -1532,25 +1510,28 @@ pub fn process_crate(sess: &Session,
     };
     root_path.pop();
 
-    let mut visitor = DxrVisitor{ sess: sess,
-                                  analysis: analysis,
-                                  collected_paths: vec!(),
-                                  collecting: false,
-                                  fmt: FmtStrs::new(box Recorder {
-                                                        out: output_file as Box<Writer+'static>,
-                                                        dump_spans: false,
-                                                    },
-                                                    SpanUtils {
-                                                        sess: sess,
-                                                        err_count: Cell::new(0)
-                                                    },
-                                                    cratename.clone()),
-                                  span: SpanUtils {
-                                      sess: sess,
-                                      err_count: Cell::new(0)
-                                  }};
+    let mut visitor = DxrVisitor {
+        sess: sess,
+        analysis: analysis,
+        collected_paths: vec!(),
+        collecting: false,
+        fmt: FmtStrs::new(box Recorder {
+                            out: output_file as Box<Writer+'static>,
+                            dump_spans: false,
+                        },
+                        SpanUtils {
+                            sess: sess,
+                            err_count: Cell::new(0)
+                        },
+                        cratename.clone()),
+        span: SpanUtils {
+            sess: sess,
+            err_count: Cell::new(0)
+        },
+        cur_scope: 0
+    };
 
     visitor.dump_crate_info(cratename.as_slice(), krate);
 
-    visit::walk_crate(&mut visitor, krate, DxrVisitorEnv::new());
+    visit::walk_crate(&mut visitor, krate);
 }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index e73d81d9bf5..6d0c02ff4e3 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -24,6 +24,8 @@ use syntax::visit::{FnKind, FkMethod, Visitor};
 use middle::ty;
 use metadata::csearch;
 
+use std::mem::replace;
+
 /// A stability index, giving the stability level for items and methods.
 pub struct Index {
     // stability for crate-local items; unmarked stability == no entry
@@ -34,68 +36,68 @@ pub struct Index {
 
 // A private tree-walker for producing an Index.
 struct Annotator {
-    index: Index
+    index: Index,
+    parent: Option<Stability>
 }
 
 impl Annotator {
     // Determine the stability for a node based on its attributes and inherited
-    // stability. The stability is recorded in the index and returned.
-    fn annotate(&mut self, id: NodeId, attrs: &[Attribute],
-                parent: Option<Stability>) -> Option<Stability> {
-        match attr::find_stability(attrs).or(parent) {
+    // stability. The stability is recorded in the index and used as the parent.
+    fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) {
+        match attr::find_stability(attrs.as_slice()) {
             Some(stab) => {
                 self.index.local.insert(id, stab.clone());
-                Some(stab)
+                let parent = replace(&mut self.parent, Some(stab));
+                f(self);
+                self.parent = parent;
+            }
+            None => {
+                self.parent.clone().map(|stab| self.index.local.insert(id, stab));
+                f(self);
             }
-            None => None
         }
     }
 }
 
-impl Visitor<Option<Stability>> for Annotator {
-    fn visit_item(&mut self, i: &Item, parent: Option<Stability>) {
-        let stab = self.annotate(i.id, i.attrs.as_slice(), parent);
-        visit::walk_item(self, i, stab)
+impl Visitor for Annotator {
+    fn visit_item(&mut self, i: &Item) {
+        self.annotate(i.id, &i.attrs, |v| visit::walk_item(v, i));
     }
 
-    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block,
-                s: Span, _: NodeId, parent: Option<Stability>) {
-        let stab = match *fk {
-            FkMethod(_, _, meth) =>
-                self.annotate(meth.id, meth.attrs.as_slice(), parent),
-            _ => parent
-        };
-        visit::walk_fn(self, fk, fd, b, s, stab)
+    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
+        match *fk {
+            FkMethod(_, _, meth) => {
+                self.annotate(meth.id, &meth.attrs, |v| visit::walk_fn(v, fk, fd, b, s));
+            }
+            _ => visit::walk_fn(self, fk, fd, b, s)
+        }
     }
 
-    fn visit_trait_item(&mut self, t: &TraitItem, parent: Option<Stability>) {
-        let stab = match *t {
-            RequiredMethod(TypeMethod {attrs: ref attrs, id: id, ..}) =>
-                self.annotate(id, attrs.as_slice(), parent),
+    fn visit_trait_item(&mut self, t: &TraitItem) {
+        let (id, attrs) = match *t {
+            RequiredMethod(TypeMethod {id, ref attrs, ..}) => (id, attrs),
 
             // work around lack of pattern matching for @ types
-            ProvidedMethod(method) => match *method {
-                Method {attrs: ref attrs, id: id, ..} =>
-                    self.annotate(id, attrs.as_slice(), parent)
+            ProvidedMethod(ref method) => match **method {
+                Method {id, ref attrs, ..} => (id, attrs)
             }
         };
-        visit::walk_trait_item(self, t, stab)
+        self.annotate(id, attrs, |v| visit::walk_trait_item(v, t));
     }
 
-    fn visit_variant(&mut self, v: &Variant, g: &Generics, parent: Option<Stability>) {
-        let stab = self.annotate(v.node.id, v.node.attrs.as_slice(), parent);
-        visit::walk_variant(self, v, g, stab)
+    fn visit_variant(&mut self, var: &Variant, g: &Generics) {
+        self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g))
     }
 
-    fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics,
-                        _: NodeId, parent: Option<Stability>) {
-        s.ctor_id.map(|id| self.annotate(id, &[], parent.clone()));
-        visit::walk_struct_def(self, s, parent)
+    fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId) {
+        match s.ctor_id {
+            Some(id) => self.annotate(id, &vec![], |v| visit::walk_struct_def(v, s)),
+            None => visit::walk_struct_def(self, s)
+        }
     }
 
-    fn visit_struct_field(&mut self, s: &StructField, parent: Option<Stability>) {
-        let stab = self.annotate(s.node.id, s.node.attrs.as_slice(), parent);
-        visit::walk_struct_field(self, s, stab)
+    fn visit_struct_field(&mut self, s: &StructField) {
+        self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s));
     }
 }
 
@@ -106,10 +108,10 @@ impl Index {
             index: Index {
                 local: NodeMap::new(),
                 extern_cache: DefIdMap::new()
-            }
+            },
+            parent: None
         };
-        let stab = annotator.annotate(ast::CRATE_NODE_ID, krate.attrs.as_slice(), None);
-        visit::walk_crate(&mut annotator, krate, stab);
+        annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, |v| visit::walk_crate(v, krate));
         annotator.index
     }
 }
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index dc2aa16eb72..86877c032d1 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1322,18 +1322,32 @@ pub fn make_return_slot_pointer(fcx: &FunctionContext, output_type: ty::t) -> Va
 }
 
 struct CheckForNestedReturnsVisitor {
-    found: bool
+    found: bool,
+    in_return: bool
 }
 
-impl Visitor<bool> for CheckForNestedReturnsVisitor {
-    fn visit_expr(&mut self, e: &ast::Expr, in_return: bool) {
+impl CheckForNestedReturnsVisitor {
+    fn explicit() -> CheckForNestedReturnsVisitor {
+        CheckForNestedReturnsVisitor { found: false, in_return: false }
+    }
+    fn implicit() -> CheckForNestedReturnsVisitor {
+        CheckForNestedReturnsVisitor { found: false, in_return: true }
+    }
+}
+
+impl Visitor for CheckForNestedReturnsVisitor {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
-            ast::ExprRet(..) if in_return => {
-                self.found = true;
-                return;
+            ast::ExprRet(..) => {
+                if self.in_return {
+                    self.found = true;
+                } else {
+                    self.in_return = true;
+                    visit::walk_expr(self, e);
+                    self.in_return = false;
+                }
             }
-            ast::ExprRet(..) => visit::walk_expr(self, e, true),
-            _ => visit::walk_expr(self, e, in_return)
+            _ => visit::walk_expr(self, e)
         }
     }
 }
@@ -1343,10 +1357,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
         Some(ast_map::NodeItem(i)) => {
             match i.node {
                 ast::ItemFn(_, _, _, _, blk) => {
-                    let mut explicit = CheckForNestedReturnsVisitor { found: false };
-                    let mut implicit = CheckForNestedReturnsVisitor { found: false };
-                    visit::walk_item(&mut explicit, &*i, false);
-                    visit::walk_expr_opt(&mut implicit, blk.expr, true);
+                    let mut explicit = CheckForNestedReturnsVisitor::explicit();
+                    let mut implicit = CheckForNestedReturnsVisitor::implicit();
+                    visit::walk_item(&mut explicit, &*i);
+                    visit::walk_expr_opt(&mut implicit, blk.expr);
                     explicit.found || implicit.found
                 }
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
@@ -1357,10 +1371,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 ast::ProvidedMethod(m) => {
                     match m.node {
                         ast::MethDecl(_, _, _, _, _, _, blk, _) => {
-                            let mut explicit = CheckForNestedReturnsVisitor { found: false };
-                            let mut implicit = CheckForNestedReturnsVisitor { found: false };
-                            visit::walk_method_helper(&mut explicit, &*m, false);
-                            visit::walk_expr_opt(&mut implicit, blk.expr, true);
+                            let mut explicit = CheckForNestedReturnsVisitor::explicit();
+                            let mut implicit = CheckForNestedReturnsVisitor::implicit();
+                            visit::walk_method_helper(&mut explicit, &*m);
+                            visit::walk_expr_opt(&mut implicit, blk.expr);
                             explicit.found || implicit.found
                         }
                         ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
@@ -1377,18 +1391,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 ast::MethodImplItem(ref m) => {
                     match m.node {
                         ast::MethDecl(_, _, _, _, _, _, blk, _) => {
-                            let mut explicit = CheckForNestedReturnsVisitor {
-                                found: false,
-                            };
-                            let mut implicit = CheckForNestedReturnsVisitor {
-                                found: false,
-                            };
-                            visit::walk_method_helper(&mut explicit,
-                                                      &**m,
-                                                      false);
-                            visit::walk_expr_opt(&mut implicit,
-                                                 blk.expr,
-                                                 true);
+                            let mut explicit = CheckForNestedReturnsVisitor::explicit();
+                            let mut implicit = CheckForNestedReturnsVisitor::implicit();
+                            visit::walk_method_helper(&mut explicit, &**m);
+                            visit::walk_expr_opt(&mut implicit, blk.expr);
                             explicit.found || implicit.found
                         }
                         ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
@@ -1401,10 +1407,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 ast::ExprFnBlock(_, _, blk) |
                 ast::ExprProc(_, blk) |
                 ast::ExprUnboxedFn(_, _, _, blk) => {
-                    let mut explicit = CheckForNestedReturnsVisitor { found: false };
-                    let mut implicit = CheckForNestedReturnsVisitor { found: false };
-                    visit::walk_expr(&mut explicit, &*e, false);
-                    visit::walk_expr_opt(&mut implicit, blk.expr, true);
+                    let mut explicit = CheckForNestedReturnsVisitor::explicit();
+                    let mut implicit = CheckForNestedReturnsVisitor::implicit();
+                    visit::walk_expr(&mut explicit, &*e);
+                    visit::walk_expr_opt(&mut implicit, blk.expr);
                     explicit.found || implicit.found
                 }
                 _ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
@@ -2135,8 +2141,8 @@ pub struct TransItemVisitor<'a, 'tcx: 'a> {
     pub ccx: &'a CrateContext<'a, 'tcx>,
 }
 
-impl<'a, 'tcx> Visitor<()> for TransItemVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item, _:()) {
+impl<'a, 'tcx> Visitor for TransItemVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         trans_item(self.ccx, i);
     }
 }
@@ -2236,7 +2242,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
         // Be sure to travel more than just one layer deep to catch nested
         // items in blocks and such.
         let mut v = TransItemVisitor{ ccx: ccx };
-        v.visit_block(&**body, ());
+        v.visit_block(&**body);
       }
       ast::ItemImpl(ref generics, _, _, ref impl_items) => {
         meth::trans_impl(ccx,
@@ -2254,7 +2260,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
       ast::ItemStatic(_, m, ref expr) => {
           // Recurse on the expression to catch items in blocks
           let mut v = TransItemVisitor{ ccx: ccx };
-          v.visit_expr(&**expr, ());
+          v.visit_expr(&**expr);
 
           let trans_everywhere = attr::requests_inline(item.attrs.as_slice());
           for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) {
@@ -2293,7 +2299,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
         // methods with items will not get translated and will cause ICE's when
         // metadata time comes around.
         let mut v = TransItemVisitor{ ccx: ccx };
-        visit::walk_item(&mut v, item, ());
+        visit::walk_item(&mut v, item);
       }
       _ => {/* fall through */ }
     }
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index dd9e41a61bf..164ddd65f35 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -150,7 +150,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             match els {
                 Some(elexpr) => {
                     let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
-                    trans.visit_expr(&*elexpr, ());
+                    trans.visit_expr(&*elexpr);
                 }
                 None => {}
             }
@@ -159,7 +159,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             trans::debuginfo::clear_source_location(bcx.fcx);
         } else {
             let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
-            trans.visit_block(&*thn, ());
+            trans.visit_block(&*thn);
 
             match els {
                 // if false { .. } else { .. }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index fb1a764f0fc..384502025cb 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -67,7 +67,7 @@ pub fn trans_impl(ccx: &CrateContext,
         for impl_item in impl_items.iter() {
             match *impl_item {
                 ast::MethodImplItem(method) => {
-                    visit::walk_method_helper(&mut v, &*method, ());
+                    visit::walk_method_helper(&mut v, &*method);
                 }
             }
         }
@@ -96,7 +96,7 @@ pub fn trans_impl(ccx: &CrateContext,
                 let mut v = TransItemVisitor {
                     ccx: ccx,
                 };
-                visit::walk_method_helper(&mut v, &*method, ());
+                visit::walk_method_helper(&mut v, &*method);
             }
         }
     }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 4f0f6121904..da16e443ef2 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -375,18 +375,18 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
 struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
 
-impl<'a, 'tcx> Visitor<()> for CheckTypeWellFormedVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for CheckTypeWellFormedVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         check_type_well_formed(self.ccx, i);
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
 }
 
 
-impl<'a, 'tcx> Visitor<()> for CheckItemTypesVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for CheckItemTypesVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         check_item(self.ccx, i);
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
 }
 
@@ -394,28 +394,28 @@ struct CheckItemSizedTypesVisitor<'a, 'tcx: 'a> {
     ccx: &'a CrateCtxt<'a, 'tcx>
 }
 
-impl<'a, 'tcx> Visitor<()> for CheckItemSizedTypesVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for CheckItemSizedTypesVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         check_item_sized(self.ccx, i);
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
 }
 
 pub fn check_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
     let mut visit = CheckTypeWellFormedVisitor { ccx: ccx };
-    visit::walk_crate(&mut visit, krate, ());
+    visit::walk_crate(&mut visit, krate);
 
     // If types are not well-formed, it leads to all manner of errors
     // downstream, so stop reporting errors at this point.
     ccx.tcx.sess.abort_if_errors();
 
     let mut visit = CheckItemTypesVisitor { ccx: ccx };
-    visit::walk_crate(&mut visit, krate, ());
+    visit::walk_crate(&mut visit, krate);
 
     ccx.tcx.sess.abort_if_errors();
 
     let mut visit = CheckItemSizedTypesVisitor { ccx: ccx };
-    visit::walk_crate(&mut visit, krate, ());
+    visit::walk_crate(&mut visit, krate);
 }
 
 fn check_bare_fn(ccx: &CrateCtxt,
@@ -464,9 +464,9 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for GatherLocalsVisitor<'a, 'tcx> {
+impl<'a, 'tcx> Visitor for GatherLocalsVisitor<'a, 'tcx> {
     // Add explicitly-declared locals.
-    fn visit_local(&mut self, local: &ast::Local, _: ()) {
+    fn visit_local(&mut self, local: &ast::Local) {
         let o_ty = match local.ty.node {
             ast::TyInfer => None,
             _ => Some(self.fcx.to_ty(&*local.ty))
@@ -476,11 +476,11 @@ impl<'a, 'tcx> Visitor<()> for GatherLocalsVisitor<'a, 'tcx> {
                self.fcx.pat_to_string(&*local.pat),
                self.fcx.infcx().ty_to_string(
                    self.fcx.inh.locals.borrow().get_copy(&local.id)));
-        visit::walk_local(self, local, ());
+        visit::walk_local(self, local);
     }
 
     // Add pattern bindings.
-    fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
+    fn visit_pat(&mut self, p: &ast::Pat) {
             match p.node {
               ast::PatIdent(_, ref path1, _)
                   if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => {
@@ -492,33 +492,33 @@ impl<'a, 'tcx> Visitor<()> for GatherLocalsVisitor<'a, 'tcx> {
               }
               _ => {}
             }
-            visit::walk_pat(self, p, ());
+            visit::walk_pat(self, p);
 
     }
 
-    fn visit_block(&mut self, b: &ast::Block, _: ()) {
+    fn visit_block(&mut self, b: &ast::Block) {
         // non-obvious: the `blk` variable maps to region lb, so
         // we have to keep this up-to-date.  This
         // is... unfortunate.  It'd be nice to not need this.
-        visit::walk_block(self, b, ());
+        visit::walk_block(self, b);
     }
 
     // Since an expr occurs as part of the type fixed size arrays we
     // need to record the type for that node
-    fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         match t.node {
             ast::TyFixedLengthVec(ref ty, ref count_expr) => {
-                self.visit_ty(&**ty, ());
+                self.visit_ty(&**ty);
                 check_expr_with_hint(self.fcx, &**count_expr, ty::mk_uint());
             }
-            _ => visit::walk_ty(self, t, ())
+            _ => visit::walk_ty(self, t)
         }
     }
 
     // Don't descend into fns and items
     fn visit_fn(&mut self, _: &visit::FnKind, _: &ast::FnDecl,
-                _: &ast::Block, _: Span, _: ast::NodeId, _: ()) { }
-    fn visit_item(&mut self, _: &ast::Item, _: ()) { }
+                _: &ast::Block, _: Span, _: ast::NodeId) { }
+    fn visit_item(&mut self, _: &ast::Item) { }
 
 }
 
@@ -603,7 +603,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
             _match::check_pat(&pcx, &*input.pat, *arg_ty);
         }
 
-        visit.visit_block(body, ());
+        visit.visit_block(body);
     }
 
     check_block_with_expected(&fcx, body, ExpectHasType(ret_ty));
@@ -4508,7 +4508,7 @@ pub fn check_const_with_ty(fcx: &FnCtxt,
     // This is technically unnecessary because locals in static items are forbidden,
     // but prevents type checking from blowing up before const checking can properly
     // emit a error.
-    GatherLocalsVisitor { fcx: fcx }.visit_expr(e, ());
+    GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
 
     check_expr_with_hint(fcx, e, declty);
     demand::coerce(fcx, e.span, declty, e);
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index c08401375ca..241aa5b9189 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -150,7 +150,7 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
     let mut rcx = Rcx::new(fcx, e.id);
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        rcx.visit_expr(e, ());
+        rcx.visit_expr(e);
         rcx.visit_region_obligations(e.id);
     }
     fcx.infcx().resolve_regions_and_report_errors();
@@ -346,7 +346,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
 
         let len = self.region_param_pairs.len();
         self.relate_free_regions(fn_sig.as_slice(), body.id);
-        self.visit_block(body, ());
+        self.visit_block(body);
         self.visit_region_obligations(body.id);
         self.region_param_pairs.truncate(len);
     }
@@ -479,7 +479,7 @@ impl<'fcx, 'tcx> mc::Typer<'tcx> for Rcx<'fcx, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for Rcx<'a, 'tcx> {
+impl<'a, 'tcx> Visitor for Rcx<'a, 'tcx> {
     // (..) 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
@@ -489,21 +489,21 @@ impl<'a, 'tcx> Visitor<()> for Rcx<'a, 'tcx> {
     // regions, until regionck, as described in #3238.
 
     fn visit_fn(&mut self, _fk: &visit::FnKind, _fd: &ast::FnDecl,
-                b: &ast::Block, _s: Span, id: ast::NodeId, _e: ()) {
+                b: &ast::Block, _s: Span, id: ast::NodeId) {
         self.visit_fn_body(id, b)
     }
 
-    fn visit_item(&mut self, i: &ast::Item, _: ()) { visit_item(self, i); }
+    fn visit_item(&mut self, i: &ast::Item) { visit_item(self, i); }
 
-    fn visit_expr(&mut self, ex: &ast::Expr, _: ()) { visit_expr(self, ex); }
+    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, _: ()) { visit_arm(self, a); }
+    fn visit_arm(&mut self, a: &ast::Arm) { visit_arm(self, a); }
 
-    fn visit_local(&mut self, l: &ast::Local, _: ()) { visit_local(self, l); }
+    fn visit_local(&mut self, l: &ast::Local) { visit_local(self, l); }
 
-    fn visit_block(&mut self, b: &ast::Block, _: ()) { visit_block(self, b); }
+    fn visit_block(&mut self, b: &ast::Block) { visit_block(self, b); }
 }
 
 fn visit_item(_rcx: &mut Rcx, _item: &ast::Item) {
@@ -511,7 +511,7 @@ fn visit_item(_rcx: &mut Rcx, _item: &ast::Item) {
 }
 
 fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
-    visit::walk_block(rcx, b, ());
+    visit::walk_block(rcx, b);
 }
 
 fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
@@ -520,14 +520,14 @@ fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
         constrain_bindings_in_pat(&**p, rcx);
     }
 
-    visit::walk_arm(rcx, arm, ());
+    visit::walk_arm(rcx, arm);
 }
 
 fn visit_local(rcx: &mut Rcx, l: &ast::Local) {
     // see above
     constrain_bindings_in_pat(&*l.pat, rcx);
     link_local(rcx, l);
-    visit::walk_local(rcx, l, ());
+    visit::walk_local(rcx, l);
 }
 
 fn constrain_bindings_in_pat(pat: &ast::Pat, rcx: &mut Rcx) {
@@ -625,19 +625,19 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                                false);
             }
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprMethodCall(_, _, ref args) => {
             constrain_call(rcx, expr, Some(*args.get(0)),
                            args.slice_from(1), false);
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprAssign(ref lhs, _) => {
             adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprAssignOp(_, ref lhs, ref rhs) => {
@@ -648,7 +648,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
 
             adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprIndex(ref lhs, ref rhs) |
@@ -660,14 +660,14 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             constrain_call(rcx, expr, Some(lhs.clone()),
                            [rhs.clone()], true);
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprUnary(_, ref lhs) if has_method_map => {
             // As above.
             constrain_call(rcx, expr, Some(lhs.clone()), [], true);
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprUnary(ast::UnBox, ref base) => {
@@ -675,7 +675,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             let base_ty = rcx.resolve_node_type(base.id);
             type_must_outlive(rcx, infer::Managed(expr.span),
                               base_ty, ty::ReStatic);
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprUnary(ast::UnDeref, ref base) => {
@@ -696,7 +696,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                 _ => {}
             }
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprIndex(ref vec_expr, _) => {
@@ -704,7 +704,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             let vec_type = rcx.resolve_expr_type_adjusted(&**vec_expr);
             constrain_index(rcx, expr, vec_type);
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprCast(ref source, _) => {
@@ -712,7 +712,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             // instance.  If so, we have to be sure that the type of
             // the source obeys the trait's region bound.
             constrain_cast(rcx, expr, &**source);
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprAddrOf(m, ref base) => {
@@ -728,13 +728,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             let ty0 = rcx.resolve_node_type(expr.id);
             type_must_outlive(rcx, infer::AddrOf(expr.span),
                               ty0, ty::ReScope(expr.id));
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprMatch(ref discr, ref arms) => {
             link_match(rcx, &**discr, arms.as_slice());
 
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
 
         ast::ExprFnBlock(_, _, ref body) |
@@ -745,16 +745,16 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
 
         ast::ExprLoop(ref body, _) => {
             let repeating_scope = rcx.set_repeating_scope(body.id);
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
             rcx.set_repeating_scope(repeating_scope);
         }
 
         ast::ExprWhile(ref cond, ref body, _) => {
             let repeating_scope = rcx.set_repeating_scope(cond.id);
-            rcx.visit_expr(&**cond, ());
+            rcx.visit_expr(&**cond);
 
             rcx.set_repeating_scope(body.id);
-            rcx.visit_block(&**body, ());
+            rcx.visit_block(&**body);
 
             rcx.set_repeating_scope(repeating_scope);
         }
@@ -768,19 +768,19 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                 link_pattern(rcx, mc, head_cmt, &**pat);
             }
 
-            rcx.visit_expr(&**head, ());
+            rcx.visit_expr(&**head);
             type_of_node_must_outlive(rcx,
                                       infer::AddrOf(expr.span),
                                       head.id,
                                       ty::ReScope(expr.id));
 
             let repeating_scope = rcx.set_repeating_scope(body.id);
-            rcx.visit_block(&**body, ());
+            rcx.visit_block(&**body);
             rcx.set_repeating_scope(repeating_scope);
         }
 
         _ => {
-            visit::walk_expr(rcx, expr, ());
+            visit::walk_expr(rcx, expr);
         }
     }
 }
@@ -890,7 +890,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     }
 
     let repeating_scope = rcx.set_repeating_scope(body.id);
-    visit::walk_expr(rcx, expr, ());
+    visit::walk_expr(rcx, expr);
     rcx.set_repeating_scope(repeating_scope);
 
     match ty::get(function_type).sty {
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 16136fcf3e8..086887326a2 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -1025,12 +1025,12 @@ pub fn trans_resolve_method(tcx: &ty::ctxt, id: ast::NodeId,
                    false)
 }
 
-impl<'a, 'b, 'tcx> visit::Visitor<()> for &'a FnCtxt<'b, 'tcx> {
-    fn visit_expr(&mut self, ex: &ast::Expr, _: ()) {
+impl<'a, 'b, 'tcx> visit::Visitor for &'a FnCtxt<'b, 'tcx> {
+    fn visit_expr(&mut self, ex: &ast::Expr) {
         early_resolve_expr(ex, *self, false);
-        visit::walk_expr(self, ex, ());
+        visit::walk_expr(self, ex);
     }
-    fn visit_item(&mut self, _: &ast::Item, _: ()) {
+    fn visit_item(&mut self, _: &ast::Item) {
         // no-op
     }
 }
@@ -1038,7 +1038,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<()> for &'a FnCtxt<'b, 'tcx> {
 // Detect points where a trait-bounded type parameter is
 // instantiated, resolve the impls for the parameters.
 pub fn resolve_in_block(mut fcx: &FnCtxt, bl: &ast::Block) {
-    visit::walk_block(&mut fcx, bl, ());
+    visit::walk_block(&mut fcx, bl);
 }
 
 /// Used in the kind checker after typechecking has finished. Calls
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index d65172cc0c1..89518add839 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -41,7 +41,7 @@ use syntax::visit::Visitor;
 pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
     assert_eq!(fcx.writeback_errors.get(), false);
     let mut wbcx = WritebackCx::new(fcx);
-    wbcx.visit_expr(e, ());
+    wbcx.visit_expr(e);
     wbcx.visit_upvar_borrow_map();
     wbcx.visit_unboxed_closures();
 }
@@ -51,9 +51,9 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
                                blk: &ast::Block) {
     assert_eq!(fcx.writeback_errors.get(), false);
     let mut wbcx = WritebackCx::new(fcx);
-    wbcx.visit_block(blk, ());
+    wbcx.visit_block(blk);
     for arg in decl.inputs.iter() {
-        wbcx.visit_pat(&*arg.pat, ());
+        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) {
@@ -106,21 +106,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 // below. In general, a function is made into a `visitor` if it must
 // traffic in node-ids or update tables in the type context etc.
 
-impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
-    fn visit_item(&mut self, _: &ast::Item, _: ()) {
+impl<'cx, 'tcx> Visitor for WritebackCx<'cx, 'tcx> {
+    fn visit_item(&mut self, _: &ast::Item) {
         // Ignore items
     }
 
-    fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) {
+    fn visit_stmt(&mut self, s: &ast::Stmt) {
         if self.fcx.writeback_errors.get() {
             return;
         }
 
         self.visit_node_id(ResolvingExpr(s.span), ty::stmt_node_id(s));
-        visit::walk_stmt(self, s, ());
+        visit::walk_stmt(self, s);
     }
 
-    fn visit_expr(&mut self, e:&ast::Expr, _: ()) {
+    fn visit_expr(&mut self, e:&ast::Expr) {
         if self.fcx.writeback_errors.get() {
             return;
         }
@@ -143,19 +143,19 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
             _ => {}
         }
 
-        visit::walk_expr(self, e, ());
+        visit::walk_expr(self, e);
     }
 
-    fn visit_block(&mut self, b: &ast::Block, _: ()) {
+    fn visit_block(&mut self, b: &ast::Block) {
         if self.fcx.writeback_errors.get() {
             return;
         }
 
         self.visit_node_id(ResolvingExpr(b.span), b.id);
-        visit::walk_block(self, b, ());
+        visit::walk_block(self, b);
     }
 
-    fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
+    fn visit_pat(&mut self, p: &ast::Pat) {
         if self.fcx.writeback_errors.get() {
             return;
         }
@@ -167,10 +167,10 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
                p.id,
                ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx()));
 
-        visit::walk_pat(self, p, ());
+        visit::walk_pat(self, p);
     }
 
-    fn visit_local(&mut self, l: &ast::Local, _: ()) {
+    fn visit_local(&mut self, l: &ast::Local) {
         if self.fcx.writeback_errors.get() {
             return;
         }
@@ -178,16 +178,16 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
         let var_ty = self.fcx.local_ty(l.span, l.id);
         let var_ty = self.resolve(&var_ty, ResolvingLocal(l.span));
         write_ty_to_tcx(self.tcx(), l.id, var_ty);
-        visit::walk_local(self, l, ());
+        visit::walk_local(self, l);
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         match t.node {
             ast::TyFixedLengthVec(ref ty, ref count_expr) => {
-                self.visit_ty(&**ty, ());
+                self.visit_ty(&**ty);
                 write_ty_to_tcx(self.tcx(), count_expr.id, ty::mk_uint());
             }
-            _ => visit::walk_ty(self, t, ())
+            _ => visit::walk_ty(self, t)
         }
     }
 }
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 2c6dc94f182..6a642651609 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -191,8 +191,8 @@ struct CoherenceCheckVisitor<'a, 'tcx: 'a> {
     cc: &'a CoherenceChecker<'a, 'tcx>
 }
 
-impl<'a, 'tcx> visit::Visitor<()> for CoherenceCheckVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &Item, _: ()) {
+impl<'a, 'tcx> visit::Visitor for CoherenceCheckVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
 
         //debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
 
@@ -210,7 +210,7 @@ impl<'a, 'tcx> visit::Visitor<()> for CoherenceCheckVisitor<'a, 'tcx> {
             }
         };
 
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 }
 
@@ -218,13 +218,13 @@ struct PrivilegedScopeVisitor<'a, 'tcx: 'a> {
     cc: &'a CoherenceChecker<'a, 'tcx>
 }
 
-impl<'a, 'tcx> visit::Visitor<()> for PrivilegedScopeVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &Item, _: ()) {
+impl<'a, 'tcx> visit::Visitor for PrivilegedScopeVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
 
         match item.node {
             ItemMod(ref module_) => {
                 // Then visit the module items.
-                visit::walk_mod(self, module_, ());
+                visit::walk_mod(self, module_);
             }
             ItemImpl(_, None, ref ast_ty, _) => {
                 if !self.cc.ast_type_is_defined_in_local_crate(&**ast_ty) {
@@ -256,10 +256,10 @@ impl<'a, 'tcx> visit::Visitor<()> for PrivilegedScopeVisitor<'a, 'tcx> {
                     }
                 }
 
-                visit::walk_item(self, item, ());
+                visit::walk_item(self, item);
             }
             _ => {
-                visit::walk_item(self, item, ());
+                visit::walk_item(self, item);
             }
         }
     }
@@ -271,7 +271,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
         // containing the inherent methods and extension methods. It also
         // builds up the trait inheritance table.
         let mut visitor = CoherenceCheckVisitor { cc: self };
-        visit::walk_crate(&mut visitor, krate, ());
+        visit::walk_crate(&mut visitor, krate);
 
         // Check that there are no overlapping trait instances
         self.check_implementation_coherence();
@@ -543,7 +543,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
     // Privileged scope checking
     fn check_privileged_scopes(&self, krate: &Crate) {
         let mut visitor = PrivilegedScopeVisitor{ cc: self };
-        visit::walk_crate(&mut visitor, krate, ());
+        visit::walk_crate(&mut visitor, krate);
     }
 
     fn trait_ref_to_trait_def_id(&self, trait_ref: &TraitRef) -> DefId {
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index d1d76734941..3af083be57a 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -84,10 +84,10 @@ pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
     }
 
     let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 
     let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
-    visit::walk_crate(&mut visitor, krate, ());
+    visit::walk_crate(&mut visitor, krate);
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -99,8 +99,8 @@ struct CollectTraitDefVisitor<'a, 'tcx: 'a> {
     ccx: &'a CrateCtxt<'a, 'tcx>
 }
 
-impl<'a, 'tcx> visit::Visitor<()> for CollectTraitDefVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item, _: ()) {
+impl<'a, 'tcx> visit::Visitor for CollectTraitDefVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         match i.node {
             ast::ItemTrait(..) => {
                 // computing the trait def also fills in the table
@@ -109,7 +109,7 @@ impl<'a, 'tcx> visit::Visitor<()> for CollectTraitDefVisitor<'a, 'tcx> {
             _ => { }
         }
 
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
 }
 
@@ -120,14 +120,14 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
     ccx: &'a CrateCtxt<'a, 'tcx>
 }
 
-impl<'a, 'tcx> visit::Visitor<()> for CollectItemTypesVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item, _: ()) {
+impl<'a, 'tcx> visit::Visitor for CollectItemTypesVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &ast::Item) {
         convert(self.ccx, i);
-        visit::walk_item(self, i, ());
+        visit::walk_item(self, i);
     }
-    fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
+    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         convert_foreign(self.ccx, i);
-        visit::walk_foreign_item(self, i, ());
+        visit::walk_foreign_item(self, i);
     }
 }
 
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 7e8c53159fb..83d7972e11c 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -301,7 +301,7 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
         })
     };
 
-    visit::walk_crate(&mut terms_cx, krate, ());
+    visit::walk_crate(&mut terms_cx, krate);
 
     terms_cx
 }
@@ -337,8 +337,8 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for TermsContext<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         debug!("add_inferreds for item {}", item.repr(self.tcx));
 
         let inferreds_on_entry = self.num_inferred();
@@ -379,7 +379,7 @@ impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
                     assert!(newly_added);
                 }
 
-                visit::walk_item(self, item, ());
+                visit::walk_item(self, item);
             }
 
             ast::ItemImpl(..) |
@@ -389,7 +389,7 @@ impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
             ast::ItemForeignMod(..) |
             ast::ItemTy(..) |
             ast::ItemMac(..) => {
-                visit::walk_item(self, item, ());
+                visit::walk_item(self, item);
             }
         }
     }
@@ -473,12 +473,12 @@ fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
         bivariant: bivariant,
         constraints: Vec::new(),
     };
-    visit::walk_crate(&mut constraint_cx, krate, ());
+    visit::walk_crate(&mut constraint_cx, krate);
     constraint_cx
 }
 
-impl<'a, 'tcx> Visitor<()> for ConstraintContext<'a, 'tcx> {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl<'a, 'tcx> Visitor for ConstraintContext<'a, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         let did = ast_util::local_def(item.id);
         let tcx = self.terms_cx.tcx;
 
@@ -533,7 +533,7 @@ impl<'a, 'tcx> Visitor<()> for ConstraintContext<'a, 'tcx> {
             ast::ItemTy(..) |
             ast::ItemImpl(..) |
             ast::ItemMac(..) => {
-                visit::walk_item(self, item, ());
+                visit::walk_item(self, item);
             }
         }
     }
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 7a36c423add..0375ddbd371 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -47,7 +47,7 @@ pub fn check_crate(krate: &ast::Crate,
 
     {
         let mut cx = Context { sess: sess, items: items };
-        visit::walk_crate(&mut cx, krate, ());
+        visit::walk_crate(&mut cx, krate);
     }
     verify(sess, items);
 }
@@ -105,13 +105,13 @@ impl<'a> Context<'a> {
     }
 }
 
-impl<'a> Visitor<()> for Context<'a> {
-    fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
+impl<'a> Visitor for Context<'a> {
+    fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         match lang_items::extract(i.attrs.as_slice()) {
             None => {}
             Some(lang_item) => self.register(lang_item.get(), i.span),
         }
-        visit::walk_foreign_item(self, i, ())
+        visit::walk_foreign_item(self, i)
     }
 }
 
diff --git a/src/librustc/plugin/build.rs b/src/librustc/plugin/build.rs
index ad35c4efe11..f02251350a4 100644
--- a/src/librustc/plugin/build.rs
+++ b/src/librustc/plugin/build.rs
@@ -21,8 +21,8 @@ struct RegistrarFinder {
     registrars: Vec<(ast::NodeId, Span)> ,
 }
 
-impl Visitor<()> for RegistrarFinder {
-    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+impl Visitor for RegistrarFinder {
+    fn visit_item(&mut self, item: &ast::Item) {
         match item.node {
             ast::ItemFn(..) => {
                 if attr::contains_name(item.attrs.as_slice(),
@@ -33,7 +33,7 @@ impl Visitor<()> for RegistrarFinder {
             _ => {}
         }
 
-        visit::walk_item(self, item, ());
+        visit::walk_item(self, item);
     }
 }
 
@@ -41,7 +41,7 @@ impl Visitor<()> for RegistrarFinder {
 pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
                              krate: &ast::Crate) -> Option<ast::NodeId> {
     let mut finder = RegistrarFinder { registrars: Vec::new() };
-    visit::walk_crate(&mut finder, krate, ());
+    visit::walk_crate(&mut finder, krate);
 
     match finder.registrars.len() {
         0 => None,
diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs
index 4f38c74893e..31265cc7571 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc/plugin/load.rs
@@ -69,7 +69,7 @@ impl<'a> PluginLoader<'a> {
 pub fn load_plugins(sess: &Session, krate: &ast::Crate,
                     addl_plugins: Option<Plugins>) -> Plugins {
     let mut loader = PluginLoader::new(sess);
-    visit::walk_crate(&mut loader, krate, ());
+    visit::walk_crate(&mut loader, krate);
 
     let mut plugins = loader.plugins;
 
@@ -87,8 +87,8 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
 }
 
 // note that macros aren't expanded yet, and therefore macros can't add plugins.
-impl<'a> Visitor<()> for PluginLoader<'a> {
-    fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
+impl<'a> Visitor for PluginLoader<'a> {
+    fn visit_view_item(&mut self, vi: &ast::ViewItem) {
         match vi.node {
             ast::ViewItemExternCrate(name, _, _) => {
                 let mut plugin_phase = false;
@@ -124,7 +124,7 @@ impl<'a> Visitor<()> for PluginLoader<'a> {
             _ => (),
         }
     }
-    fn visit_mac(&mut self, _: &ast::Mac, _:()) {
+    fn visit_mac(&mut self, _: &ast::Mac) {
         // bummer... can't see plugins inside macros.
         // do nothing.
     }
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 61ef9df99e8..b230b56a6ce 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -62,14 +62,14 @@ struct LoopQueryVisitor<'a> {
     flag: bool,
 }
 
-impl<'a> Visitor<()> for LoopQueryVisitor<'a> {
-    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
+impl<'a> Visitor for LoopQueryVisitor<'a> {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         self.flag |= (self.p)(&e.node);
         match e.node {
           // Skip inner loops, since a break in the inner loop isn't a
           // break inside the outer loop
           ast::ExprLoop(..) | ast::ExprWhile(..) | ast::ExprForLoop(..) => {}
-          _ => visit::walk_expr(self, e, ())
+          _ => visit::walk_expr(self, e)
         }
     }
 }
@@ -81,7 +81,7 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
         p: p,
         flag: false,
     };
-    visit::walk_block(&mut v, b, ());
+    visit::walk_block(&mut v, b);
     return v.flag;
 }
 
@@ -90,10 +90,10 @@ struct BlockQueryVisitor<'a> {
     flag: bool,
 }
 
-impl<'a> Visitor<()> for BlockQueryVisitor<'a> {
-    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
+impl<'a> Visitor for BlockQueryVisitor<'a> {
+    fn visit_expr(&mut self, e: &ast::Expr) {
         self.flag |= (self.p)(e);
-        visit::walk_expr(self, e, ())
+        visit::walk_expr(self, e)
     }
 }
 
@@ -104,7 +104,7 @@ pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
         p: p,
         flag: false,
     };
-    visit::walk_block(&mut v, &*b, ());
+    visit::walk_block(&mut v, &*b);
     return v.flag;
 }
 
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index 8e24fc1ad5b..a34dcc41cc3 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -86,7 +86,7 @@ impl Svh {
 
         {
             let mut visit = svh_visitor::make(&mut state);
-            visit::walk_crate(&mut visit, krate, ());
+            visit::walk_crate(&mut visit, krate);
         }
 
         // FIXME (#14132): This hash is still sensitive to e.g. the
@@ -322,12 +322,9 @@ mod svh_visitor {
     }
     fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
 
-    // local short-hand eases writing signatures of syntax::visit mod.
-    type E = ();
+    impl<'a> Visitor for StrictVersionHashVisitor<'a> {
 
-    impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> {
-
-        fn visit_mac(&mut self, macro: &Mac, e: E) {
+        fn visit_mac(&mut self, macro: &Mac) {
             // macro invocations, namely macro_rules definitions,
             // *can* appear as items, even in the expanded crate AST.
 
@@ -350,7 +347,7 @@ mod svh_visitor {
                       pprust::to_string(|pp_state| pp_state.print_mac(macro)));
             }
 
-            visit::walk_mac(self, macro, e);
+            visit::walk_mac(self, macro);
 
             fn macro_name(macro: &Mac) -> token::InternedString {
                 match &macro.node {
@@ -364,26 +361,26 @@ mod svh_visitor {
         }
 
         fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
-                            g: &Generics, _: NodeId, e: E) {
+                            g: &Generics, _: NodeId) {
             SawStructDef(content(ident)).hash(self.st);
-            visit::walk_generics(self, g, e.clone());
-            visit::walk_struct_def(self, s, e)
+            visit::walk_generics(self, g);
+            visit::walk_struct_def(self, s)
         }
 
-        fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) {
+        fn visit_variant(&mut self, v: &Variant, g: &Generics) {
             SawVariant.hash(self.st);
             // walk_variant does not call walk_generics, so do it here.
-            visit::walk_generics(self, g, e.clone());
-            visit::walk_variant(self, v, g, e)
+            visit::walk_generics(self, g);
+            visit::walk_variant(self, v, g)
         }
 
-        fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>, env: E) {
+        fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>) {
             SawOptLifetimeRef.hash(self.st);
             // (This is a strange method in the visitor trait, in that
             // it does not expose a walk function to do the subroutine
             // calls.)
             match *l {
-                Some(ref l) => self.visit_lifetime_ref(l, env),
+                Some(ref l) => self.visit_lifetime_ref(l),
                 None => ()
             }
         }
@@ -402,15 +399,15 @@ mod svh_visitor {
         // (If you edit a method such that it deviates from the
         // pattern, please move that method up above this comment.)
 
-        fn visit_ident(&mut self, _: Span, ident: Ident, _: E) {
+        fn visit_ident(&mut self, _: Span, ident: Ident) {
             SawIdent(content(ident)).hash(self.st);
         }
 
-        fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) {
+        fn visit_lifetime_ref(&mut self, l: &Lifetime) {
             SawLifetimeRef(content(l.name)).hash(self.st);
         }
 
-        fn visit_lifetime_decl(&mut self, l: &LifetimeDef, _: E) {
+        fn visit_lifetime_decl(&mut self, l: &LifetimeDef) {
             SawLifetimeDecl(content(l.lifetime.name)).hash(self.st);
         }
 
@@ -419,15 +416,15 @@ mod svh_visitor {
         // monomorphization and cross-crate inlining generally implies
         // that a change to a crate body will require downstream
         // crates to be recompiled.
-        fn visit_expr(&mut self, ex: &Expr, e: E) {
-            SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e)
+        fn visit_expr(&mut self, ex: &Expr) {
+            SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex)
         }
 
-        fn visit_stmt(&mut self, s: &Stmt, e: E) {
-            SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e)
+        fn visit_stmt(&mut self, s: &Stmt) {
+            SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s)
         }
 
-        fn visit_view_item(&mut self, i: &ViewItem, e: E) {
+        fn visit_view_item(&mut self, i: &ViewItem) {
             // Two kinds of view items can affect the ABI for a crate:
             // exported `pub use` view items (since that may expose
             // items that downstream crates can call), and `use
@@ -437,79 +434,79 @@ mod svh_visitor {
             // The simplest approach to handling both of the above is
             // just to adopt the same simple-minded (fine-grained)
             // hash that I am deploying elsewhere here.
-            SawViewItem.hash(self.st); visit::walk_view_item(self, i, e)
+            SawViewItem.hash(self.st); visit::walk_view_item(self, i)
         }
 
-        fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) {
+        fn visit_foreign_item(&mut self, i: &ForeignItem) {
             // FIXME (#14132) ideally we would incorporate privacy (or
             // perhaps reachability) somewhere here, so foreign items
             // that do not leak into downstream crates would not be
             // part of the ABI.
-            SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i, e)
+            SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i)
         }
 
-        fn visit_item(&mut self, i: &Item, e: E) {
+        fn visit_item(&mut self, i: &Item) {
             // FIXME (#14132) ideally would incorporate reachability
             // analysis somewhere here, so items that never leak into
             // downstream crates (e.g. via monomorphisation or
             // inlining) would not be part of the ABI.
-            SawItem.hash(self.st); visit::walk_item(self, i, e)
+            SawItem.hash(self.st); visit::walk_item(self, i)
         }
 
-        fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) {
-            SawMod.hash(self.st); visit::walk_mod(self, m, e)
+        fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) {
+            SawMod.hash(self.st); visit::walk_mod(self, m)
         }
 
-        fn visit_decl(&mut self, d: &Decl, e: E) {
-            SawDecl.hash(self.st); visit::walk_decl(self, d, e)
+        fn visit_decl(&mut self, d: &Decl) {
+            SawDecl.hash(self.st); visit::walk_decl(self, d)
         }
 
-        fn visit_ty(&mut self, t: &Ty, e: E) {
-            SawTy.hash(self.st); visit::walk_ty(self, t, e)
+        fn visit_ty(&mut self, t: &Ty) {
+            SawTy.hash(self.st); visit::walk_ty(self, t)
         }
 
-        fn visit_generics(&mut self, g: &Generics, e: E) {
-            SawGenerics.hash(self.st); visit::walk_generics(self, g, e)
+        fn visit_generics(&mut self, g: &Generics) {
+            SawGenerics.hash(self.st); visit::walk_generics(self, g)
         }
 
-        fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) {
-            SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e)
+        fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
+            SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s)
         }
 
-        fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
-            SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
+        fn visit_ty_method(&mut self, t: &TypeMethod) {
+            SawTyMethod.hash(self.st); visit::walk_ty_method(self, t)
         }
 
-        fn visit_trait_item(&mut self, t: &TraitItem, e: E) {
-            SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t, e)
+        fn visit_trait_item(&mut self, t: &TraitItem) {
+            SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t)
         }
 
-        fn visit_struct_field(&mut self, s: &StructField, e: E) {
-            SawStructField.hash(self.st); visit::walk_struct_field(self, s, e)
+        fn visit_struct_field(&mut self, s: &StructField) {
+            SawStructField.hash(self.st); visit::walk_struct_field(self, s)
         }
 
-        fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
-            SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e)
+        fn visit_explicit_self(&mut self, es: &ExplicitSelf) {
+            SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es)
         }
 
-        fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) {
-            SawPath.hash(self.st); visit::walk_path(self, path, e)
+        fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
+            SawPath.hash(self.st); visit::walk_path(self, path)
         }
 
-        fn visit_block(&mut self, b: &Block, e: E) {
-            SawBlock.hash(self.st); visit::walk_block(self, b, e)
+        fn visit_block(&mut self, b: &Block) {
+            SawBlock.hash(self.st); visit::walk_block(self, b)
         }
 
-        fn visit_pat(&mut self, p: &Pat, e: E) {
-            SawPat.hash(self.st); visit::walk_pat(self, p, e)
+        fn visit_pat(&mut self, p: &Pat) {
+            SawPat.hash(self.st); visit::walk_pat(self, p)
         }
 
-        fn visit_local(&mut self, l: &Local, e: E) {
-            SawLocal.hash(self.st); visit::walk_local(self, l, e)
+        fn visit_local(&mut self, l: &Local) {
+            SawLocal.hash(self.st); visit::walk_local(self, l)
         }
 
-        fn visit_arm(&mut self, a: &Arm, e: E) {
-            SawArm.hash(self.st); visit::walk_arm(self, a, e)
+        fn visit_arm(&mut self, a: &Arm) {
+            SawArm.hash(self.st); visit::walk_arm(self, a)
         }
     }
 }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 8ef13ef2604..3db71c6d309 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -366,17 +366,16 @@ impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> {
     }
 }
 
-impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
+impl<'a, O: IdVisitingOperation> Visitor for IdVisitor<'a, O> {
     fn visit_mod(&mut self,
                  module: &Mod,
                  _: Span,
-                 node_id: NodeId,
-                 env: ()) {
+                 node_id: NodeId) {
         self.operation.visit_id(node_id);
-        visit::walk_mod(self, module, env)
+        visit::walk_mod(self, module)
     }
 
-    fn visit_view_item(&mut self, view_item: &ViewItem, env: ()) {
+    fn visit_view_item(&mut self, view_item: &ViewItem) {
         if !self.pass_through_items {
             if self.visited_outermost {
                 return;
@@ -403,16 +402,16 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
                 }
             }
         }
-        visit::walk_view_item(self, view_item, env);
+        visit::walk_view_item(self, view_item);
         self.visited_outermost = false;
     }
 
-    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem, env: ()) {
+    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
         self.operation.visit_id(foreign_item.id);
-        visit::walk_foreign_item(self, foreign_item, env)
+        visit::walk_foreign_item(self, foreign_item)
     }
 
-    fn visit_item(&mut self, item: &Item, env: ()) {
+    fn visit_item(&mut self, item: &Item) {
         if !self.pass_through_items {
             if self.visited_outermost {
                 return
@@ -431,48 +430,48 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
             _ => {}
         }
 
-        visit::walk_item(self, item, env);
+        visit::walk_item(self, item);
 
         self.visited_outermost = false
     }
 
-    fn visit_local(&mut self, local: &Local, env: ()) {
+    fn visit_local(&mut self, local: &Local) {
         self.operation.visit_id(local.id);
-        visit::walk_local(self, local, env)
+        visit::walk_local(self, local)
     }
 
-    fn visit_block(&mut self, block: &Block, env: ()) {
+    fn visit_block(&mut self, block: &Block) {
         self.operation.visit_id(block.id);
-        visit::walk_block(self, block, env)
+        visit::walk_block(self, block)
     }
 
-    fn visit_stmt(&mut self, statement: &Stmt, env: ()) {
+    fn visit_stmt(&mut self, statement: &Stmt) {
         self.operation.visit_id(ast_util::stmt_id(statement));
-        visit::walk_stmt(self, statement, env)
+        visit::walk_stmt(self, statement)
     }
 
-    fn visit_pat(&mut self, pattern: &Pat, env: ()) {
+    fn visit_pat(&mut self, pattern: &Pat) {
         self.operation.visit_id(pattern.id);
-        visit::walk_pat(self, pattern, env)
+        visit::walk_pat(self, pattern)
     }
 
-    fn visit_expr(&mut self, expression: &Expr, env: ()) {
+    fn visit_expr(&mut self, expression: &Expr) {
         self.operation.visit_id(expression.id);
-        visit::walk_expr(self, expression, env)
+        visit::walk_expr(self, expression)
     }
 
-    fn visit_ty(&mut self, typ: &Ty, env: ()) {
+    fn visit_ty(&mut self, typ: &Ty) {
         self.operation.visit_id(typ.id);
         match typ.node {
             TyPath(_, _, id) => self.operation.visit_id(id),
             _ => {}
         }
-        visit::walk_ty(self, typ, env)
+        visit::walk_ty(self, typ)
     }
 
-    fn visit_generics(&mut self, generics: &Generics, env: ()) {
+    fn visit_generics(&mut self, generics: &Generics) {
         self.visit_generics_helper(generics);
-        visit::walk_generics(self, generics, env)
+        visit::walk_generics(self, generics)
     }
 
     fn visit_fn(&mut self,
@@ -480,8 +479,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
                 function_declaration: &FnDecl,
                 block: &Block,
                 span: Span,
-                node_id: NodeId,
-                env: ()) {
+                node_id: NodeId) {
         if !self.pass_through_items {
             match *function_kind {
                 visit::FkMethod(..) if self.visited_outermost => return,
@@ -508,8 +506,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
                         function_kind,
                         function_declaration,
                         block,
-                        span,
-                        env);
+                        span);
 
         if !self.pass_through_items {
             match *function_kind {
@@ -519,28 +516,27 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
         }
     }
 
-    fn visit_struct_field(&mut self, struct_field: &StructField, env: ()) {
+    fn visit_struct_field(&mut self, struct_field: &StructField) {
         self.operation.visit_id(struct_field.node.id);
-        visit::walk_struct_field(self, struct_field, env)
+        visit::walk_struct_field(self, struct_field)
     }
 
     fn visit_struct_def(&mut self,
                         struct_def: &StructDef,
                         _: ast::Ident,
                         _: &ast::Generics,
-                        id: NodeId,
-                        _: ()) {
+                        id: NodeId) {
         self.operation.visit_id(id);
         struct_def.ctor_id.map(|ctor_id| self.operation.visit_id(ctor_id));
-        visit::walk_struct_def(self, struct_def, ());
+        visit::walk_struct_def(self, struct_def);
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem, _: ()) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
         match *tm {
             ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
             ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
         }
-        visit::walk_trait_item(self, tm, ());
+        visit::walk_trait_item(self, tm);
     }
 }
 
@@ -552,7 +548,7 @@ pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem,
         visited_outermost: false,
     };
 
-    visit::walk_inlined_item(&mut id_visitor, item, ());
+    visit::walk_inlined_item(&mut id_visitor, item);
 }
 
 struct IdRangeComputingVisitor {
@@ -595,7 +591,7 @@ pub fn compute_id_range_for_fn_body(fk: &visit::FnKind,
         pass_through_items: false,
         visited_outermost: false,
     };
-    id_visitor.visit_fn(fk, decl, body, sp, id, ());
+    id_visitor.visit_fn(fk, decl, body, sp, id);
     visitor.result.get()
 }
 
@@ -643,8 +639,8 @@ struct EachViewItemData<'a> {
     callback: |&ast::ViewItem|: 'a -> bool,
 }
 
-impl<'a> Visitor<()> for EachViewItemData<'a> {
-    fn visit_view_item(&mut self, view_item: &ast::ViewItem, _: ()) {
+impl<'a> Visitor for EachViewItemData<'a> {
+    fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
         let _ = (self.callback)(view_item);
     }
 }
@@ -654,7 +650,7 @@ impl EachViewItem for ast::Crate {
         let mut visit = EachViewItemData {
             callback: f,
         };
-        visit::walk_crate(&mut visit, self, ());
+        visit::walk_crate(&mut visit, self);
         true
     }
 }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d0f3cf6f9d7..04df6d618e9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -648,29 +648,29 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
 /// array
 #[deriving(Clone)]
 struct PatIdentFinder {
-    ident_accumulator: Vec<ast::Ident> ,
+    ident_accumulator: Vec<ast::Ident>
 }
 
-impl Visitor<()> for PatIdentFinder {
-    fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
+impl Visitor for PatIdentFinder {
+    fn visit_pat(&mut self, pattern: &ast::Pat) {
         match *pattern {
             ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
                 self.ident_accumulator.push(path1.node);
                 // visit optional subpattern of PatIdent:
                 for subpat in inner.iter() {
-                    self.visit_pat(&**subpat, ())
+                    self.visit_pat(&**subpat)
                 }
             }
             // use the default traversal for non-PatIdents
-            _ => visit::walk_pat(self, pattern, ())
+            _ => visit::walk_pat(self, pattern)
         }
     }
 }
 
 /// find the PatIdent paths in a pattern
-fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
+fn pattern_bindings(pat: &ast::Pat) -> Vec<ast::Ident> {
     let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
-    name_finder.visit_pat(pat,());
+    name_finder.visit_pat(pat);
     name_finder.ident_accumulator
 }
 
@@ -678,7 +678,7 @@ fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
 fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
     let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
     for arg in fn_decl.inputs.iter() {
-        pat_idents.visit_pat(&*arg.pat, ());
+        pat_idents.visit_pat(&*arg.pat);
     }
     pat_idents.ident_accumulator
 }
@@ -1099,7 +1099,7 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
 
 /// Check that there are no macro invocations left in the AST:
 pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
-    visit::walk_crate(&mut MacroExterminator{sess:sess}, krate, ());
+    visit::walk_crate(&mut MacroExterminator{sess:sess}, krate);
 }
 
 /// A visitor that ensures that no macro invocations remain in an AST.
@@ -1107,8 +1107,8 @@ struct MacroExterminator<'a>{
     sess: &'a parse::ParseSess
 }
 
-impl<'a> visit::Visitor<()> for MacroExterminator<'a> {
-    fn visit_mac(&mut self, macro: &ast::Mac, _:()) {
+impl<'a> Visitor for MacroExterminator<'a> {
+    fn visit_mac(&mut self, macro: &ast::Mac) {
         self.sess.span_diagnostic.span_bug(macro.span,
                                            "macro exterminator: expected AST \
                                            with no macro invocations");
@@ -1144,15 +1144,14 @@ mod test {
         path_accumulator: Vec<ast::Path> ,
     }
 
-    impl Visitor<()> for PathExprFinderContext {
-
-        fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
-            match *expr {
-                ast::Expr{id:_,span:_,node:ast::ExprPath(ref p)} => {
+    impl Visitor for PathExprFinderContext {
+        fn visit_expr(&mut self, expr: &ast::Expr) {
+            match expr.node {
+                ast::ExprPath(ref p) => {
                     self.path_accumulator.push(p.clone());
                     // not calling visit_path, but it should be fine.
                 }
-                _ => visit::walk_expr(self,expr,())
+                _ => visit::walk_expr(self, expr)
             }
         }
     }
@@ -1160,18 +1159,18 @@ mod test {
     // find the variable references in a crate
     fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
         let mut path_finder = PathExprFinderContext{path_accumulator:Vec::new()};
-        visit::walk_crate(&mut path_finder, the_crate, ());
+        visit::walk_crate(&mut path_finder, the_crate);
         path_finder.path_accumulator
     }
 
     /// A Visitor that extracts the identifiers from a thingy.
     // as a side note, I'm starting to want to abstract over these....
-    struct IdentFinder{
+    struct IdentFinder {
         ident_accumulator: Vec<ast::Ident>
     }
 
-    impl Visitor<()> for IdentFinder {
-        fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){
+    impl Visitor for IdentFinder {
+        fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident){
             self.ident_accumulator.push(id);
         }
     }
@@ -1179,7 +1178,7 @@ mod test {
     /// Find the idents in a crate
     fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
         let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()};
-        visit::walk_crate(&mut ident_finder, the_crate, ());
+        visit::walk_crate(&mut ident_finder, the_crate);
         ident_finder.ident_accumulator
     }
 
@@ -1277,7 +1276,7 @@ mod test {
     // find the pat_ident paths in a crate
     fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
         let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
-        visit::walk_crate(&mut name_finder, the_crate, ());
+        visit::walk_crate(&mut name_finder, the_crate);
         name_finder.ident_accumulator
     }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 50b42ea2c0f..c31082ddf59 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Context-passing AST walker. Each overridden visit method has full control
-//! over what happens with its node, it can do its own traversal of the node's
-//! children (potentially passing in different contexts to each), call
-//! `visit::visit_*` to apply the default traversal algorithm (again, it can
-//! override the context), or prevent deeper traversal by doing nothing.
+//! AST walker. Each overridden visit method has full control over what
+//! happens with its node, it can do its own traversal of the node's children,
+//! call `visit::walk_*` to apply the default traversal algorithm, or prevent
+//! deeper traversal by doing nothing.
 //!
 //! Note: it is an important invariant that the default visitor walks the body
 //! of a function in "execution order" (more concretely, reverse post-order
@@ -72,85 +71,82 @@ pub fn generics_of_fn(fk: &FnKind) -> Generics {
 /// explicitly, you need to override each method.  (And you also need
 /// to monitor future changes to `Visitor` in case a new method with a
 /// new default implementation gets introduced.)
-pub trait Visitor<E: Clone> {
+pub trait Visitor {
 
-    fn visit_ident(&mut self, _sp: Span, _ident: Ident, _e: E) {
+    fn visit_ident(&mut self, _sp: Span, _ident: Ident) {
         /*! Visit the idents */
     }
-    fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) { walk_mod(self, m, e) }
-    fn visit_view_item(&mut self, i: &ViewItem, e: E) { walk_view_item(self, i, e) }
-    fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) { walk_foreign_item(self, i, e) }
-    fn visit_item(&mut self, i: &Item, e: E) { walk_item(self, i, e) }
-    fn visit_local(&mut self, l: &Local, e: E) { walk_local(self, l, e) }
-    fn visit_block(&mut self, b: &Block, e: E) { walk_block(self, b, e) }
-    fn visit_stmt(&mut self, s: &Stmt, e: E) { walk_stmt(self, s, e) }
-    fn visit_arm(&mut self, a: &Arm, e: E) { walk_arm(self, a, e) }
-    fn visit_pat(&mut self, p: &Pat, e: E) { walk_pat(self, p, e) }
-    fn visit_decl(&mut self, d: &Decl, e: E) { walk_decl(self, d, e) }
-    fn visit_expr(&mut self, ex: &Expr, e: E) { walk_expr(self, ex, e) }
-    fn visit_expr_post(&mut self, _ex: &Expr, _e: E) { }
-    fn visit_ty(&mut self, t: &Ty, e: E) { walk_ty(self, t, e) }
-    fn visit_generics(&mut self, g: &Generics, e: E) { walk_generics(self, g, e) }
-    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) {
-        walk_fn(self, fk, fd, b, s, e)
-    }
-    fn visit_ty_method(&mut self, t: &TypeMethod, e: E) { walk_ty_method(self, t, e) }
-    fn visit_trait_item(&mut self, t: &TraitItem, e: E) { walk_trait_item(self, t, e) }
-    fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId, e: E) {
-        walk_struct_def(self, s, e)
-    }
-    fn visit_struct_field(&mut self, s: &StructField, e: E) { walk_struct_field(self, s, e) }
-    fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) { walk_variant(self, v, g, e) }
+    fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
+    fn visit_view_item(&mut self, i: &ViewItem) { walk_view_item(self, i) }
+    fn visit_foreign_item(&mut self, i: &ForeignItem) { walk_foreign_item(self, i) }
+    fn visit_item(&mut self, i: &Item) { walk_item(self, i) }
+    fn visit_local(&mut self, l: &Local) { walk_local(self, l) }
+    fn visit_block(&mut self, b: &Block) { walk_block(self, b) }
+    fn visit_stmt(&mut self, s: &Stmt) { walk_stmt(self, s) }
+    fn visit_arm(&mut self, a: &Arm) { walk_arm(self, a) }
+    fn visit_pat(&mut self, p: &Pat) { walk_pat(self, p) }
+    fn visit_decl(&mut self, d: &Decl) { walk_decl(self, d) }
+    fn visit_expr(&mut self, ex: &Expr) { walk_expr(self, ex) }
+    fn visit_expr_post(&mut self, _ex: &Expr) { }
+    fn visit_ty(&mut self, t: &Ty) { walk_ty(self, t) }
+    fn visit_generics(&mut self, g: &Generics) { walk_generics(self, g) }
+    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
+        walk_fn(self, fk, fd, b, s)
+    }
+    fn visit_ty_method(&mut self, t: &TypeMethod) { walk_ty_method(self, t) }
+    fn visit_trait_item(&mut self, t: &TraitItem) { walk_trait_item(self, t) }
+    fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId) {
+        walk_struct_def(self, s)
+    }
+    fn visit_struct_field(&mut self, s: &StructField) { walk_struct_field(self, s) }
+    fn visit_variant(&mut self, v: &Variant, g: &Generics) { walk_variant(self, v, g) }
     fn visit_opt_lifetime_ref(&mut self,
                               _span: Span,
-                              opt_lifetime: &Option<Lifetime>,
-                              env: E) {
+                              opt_lifetime: &Option<Lifetime>) {
         /*!
          * Visits an optional reference to a lifetime. The `span` is
          * the span of some surrounding reference should opt_lifetime
          * be None.
          */
         match *opt_lifetime {
-            Some(ref l) => self.visit_lifetime_ref(l, env),
+            Some(ref l) => self.visit_lifetime_ref(l),
             None => ()
         }
     }
-    fn visit_lifetime_ref(&mut self, _lifetime: &Lifetime, _e: E) {
+    fn visit_lifetime_ref(&mut self, _lifetime: &Lifetime) {
         /*! Visits a reference to a lifetime */
     }
-    fn visit_lifetime_decl(&mut self, _lifetime: &LifetimeDef, _e: E) {
+    fn visit_lifetime_decl(&mut self, _lifetime: &LifetimeDef) {
         /*! Visits a declaration of a lifetime */
     }
-    fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
-        walk_explicit_self(self, es, e)
+    fn visit_explicit_self(&mut self, es: &ExplicitSelf) {
+        walk_explicit_self(self, es)
     }
-    fn visit_mac(&mut self, _macro: &Mac, _e: E) {
+    fn visit_mac(&mut self, _macro: &Mac) {
         fail!("visit_mac disabled by default");
         // NB: see note about macros above.
         // if you really want a visitor that
         // works on macros, use this
         // definition in your trait impl:
-        // visit::walk_mac(self, _macro, _e)
+        // visit::walk_mac(self, _macro)
     }
-    fn visit_path(&mut self, path: &Path, _id: ast::NodeId, e: E) {
-        walk_path(self, path, e)
+    fn visit_path(&mut self, path: &Path, _id: ast::NodeId) {
+        walk_path(self, path)
     }
-    fn visit_attribute(&mut self, _attr: &Attribute, _e: E) {}
+    fn visit_attribute(&mut self, _attr: &Attribute) {}
 }
 
-pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                  item: &ast::InlinedItem,
-                                                  env: E) {
+pub fn walk_inlined_item<V: Visitor>(visitor: &mut V, item: &ast::InlinedItem) {
     match *item {
-        IIItem(i) => visitor.visit_item(&*i, env),
-        IIForeign(i) => visitor.visit_foreign_item(&*i, env),
+        IIItem(i) => visitor.visit_item(&*i),
+        IIForeign(i) => visitor.visit_foreign_item(&*i),
         IITraitItem(_, iti) => {
             match iti {
                 ProvidedInlinedTraitItem(m) => {
-                    walk_method_helper(visitor, &*m, env)
+                    walk_method_helper(visitor, &*m)
                 }
                 RequiredInlinedTraitItem(m) => {
-                    walk_method_helper(visitor, &*m, env)
+                    walk_method_helper(visitor, &*m)
                 }
             }
         }
@@ -158,637 +154,600 @@ pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
 }
 
 
-pub fn walk_crate<E: Clone, V: Visitor<E>>(visitor: &mut V, krate: &Crate, env: E) {
-    visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID, env.clone());
+pub fn walk_crate<V: Visitor>(visitor: &mut V, krate: &Crate) {
+    visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
     for attr in krate.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn walk_mod<E: Clone, V: Visitor<E>>(visitor: &mut V, module: &Mod, env: E) {
+pub fn walk_mod<V: Visitor>(visitor: &mut V, module: &Mod) {
     for view_item in module.view_items.iter() {
-        visitor.visit_view_item(view_item, env.clone())
+        visitor.visit_view_item(view_item)
     }
 
     for item in module.items.iter() {
-        visitor.visit_item(&**item, env.clone())
+        visitor.visit_item(&**item)
     }
 }
 
-pub fn walk_view_item<E: Clone, V: Visitor<E>>(visitor: &mut V, vi: &ViewItem, env: E) {
+pub fn walk_view_item<V: Visitor>(visitor: &mut V, vi: &ViewItem) {
     match vi.node {
         ViewItemExternCrate(name, _, _) => {
-            visitor.visit_ident(vi.span, name, env.clone())
+            visitor.visit_ident(vi.span, name)
         }
         ViewItemUse(ref vp) => {
             match vp.node {
                 ViewPathSimple(ident, ref path, id) => {
-                    visitor.visit_ident(vp.span, ident, env.clone());
-                    visitor.visit_path(path, id, env.clone());
+                    visitor.visit_ident(vp.span, ident);
+                    visitor.visit_path(path, id);
                 }
                 ViewPathGlob(ref path, id) => {
-                    visitor.visit_path(path, id, env.clone());
+                    visitor.visit_path(path, id);
                 }
                 ViewPathList(ref path, ref list, _) => {
                     for id in list.iter() {
                         match id.node {
                             PathListIdent { name, .. } => {
-                                visitor.visit_ident(id.span, name, env.clone());
+                                visitor.visit_ident(id.span, name);
                             }
                             PathListMod { .. } => ()
                         }
                     }
-                    walk_path(visitor, path, env.clone());
+                    walk_path(visitor, path);
                 }
             }
         }
     }
     for attr in vi.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn walk_local<E: Clone, V: Visitor<E>>(visitor: &mut V, local: &Local, env: E) {
-    visitor.visit_pat(&*local.pat, env.clone());
-    visitor.visit_ty(&*local.ty, env.clone());
+pub fn walk_local<V: Visitor>(visitor: &mut V, local: &Local) {
+    visitor.visit_pat(&*local.pat);
+    visitor.visit_ty(&*local.ty);
     match local.init {
         None => {}
-        Some(initializer) => visitor.visit_expr(&*initializer, env),
+        Some(initializer) => visitor.visit_expr(&*initializer),
     }
 }
 
-pub fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                   explicit_self: &ExplicitSelf,
-                                                   env: E) {
+pub fn walk_explicit_self<V: Visitor>(visitor: &mut V, explicit_self: &ExplicitSelf) {
     match explicit_self.node {
         SelfStatic | SelfValue(_) => {},
         SelfRegion(ref lifetime, _, _) => {
-            visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
+            visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime)
         }
-        SelfExplicit(ref typ, _) => visitor.visit_ty(&**typ, env.clone()),
+        SelfExplicit(ref typ, _) => visitor.visit_ty(&**typ),
     }
 }
 
 /// Like with walk_method_helper this doesn't correspond to a method
 /// in Visitor, and so it gets a _helper suffix.
-pub fn walk_trait_ref_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                      trait_ref: &TraitRef,
-                                                      env: E) {
-    visitor.visit_path(&trait_ref.path, trait_ref.ref_id, env)
+pub fn walk_trait_ref_helper<V: Visitor>(visitor: &mut V, trait_ref: &TraitRef) {
+    visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
 }
 
-pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E) {
-    visitor.visit_ident(item.span, item.ident, env.clone());
+pub fn walk_item<V: Visitor>(visitor: &mut V, item: &Item) {
+    visitor.visit_ident(item.span, item.ident);
     match item.node {
         ItemStatic(ref typ, _, ref expr) => {
-            visitor.visit_ty(&**typ, env.clone());
-            visitor.visit_expr(&**expr, env.clone());
+            visitor.visit_ty(&**typ);
+            visitor.visit_expr(&**expr);
         }
         ItemFn(declaration, fn_style, abi, ref generics, body) => {
             visitor.visit_fn(&FkItemFn(item.ident, generics, fn_style, abi),
                              &*declaration,
                              &*body,
                              item.span,
-                             item.id,
-                             env.clone())
+                             item.id)
         }
         ItemMod(ref module) => {
-            visitor.visit_mod(module, item.span, item.id, env.clone())
+            visitor.visit_mod(module, item.span, item.id)
         }
         ItemForeignMod(ref foreign_module) => {
             for view_item in foreign_module.view_items.iter() {
-                visitor.visit_view_item(view_item, env.clone())
+                visitor.visit_view_item(view_item)
             }
             for foreign_item in foreign_module.items.iter() {
-                visitor.visit_foreign_item(&**foreign_item, env.clone())
+                visitor.visit_foreign_item(&**foreign_item)
             }
         }
         ItemTy(ref typ, ref type_parameters) => {
-            visitor.visit_ty(&**typ, env.clone());
-            visitor.visit_generics(type_parameters, env.clone())
+            visitor.visit_ty(&**typ);
+            visitor.visit_generics(type_parameters)
         }
         ItemEnum(ref enum_definition, ref type_parameters) => {
-            visitor.visit_generics(type_parameters, env.clone());
-            walk_enum_def(visitor, enum_definition, type_parameters, env.clone())
+            visitor.visit_generics(type_parameters);
+            walk_enum_def(visitor, enum_definition, type_parameters)
         }
         ItemImpl(ref type_parameters,
                  ref trait_reference,
                  typ,
                  ref impl_items) => {
-            visitor.visit_generics(type_parameters, env.clone());
+            visitor.visit_generics(type_parameters);
             match *trait_reference {
                 Some(ref trait_reference) => walk_trait_ref_helper(visitor,
-                                                                   trait_reference, env.clone()),
+                                                                   trait_reference),
                 None => ()
             }
-            visitor.visit_ty(&*typ, env.clone());
+            visitor.visit_ty(&*typ);
             for impl_item in impl_items.iter() {
                 match *impl_item {
                     MethodImplItem(method) => {
-                        walk_method_helper(visitor, &*method, env.clone())
+                        walk_method_helper(visitor, &*method)
                     }
                 }
             }
         }
         ItemStruct(ref struct_definition, ref generics) => {
-            visitor.visit_generics(generics, env.clone());
+            visitor.visit_generics(generics);
             visitor.visit_struct_def(&**struct_definition,
                                      item.ident,
                                      generics,
-                                     item.id,
-                                     env.clone())
+                                     item.id)
         }
         ItemTrait(ref generics, _, ref bounds, ref methods) => {
-            visitor.visit_generics(generics, env.clone());
-            walk_ty_param_bounds(visitor, bounds, env.clone());
+            visitor.visit_generics(generics);
+            walk_ty_param_bounds(visitor, bounds);
             for method in methods.iter() {
-                visitor.visit_trait_item(method, env.clone())
+                visitor.visit_trait_item(method)
             }
         }
-        ItemMac(ref macro) => visitor.visit_mac(macro, env.clone()),
+        ItemMac(ref macro) => visitor.visit_mac(macro),
     }
     for attr in item.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn walk_enum_def<E: Clone, V:Visitor<E>>(visitor: &mut V,
-                                             enum_definition: &EnumDef,
-                                             generics: &Generics,
-                                             env: E) {
+pub fn walk_enum_def<V: Visitor>(visitor: &mut V,
+                                 enum_definition: &EnumDef,
+                                 generics: &Generics) {
     for &variant in enum_definition.variants.iter() {
-        visitor.visit_variant(&*variant, generics, env.clone());
+        visitor.visit_variant(&*variant, generics);
     }
 }
 
-pub fn walk_variant<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                             variant: &Variant,
-                                             generics: &Generics,
-                                             env: E) {
-    visitor.visit_ident(variant.span, variant.node.name, env.clone());
+pub fn walk_variant<V: Visitor>(visitor: &mut V,
+                                variant: &Variant,
+                                generics: &Generics) {
+    visitor.visit_ident(variant.span, variant.node.name);
 
     match variant.node.kind {
         TupleVariantKind(ref variant_arguments) => {
             for variant_argument in variant_arguments.iter() {
-                visitor.visit_ty(&*variant_argument.ty, env.clone())
+                visitor.visit_ty(&*variant_argument.ty)
             }
         }
         StructVariantKind(ref struct_definition) => {
             visitor.visit_struct_def(&**struct_definition,
                                      variant.node.name,
                                      generics,
-                                     variant.node.id,
-                                     env.clone())
+                                     variant.node.id)
         }
     }
     match variant.node.disr_expr {
-        Some(ref expr) => visitor.visit_expr(&**expr, env.clone()),
+        Some(ref expr) => visitor.visit_expr(&**expr),
         None => ()
     }
     for attr in variant.node.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn skip_ty<E, V: Visitor<E>>(_: &mut V, _: &Ty, _: E) {
+pub fn skip_ty<V: Visitor>(_: &mut V, _: &Ty) {
     // Empty!
 }
 
-pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
+pub fn walk_ty<V: Visitor>(visitor: &mut V, typ: &Ty) {
     match typ.node {
         TyUniq(ty) | TyVec(ty) | TyBox(ty) | TyParen(ty) => {
-            visitor.visit_ty(&*ty, env)
+            visitor.visit_ty(&*ty)
         }
         TyPtr(ref mutable_type) => {
-            visitor.visit_ty(&*mutable_type.ty, env)
+            visitor.visit_ty(&*mutable_type.ty)
         }
         TyRptr(ref lifetime, ref mutable_type) => {
-            visitor.visit_opt_lifetime_ref(typ.span, lifetime, env.clone());
-            visitor.visit_ty(&*mutable_type.ty, env)
+            visitor.visit_opt_lifetime_ref(typ.span, lifetime);
+            visitor.visit_ty(&*mutable_type.ty)
         }
         TyTup(ref tuple_element_types) => {
             for &tuple_element_type in tuple_element_types.iter() {
-                visitor.visit_ty(&*tuple_element_type, env.clone())
+                visitor.visit_ty(&*tuple_element_type)
             }
         }
         TyClosure(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
-                visitor.visit_ty(&*argument.ty, env.clone())
+                visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output, env.clone());
-            walk_ty_param_bounds(visitor, &function_declaration.bounds,
-                                 env.clone());
-            walk_lifetime_decls(visitor, &function_declaration.lifetimes,
-                                env.clone());
+            visitor.visit_ty(&*function_declaration.decl.output);
+            walk_ty_param_bounds(visitor, &function_declaration.bounds);
+            walk_lifetime_decls(visitor, &function_declaration.lifetimes);
         }
         TyProc(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
-                visitor.visit_ty(&*argument.ty, env.clone())
+                visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output, env.clone());
-            walk_ty_param_bounds(visitor, &function_declaration.bounds,
-                                 env.clone());
-            walk_lifetime_decls(visitor, &function_declaration.lifetimes,
-                                env.clone());
+            visitor.visit_ty(&*function_declaration.decl.output);
+            walk_ty_param_bounds(visitor, &function_declaration.bounds);
+            walk_lifetime_decls(visitor, &function_declaration.lifetimes);
         }
         TyBareFn(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
-                visitor.visit_ty(&*argument.ty, env.clone())
+                visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output, env.clone());
-            walk_lifetime_decls(visitor, &function_declaration.lifetimes,
-                                env.clone());
+            visitor.visit_ty(&*function_declaration.decl.output);
+            walk_lifetime_decls(visitor, &function_declaration.lifetimes);
         }
         TyUnboxedFn(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
-                visitor.visit_ty(&*argument.ty, env.clone())
+                visitor.visit_ty(&*argument.ty)
             }
-            visitor.visit_ty(&*function_declaration.decl.output, env.clone());
+            visitor.visit_ty(&*function_declaration.decl.output);
         }
         TyPath(ref path, ref opt_bounds, id) => {
-            visitor.visit_path(path, id, env.clone());
+            visitor.visit_path(path, id);
             match *opt_bounds {
                 Some(ref bounds) => {
-                    walk_ty_param_bounds(visitor, bounds, env.clone());
+                    walk_ty_param_bounds(visitor, bounds);
                 }
                 None => { }
             }
         }
         TyFixedLengthVec(ref ty, ref expression) => {
-            visitor.visit_ty(&**ty, env.clone());
-            visitor.visit_expr(&**expression, env)
+            visitor.visit_ty(&**ty);
+            visitor.visit_expr(&**expression)
         }
         TyTypeof(ref expression) => {
-            visitor.visit_expr(&**expression, env)
+            visitor.visit_expr(&**expression)
         }
         TyNil | TyBot | TyInfer => {}
     }
 }
 
-fn walk_lifetime_decls<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                lifetimes: &Vec<LifetimeDef>,
-                                                env: E) {
+fn walk_lifetime_decls<V: Visitor>(visitor: &mut V, lifetimes: &Vec<LifetimeDef>) {
     for l in lifetimes.iter() {
-        visitor.visit_lifetime_decl(l, env.clone());
+        visitor.visit_lifetime_decl(l);
     }
 }
 
-pub fn walk_path<E: Clone, V: Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
+pub fn walk_path<V: Visitor>(visitor: &mut V, path: &Path) {
     for segment in path.segments.iter() {
-        visitor.visit_ident(path.span, segment.identifier, env.clone());
+        visitor.visit_ident(path.span, segment.identifier);
 
         for typ in segment.types.iter() {
-            visitor.visit_ty(&**typ, env.clone());
+            visitor.visit_ty(&**typ);
         }
         for lifetime in segment.lifetimes.iter() {
-            visitor.visit_lifetime_ref(lifetime, env.clone());
+            visitor.visit_lifetime_ref(lifetime);
         }
     }
 }
 
-pub fn walk_pat<E: Clone, V: Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E) {
+pub fn walk_pat<V: Visitor>(visitor: &mut V, pattern: &Pat) {
     match pattern.node {
         PatEnum(ref path, ref children) => {
-            visitor.visit_path(path, pattern.id, env.clone());
+            visitor.visit_path(path, pattern.id);
             for children in children.iter() {
                 for child in children.iter() {
-                    visitor.visit_pat(&**child, env.clone())
+                    visitor.visit_pat(&**child)
                 }
             }
         }
         PatStruct(ref path, ref fields, _) => {
-            visitor.visit_path(path, pattern.id, env.clone());
+            visitor.visit_path(path, pattern.id);
             for field in fields.iter() {
-                visitor.visit_pat(&*field.pat, env.clone())
+                visitor.visit_pat(&*field.pat)
             }
         }
         PatTup(ref tuple_elements) => {
             for tuple_element in tuple_elements.iter() {
-                visitor.visit_pat(&**tuple_element, env.clone())
+                visitor.visit_pat(&**tuple_element)
             }
         }
         PatBox(ref subpattern) |
         PatRegion(ref subpattern) => {
-            visitor.visit_pat(&**subpattern, env)
+            visitor.visit_pat(&**subpattern)
         }
         PatIdent(_, ref pth1, ref optional_subpattern) => {
-            visitor.visit_ident(pth1.span, pth1.node, env.clone());
+            visitor.visit_ident(pth1.span, pth1.node);
             match *optional_subpattern {
                 None => {}
-                Some(ref subpattern) => visitor.visit_pat(&**subpattern, env),
+                Some(ref subpattern) => visitor.visit_pat(&**subpattern),
             }
         }
-        PatLit(ref expression) => visitor.visit_expr(&**expression, env),
+        PatLit(ref expression) => visitor.visit_expr(&**expression),
         PatRange(ref lower_bound, ref upper_bound) => {
-            visitor.visit_expr(&**lower_bound, env.clone());
-            visitor.visit_expr(&**upper_bound, env)
+            visitor.visit_expr(&**lower_bound);
+            visitor.visit_expr(&**upper_bound)
         }
         PatWild(_) => (),
         PatVec(ref prepattern, ref slice_pattern, ref postpatterns) => {
             for prepattern in prepattern.iter() {
-                visitor.visit_pat(&**prepattern, env.clone())
+                visitor.visit_pat(&**prepattern)
             }
             for slice_pattern in slice_pattern.iter() {
-                visitor.visit_pat(&**slice_pattern, env.clone())
+                visitor.visit_pat(&**slice_pattern)
             }
             for postpattern in postpatterns.iter() {
-                visitor.visit_pat(&**postpattern, env.clone())
+                visitor.visit_pat(&**postpattern)
             }
         }
-        PatMac(ref macro) => visitor.visit_mac(macro, env),
+        PatMac(ref macro) => visitor.visit_mac(macro),
     }
 }
 
-pub fn walk_foreign_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                  foreign_item: &ForeignItem,
-                                                  env: E) {
-    visitor.visit_ident(foreign_item.span, foreign_item.ident, env.clone());
+pub fn walk_foreign_item<V: Visitor>(visitor: &mut V, foreign_item: &ForeignItem) {
+    visitor.visit_ident(foreign_item.span, foreign_item.ident);
 
     match foreign_item.node {
         ForeignItemFn(ref function_declaration, ref generics) => {
-            walk_fn_decl(visitor, &**function_declaration, env.clone());
-            visitor.visit_generics(generics, env.clone())
+            walk_fn_decl(visitor, &**function_declaration);
+            visitor.visit_generics(generics)
         }
-        ForeignItemStatic(ref typ, _) => visitor.visit_ty(&**typ, env.clone()),
+        ForeignItemStatic(ref typ, _) => visitor.visit_ty(&**typ),
     }
 
     for attr in foreign_item.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn walk_ty_param_bounds<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                     bounds: &OwnedSlice<TyParamBound>,
-                                                     env: E) {
+pub fn walk_ty_param_bounds<V: Visitor>(visitor: &mut V,
+                                        bounds: &OwnedSlice<TyParamBound>) {
     for bound in bounds.iter() {
         match *bound {
             TraitTyParamBound(ref typ) => {
-                walk_trait_ref_helper(visitor, typ, env.clone())
+                walk_trait_ref_helper(visitor, typ)
             }
             UnboxedFnTyParamBound(ref function_declaration) => {
                 for argument in function_declaration.decl.inputs.iter() {
-                    visitor.visit_ty(&*argument.ty, env.clone())
+                    visitor.visit_ty(&*argument.ty)
                 }
-                visitor.visit_ty(&*function_declaration.decl.output,
-                                 env.clone());
+                visitor.visit_ty(&*function_declaration.decl.output);
             }
             RegionTyParamBound(ref lifetime) => {
-                visitor.visit_lifetime_ref(lifetime, env.clone());
+                visitor.visit_lifetime_ref(lifetime);
             }
         }
     }
 }
 
-pub fn walk_generics<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                              generics: &Generics,
-                                              env: E) {
+pub fn walk_generics<V: Visitor>(visitor: &mut V, generics: &Generics) {
     for type_parameter in generics.ty_params.iter() {
-        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone());
+        walk_ty_param_bounds(visitor, &type_parameter.bounds);
         match type_parameter.default {
-            Some(ref ty) => visitor.visit_ty(&**ty, env.clone()),
+            Some(ref ty) => visitor.visit_ty(&**ty),
             None => {}
         }
     }
-    walk_lifetime_decls(visitor, &generics.lifetimes, env.clone());
+    walk_lifetime_decls(visitor, &generics.lifetimes);
     for predicate in generics.where_clause.predicates.iter() {
-        visitor.visit_ident(predicate.span, predicate.ident, env.clone());
-        walk_ty_param_bounds(visitor, &predicate.bounds, env.clone());
+        visitor.visit_ident(predicate.span, predicate.ident);
+        walk_ty_param_bounds(visitor, &predicate.bounds);
     }
 }
 
-pub fn walk_fn_decl<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                             function_declaration: &FnDecl,
-                                             env: E) {
+pub fn walk_fn_decl<V: Visitor>(visitor: &mut V, function_declaration: &FnDecl) {
     for argument in function_declaration.inputs.iter() {
-        visitor.visit_pat(&*argument.pat, env.clone());
-        visitor.visit_ty(&*argument.ty, env.clone())
+        visitor.visit_pat(&*argument.pat);
+        visitor.visit_ty(&*argument.ty)
     }
-    visitor.visit_ty(&*function_declaration.output, env)
+    visitor.visit_ty(&*function_declaration.output)
 }
 
 // Note: there is no visit_method() method in the visitor, instead override
 // visit_fn() and check for FkMethod().  I named this visit_method_helper()
 // because it is not a default impl of any method, though I doubt that really
 // clarifies anything. - Niko
-pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                   method: &Method,
-                                                   env: E) {
+pub fn walk_method_helper<V: Visitor>(visitor: &mut V, method: &Method) {
     match method.node {
         MethDecl(ident, ref generics, _, _, _, decl, body, _) => {
-            visitor.visit_ident(method.span, ident, env.clone());
+            visitor.visit_ident(method.span, ident);
             visitor.visit_fn(&FkMethod(ident, generics, method),
                              &*decl,
                              &*body,
                              method.span,
-                             method.id,
-                             env.clone());
+                             method.id);
             for attr in method.attrs.iter() {
-                visitor.visit_attribute(attr, env.clone());
+                visitor.visit_attribute(attr);
             }
 
         },
-        MethMac(ref mac) => visitor.visit_mac(mac, env.clone())
+        MethMac(ref mac) => visitor.visit_mac(mac)
     }
 }
 
-pub fn walk_fn<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                        function_kind: &FnKind,
-                                        function_declaration: &FnDecl,
-                                        function_body: &Block,
-                                        _span: Span,
-                                        env: E) {
-    walk_fn_decl(visitor, function_declaration, env.clone());
+pub fn walk_fn<V: Visitor>(visitor: &mut V,
+                           function_kind: &FnKind,
+                           function_declaration: &FnDecl,
+                           function_body: &Block,
+                           _span: Span) {
+    walk_fn_decl(visitor, function_declaration);
 
     match *function_kind {
         FkItemFn(_, generics, _, _) => {
-            visitor.visit_generics(generics, env.clone());
+            visitor.visit_generics(generics);
         }
         FkMethod(_, generics, method) => {
-            visitor.visit_generics(generics, env.clone());
+            visitor.visit_generics(generics);
             match method.node {
                 MethDecl(_, _, _, ref explicit_self, _, _, _, _) =>
-                    visitor.visit_explicit_self(explicit_self, env.clone()),
+                    visitor.visit_explicit_self(explicit_self),
                 MethMac(ref mac) =>
-                    visitor.visit_mac(mac, env.clone())
+                    visitor.visit_mac(mac)
             }
         }
         FkFnBlock(..) => {}
     }
 
-    visitor.visit_block(function_body, env)
+    visitor.visit_block(function_body)
 }
 
-pub fn walk_ty_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                               method_type: &TypeMethod,
-                                               env: E) {
-    visitor.visit_ident(method_type.span, method_type.ident, env.clone());
-    visitor.visit_explicit_self(&method_type.explicit_self, env.clone());
+pub fn walk_ty_method<V: Visitor>(visitor: &mut V, method_type: &TypeMethod) {
+    visitor.visit_ident(method_type.span, method_type.ident);
+    visitor.visit_explicit_self(&method_type.explicit_self);
     for argument_type in method_type.decl.inputs.iter() {
-        visitor.visit_ty(&*argument_type.ty, env.clone())
+        visitor.visit_ty(&*argument_type.ty)
     }
-    visitor.visit_generics(&method_type.generics, env.clone());
-    visitor.visit_ty(&*method_type.decl.output, env.clone());
+    visitor.visit_generics(&method_type.generics);
+    visitor.visit_ty(&*method_type.decl.output);
     for attr in method_type.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn walk_trait_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                  trait_method: &TraitItem,
-                                                  env: E) {
+pub fn walk_trait_item<V: Visitor>(visitor: &mut V, trait_method: &TraitItem) {
     match *trait_method {
         RequiredMethod(ref method_type) => {
-            visitor.visit_ty_method(method_type, env)
+            visitor.visit_ty_method(method_type)
         }
-        ProvidedMethod(ref method) => walk_method_helper(visitor, &**method, env),
+        ProvidedMethod(ref method) => walk_method_helper(visitor, &**method),
     }
 }
 
-pub fn walk_struct_def<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                struct_definition: &StructDef,
-                                                env: E) {
+pub fn walk_struct_def<V: Visitor>(visitor: &mut V,
+                                   struct_definition: &StructDef) {
     match struct_definition.super_struct {
-        Some(ref t) => visitor.visit_ty(&**t, env.clone()),
+        Some(ref t) => visitor.visit_ty(&**t),
         None => {},
     }
     for field in struct_definition.fields.iter() {
-        visitor.visit_struct_field(field, env.clone())
+        visitor.visit_struct_field(field)
     }
 }
 
-pub fn walk_struct_field<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                  struct_field: &StructField,
-                                                  env: E) {
+pub fn walk_struct_field<V: Visitor>(visitor: &mut V,
+                                     struct_field: &StructField) {
     match struct_field.node.kind {
         NamedField(name, _) => {
-            visitor.visit_ident(struct_field.span, name, env.clone())
+            visitor.visit_ident(struct_field.span, name)
         }
         _ => {}
     }
 
-    visitor.visit_ty(&*struct_field.node.ty, env.clone());
+    visitor.visit_ty(&*struct_field.node.ty);
 
     for attr in struct_field.node.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }
 
-pub fn walk_block<E: Clone, V: Visitor<E>>(visitor: &mut V, block: &Block, env: E) {
+pub fn walk_block<V: Visitor>(visitor: &mut V, block: &Block) {
     for view_item in block.view_items.iter() {
-        visitor.visit_view_item(view_item, env.clone())
+        visitor.visit_view_item(view_item)
     }
     for statement in block.stmts.iter() {
-        visitor.visit_stmt(&**statement, env.clone())
+        visitor.visit_stmt(&**statement)
     }
-    walk_expr_opt(visitor, block.expr, env)
+    walk_expr_opt(visitor, block.expr)
 }
 
-pub fn walk_stmt<E: Clone, V: Visitor<E>>(visitor: &mut V, statement: &Stmt, env: E) {
+pub fn walk_stmt<V: Visitor>(visitor: &mut V, statement: &Stmt) {
     match statement.node {
-        StmtDecl(ref declaration, _) => visitor.visit_decl(&**declaration, env),
+        StmtDecl(ref declaration, _) => visitor.visit_decl(&**declaration),
         StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => {
-            visitor.visit_expr(&**expression, env)
+            visitor.visit_expr(&**expression)
         }
-        StmtMac(ref macro, _) => visitor.visit_mac(macro, env),
+        StmtMac(ref macro, _) => visitor.visit_mac(macro),
     }
 }
 
-pub fn walk_decl<E: Clone, V: Visitor<E>>(visitor: &mut V, declaration: &Decl, env: E) {
+pub fn walk_decl<V: Visitor>(visitor: &mut V, declaration: &Decl) {
     match declaration.node {
-        DeclLocal(ref local) => visitor.visit_local(&**local, env),
-        DeclItem(ref item) => visitor.visit_item(&**item, env),
+        DeclLocal(ref local) => visitor.visit_local(&**local),
+        DeclItem(ref item) => visitor.visit_item(&**item),
     }
 }
 
-pub fn walk_expr_opt<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                              optional_expression: Option<Gc<Expr>>,
-                                              env: E) {
+pub fn walk_expr_opt<V: Visitor>(visitor: &mut V,
+                                 optional_expression: Option<Gc<Expr>>) {
     match optional_expression {
         None => {}
-        Some(ref expression) => visitor.visit_expr(&**expression, env),
+        Some(ref expression) => visitor.visit_expr(&**expression),
     }
 }
 
-pub fn walk_exprs<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                           expressions: &[Gc<Expr>],
-                                           env: E) {
+pub fn walk_exprs<V: Visitor>(visitor: &mut V, expressions: &[Gc<Expr>]) {
     for expression in expressions.iter() {
-        visitor.visit_expr(&**expression, env.clone())
+        visitor.visit_expr(&**expression)
     }
 }
 
-pub fn walk_mac<E, V: Visitor<E>>(_: &mut V, _: &Mac, _: E) {
+pub fn walk_mac<V: Visitor>(_: &mut V, _: &Mac) {
     // Empty!
 }
 
-pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, env: E) {
+pub fn walk_expr<V: Visitor>(visitor: &mut V, expression: &Expr) {
     match expression.node {
         ExprBox(ref place, ref subexpression) => {
-            visitor.visit_expr(&**place, env.clone());
-            visitor.visit_expr(&**subexpression, env.clone())
+            visitor.visit_expr(&**place);
+            visitor.visit_expr(&**subexpression)
         }
         ExprVec(ref subexpressions) => {
-            walk_exprs(visitor, subexpressions.as_slice(), env.clone())
+            walk_exprs(visitor, subexpressions.as_slice())
         }
         ExprRepeat(ref element, ref count) => {
-            visitor.visit_expr(&**element, env.clone());
-            visitor.visit_expr(&**count, env.clone())
+            visitor.visit_expr(&**element);
+            visitor.visit_expr(&**count)
         }
         ExprStruct(ref path, ref fields, optional_base) => {
-            visitor.visit_path(path, expression.id, env.clone());
+            visitor.visit_path(path, expression.id);
             for field in fields.iter() {
-                visitor.visit_expr(&*field.expr, env.clone())
+                visitor.visit_expr(&*field.expr)
             }
-            walk_expr_opt(visitor, optional_base, env.clone())
+            walk_expr_opt(visitor, optional_base)
         }
         ExprTup(ref subexpressions) => {
             for subexpression in subexpressions.iter() {
-                visitor.visit_expr(&**subexpression, env.clone())
+                visitor.visit_expr(&**subexpression)
             }
         }
         ExprCall(ref callee_expression, ref arguments) => {
             for argument in arguments.iter() {
-                visitor.visit_expr(&**argument, env.clone())
+                visitor.visit_expr(&**argument)
             }
-            visitor.visit_expr(&**callee_expression, env.clone())
+            visitor.visit_expr(&**callee_expression)
         }
         ExprMethodCall(_, ref types, ref arguments) => {
-            walk_exprs(visitor, arguments.as_slice(), env.clone());
+            walk_exprs(visitor, arguments.as_slice());
             for typ in types.iter() {
-                visitor.visit_ty(&**typ, env.clone())
+                visitor.visit_ty(&**typ)
             }
         }
         ExprBinary(_, ref left_expression, ref right_expression) => {
-            visitor.visit_expr(&**left_expression, env.clone());
-            visitor.visit_expr(&**right_expression, env.clone())
+            visitor.visit_expr(&**left_expression);
+            visitor.visit_expr(&**right_expression)
         }
         ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => {
-            visitor.visit_expr(&**subexpression, env.clone())
+            visitor.visit_expr(&**subexpression)
         }
         ExprLit(_) => {}
         ExprCast(ref subexpression, ref typ) => {
-            visitor.visit_expr(&**subexpression, env.clone());
-            visitor.visit_ty(&**typ, env.clone())
+            visitor.visit_expr(&**subexpression);
+            visitor.visit_ty(&**typ)
         }
         ExprIf(ref head_expression, ref if_block, optional_else) => {
-            visitor.visit_expr(&**head_expression, env.clone());
-            visitor.visit_block(&**if_block, env.clone());
-            walk_expr_opt(visitor, optional_else, env.clone())
+            visitor.visit_expr(&**head_expression);
+            visitor.visit_block(&**if_block);
+            walk_expr_opt(visitor, optional_else)
         }
         ExprWhile(ref subexpression, ref block, _) => {
-            visitor.visit_expr(&**subexpression, env.clone());
-            visitor.visit_block(&**block, env.clone())
+            visitor.visit_expr(&**subexpression);
+            visitor.visit_block(&**block)
         }
         ExprForLoop(ref pattern, ref subexpression, ref block, _) => {
-            visitor.visit_pat(&**pattern, env.clone());
-            visitor.visit_expr(&**subexpression, env.clone());
-            visitor.visit_block(&**block, env.clone())
+            visitor.visit_pat(&**pattern);
+            visitor.visit_expr(&**subexpression);
+            visitor.visit_block(&**block)
         }
-        ExprLoop(ref block, _) => visitor.visit_block(&**block, env.clone()),
+        ExprLoop(ref block, _) => visitor.visit_block(&**block),
         ExprMatch(ref subexpression, ref arms) => {
-            visitor.visit_expr(&**subexpression, env.clone());
+            visitor.visit_expr(&**subexpression);
             for arm in arms.iter() {
-                visitor.visit_arm(arm, env.clone())
+                visitor.visit_arm(arm)
             }
         }
         ExprFnBlock(_, ref function_declaration, ref body) => {
@@ -796,81 +755,78 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
                              &**function_declaration,
                              &**body,
                              expression.span,
-                             expression.id,
-                             env.clone())
+                             expression.id)
         }
         ExprUnboxedFn(_, _, ref function_declaration, ref body) => {
             visitor.visit_fn(&FkFnBlock,
                              &**function_declaration,
                              &**body,
                              expression.span,
-                             expression.id,
-                             env.clone())
+                             expression.id)
         }
         ExprProc(ref function_declaration, ref body) => {
             visitor.visit_fn(&FkFnBlock,
                              &**function_declaration,
                              &**body,
                              expression.span,
-                             expression.id,
-                             env.clone())
+                             expression.id)
         }
-        ExprBlock(ref block) => visitor.visit_block(&**block, env.clone()),
+        ExprBlock(ref block) => visitor.visit_block(&**block),
         ExprAssign(ref left_hand_expression, ref right_hand_expression) => {
-            visitor.visit_expr(&**right_hand_expression, env.clone());
-            visitor.visit_expr(&**left_hand_expression, env.clone())
+            visitor.visit_expr(&**right_hand_expression);
+            visitor.visit_expr(&**left_hand_expression)
         }
         ExprAssignOp(_, ref left_expression, ref right_expression) => {
-            visitor.visit_expr(&**right_expression, env.clone());
-            visitor.visit_expr(&**left_expression, env.clone())
+            visitor.visit_expr(&**right_expression);
+            visitor.visit_expr(&**left_expression)
         }
         ExprField(ref subexpression, _, ref types) => {
-            visitor.visit_expr(&**subexpression, env.clone());
+            visitor.visit_expr(&**subexpression);
             for typ in types.iter() {
-                visitor.visit_ty(&**typ, env.clone())
+                visitor.visit_ty(&**typ)
             }
         }
         ExprTupField(ref subexpression, _, ref types) => {
-            visitor.visit_expr(&**subexpression, env.clone());
+            visitor.visit_expr(&**subexpression);
             for typ in types.iter() {
-                visitor.visit_ty(&**typ, env.clone())
+                visitor.visit_ty(&**typ)
             }
         }
         ExprIndex(ref main_expression, ref index_expression) => {
-            visitor.visit_expr(&**main_expression, env.clone());
-            visitor.visit_expr(&**index_expression, env.clone())
+            visitor.visit_expr(&**main_expression);
+            visitor.visit_expr(&**index_expression)
         }
         ExprPath(ref path) => {
-            visitor.visit_path(path, expression.id, env.clone())
+            visitor.visit_path(path, expression.id)
         }
         ExprBreak(_) | ExprAgain(_) => {}
         ExprRet(optional_expression) => {
-            walk_expr_opt(visitor, optional_expression, env.clone())
+            walk_expr_opt(visitor, optional_expression)
         }
-        ExprMac(ref macro) => visitor.visit_mac(macro, env.clone()),
+        ExprMac(ref macro) => visitor.visit_mac(macro),
         ExprParen(ref subexpression) => {
-            visitor.visit_expr(&**subexpression, env.clone())
+            visitor.visit_expr(&**subexpression)
         }
         ExprInlineAsm(ref ia) => {
             for &(_, ref input) in ia.inputs.iter() {
-                visitor.visit_expr(&**input, env.clone())
+                visitor.visit_expr(&**input)
             }
             for &(_, ref output, _) in ia.outputs.iter() {
-                visitor.visit_expr(&**output, env.clone())
+                visitor.visit_expr(&**output)
             }
         }
     }
 
-    visitor.visit_expr_post(expression, env.clone())
+    visitor.visit_expr_post(expression)
 }
 
-pub fn walk_arm<E: Clone, V: Visitor<E>>(visitor: &mut V, arm: &Arm, env: E) {
+pub fn walk_arm<V: Visitor>(visitor: &mut V, arm: &Arm) {
     for pattern in arm.pats.iter() {
-        visitor.visit_pat(&**pattern, env.clone())
+        visitor.visit_pat(&**pattern)
     }
-    walk_expr_opt(visitor, arm.guard, env.clone());
-    visitor.visit_expr(&*arm.body, env.clone());
+    walk_expr_opt(visitor, arm.guard);
+    visitor.visit_expr(&*arm.body);
     for attr in arm.attrs.iter() {
-        visitor.visit_attribute(attr, env.clone());
+        visitor.visit_attribute(attr);
     }
 }