diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 76532b5cd22..55425b64795 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -480,6 +480,7 @@ impl Context {
                             (orig.visit_item)(it, (self, stopping));
                         }
                         NewVisitor(new_visitor) => {
+                            let mut new_visitor = new_visitor;
                             new_visitor.visit_item(it, ());
                         }
                     }
@@ -492,7 +493,8 @@ impl Context {
                             oldvisit::visit_crate(c, (self, stopping))
                         }
                         NewVisitor(new_visitor) => {
-                            visit::visit_crate(new_visitor, c, ())
+                            let mut new_visitor = new_visitor;
+                            visit::walk_crate(&mut new_visitor, c, ())
                         }
                     }
                 }
@@ -518,6 +520,7 @@ impl Context {
                             let fk = visit::fk_method(m.ident,
                                                       &m.generics,
                                                       m);
+                            let mut new_visitor = new_visitor;
                             new_visitor.visit_fn(&fk,
                                                  &m.decl,
                                                  &m.body,
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 1fea0c2e6f9..6c3fb82965d 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -89,11 +89,11 @@ pub struct Ctx {
 }
 
 impl Ctx {
-    fn extend(@mut self, elt: ident) -> @path {
+    fn extend(&self, elt: ident) -> @path {
         @vec::append(self.path.clone(), [path_name(elt)])
     }
 
-    fn map_method(@mut self,
+    fn map_method(&mut self,
                   impl_did: def_id,
                   impl_path: @path,
                   m: @method,
@@ -107,7 +107,7 @@ impl Ctx {
         self.map.insert(m.self_id, node_local(special_idents::self_));
     }
 
-    fn map_struct_def(@mut self,
+    fn map_struct_def(&mut self,
                       struct_def: @ast::struct_def,
                       parent_node: ast_node,
                       ident: ast::ident) {
@@ -130,7 +130,7 @@ impl Ctx {
         }
     }
 
-    fn map_expr(@mut self, ex: @expr) {
+    fn map_expr(&mut self, ex: @expr) {
         self.map.insert(ex.id, node_expr(ex));
 
         // Expressions which are or might be calls:
@@ -141,10 +141,10 @@ impl Ctx {
             }
         }
 
-        visit::visit_expr(self as @mut Visitor<()>, ex, ());
+        visit::walk_expr(self, ex, ());
     }
 
-    fn map_fn(@mut self,
+    fn map_fn(&mut self,
               fk: &visit::fn_kind,
               decl: &fn_decl,
               body: &Block,
@@ -153,21 +153,21 @@ impl Ctx {
         for a in decl.inputs.iter() {
             self.map.insert(a.id, node_arg);
         }
-        visit::visit_fn(self as @mut Visitor<()>, fk, decl, body, sp, id, ());
+        visit::walk_fn(self, fk, decl, body, sp, id, ());
     }
 
-    fn map_stmt(@mut self, stmt: @stmt) {
+    fn map_stmt(&mut self, stmt: @stmt) {
         self.map.insert(stmt_id(stmt), node_stmt(stmt));
-        visit::visit_stmt(self as @mut Visitor<()>, stmt, ());
+        visit::walk_stmt(self, stmt, ());
     }
 
-    fn map_block(@mut self, b: &Block) {
+    fn map_block(&mut self, b: &Block) {
         // clone is FIXME #2543
         self.map.insert(b.id, node_block((*b).clone()));
-        visit::visit_block(self as @mut Visitor<()>, b, ());
+        visit::walk_block(self, b, ());
     }
 
-    fn map_pat(@mut self, pat: @pat) {
+    fn map_pat(&mut self, pat: @pat) {
         match pat.node {
             pat_ident(_, ref path, _) => {
                 // Note: this is at least *potentially* a pattern...
@@ -177,12 +177,12 @@ impl Ctx {
             _ => ()
         }
 
-        visit::visit_pat(self as @mut Visitor<()>, pat, ());
+        visit::walk_pat(self, pat, ());
     }
 }
 
 impl Visitor<()> for Ctx {
-    fn visit_item(@mut self, i: @item, _: ()) {
+    fn visit_item(&mut self, i: @item, _: ()) {
         // clone is FIXME #2543
         let item_path = @self.path.clone();
         self.map.insert(i.id, node_item(i, item_path));
@@ -190,7 +190,8 @@ impl Visitor<()> for Ctx {
             item_impl(_, _, _, ref ms) => {
                 let impl_did = ast_util::local_def(i.id);
                 for m in ms.iter() {
-                    self.map_method(impl_did, self.extend(i.ident), *m, false)
+                    let extended = { self.extend(i.ident) };
+                    self.map_method(impl_did, extended, *m, false)
                 }
             }
             item_enum(ref enum_definition, _) => {
@@ -254,24 +255,24 @@ impl Visitor<()> for Ctx {
             }
             _ => self.path.push(path_name(i.ident))
         }
-        visit::visit_item(self as @mut Visitor<()>, i, ());
+        visit::walk_item(self, i, ());
         self.path.pop();
     }
 
-    fn visit_pat(@mut self, pat: @pat, _: ()) {
+    fn visit_pat(&mut self, pat: @pat, _: ()) {
         self.map_pat(pat);
-        visit::visit_pat(self as @mut Visitor<()>, pat, ())
+        visit::walk_pat(self, pat, ())
     }
 
-    fn visit_expr(@mut self, expr: @expr, _: ()) {
+    fn visit_expr(&mut self, expr: @expr, _: ()) {
         self.map_expr(expr)
     }
 
-    fn visit_stmt(@mut self, stmt: @stmt, _: ()) {
+    fn visit_stmt(&mut self, stmt: @stmt, _: ()) {
         self.map_stmt(stmt)
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
@@ -281,56 +282,56 @@ impl Visitor<()> for Ctx {
         self.map_fn(function_kind, function_declaration, block, span, node_id)
     }
 
-    fn visit_block(@mut self, block: &Block, _: ()) {
+    fn visit_block(&mut self, block: &Block, _: ()) {
         self.map_block(block)
     }
 
     // XXX: Methods below can become default methods.
 
-    fn visit_mod(@mut self, module: &_mod, _: span, _: NodeId, _: ()) {
-        visit::visit_mod(self as @mut Visitor<()>, module, ())
+    fn visit_mod(&mut self, module: &_mod, _: span, _: NodeId, _: ()) {
+        visit::walk_mod(self, module, ())
     }
 
-    fn visit_view_item(@mut self, view_item: &view_item, _: ()) {
-        visit::visit_view_item(self as @mut Visitor<()>, view_item, ())
+    fn visit_view_item(&mut self, view_item: &view_item, _: ()) {
+        visit::walk_view_item(self, view_item, ())
     }
 
-    fn visit_foreign_item(@mut self, foreign_item: @foreign_item, _: ()) {
-        visit::visit_foreign_item(self as @mut Visitor<()>, foreign_item, ())
+    fn visit_foreign_item(&mut self, foreign_item: @foreign_item, _: ()) {
+        visit::walk_foreign_item(self, foreign_item, ())
     }
 
-    fn visit_local(@mut self, local: @Local, _: ()) {
-        visit::visit_local(self as @mut Visitor<()>, local, ())
+    fn visit_local(&mut self, local: @Local, _: ()) {
+        visit::walk_local(self, local, ())
     }
 
-    fn visit_arm(@mut self, arm: &arm, _: ()) {
-        visit::visit_arm(self as @mut Visitor<()>, arm, ())
+    fn visit_arm(&mut self, arm: &arm, _: ()) {
+        visit::walk_arm(self, arm, ())
     }
 
-    fn visit_decl(@mut self, decl: @decl, _: ()) {
-        visit::visit_decl(self as @mut Visitor<()>, decl, ())
+    fn visit_decl(&mut self, decl: @decl, _: ()) {
+        visit::walk_decl(self, decl, ())
     }
 
-    fn visit_expr_post(@mut self, _: @expr, _: ()) {
+    fn visit_expr_post(&mut self, _: @expr, _: ()) {
         // Empty!
     }
 
-    fn visit_ty(@mut self, typ: &Ty, _: ()) {
-        visit::visit_ty(self as @mut Visitor<()>, typ, ())
+    fn visit_ty(&mut self, typ: &Ty, _: ()) {
+        visit::walk_ty(self, typ, ())
     }
 
-    fn visit_generics(@mut self, generics: &Generics, _: ()) {
-        visit::visit_generics(self as @mut Visitor<()>, generics, ())
+    fn visit_generics(&mut self, generics: &Generics, _: ()) {
+        visit::walk_generics(self, generics, ())
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
                 span: span,
                 node_id: NodeId,
                 _: ()) {
-        visit::visit_fn(self as @mut Visitor<()>,
+        visit::walk_fn(self,
                         function_kind,
                         function_declaration,
                         block,
@@ -339,21 +340,21 @@ impl Visitor<()> for Ctx {
                         ())
     }
 
-    fn visit_ty_method(@mut self, ty_method: &TypeMethod, _: ()) {
-        visit::visit_ty_method(self as @mut Visitor<()>, ty_method, ())
+    fn visit_ty_method(&mut self, ty_method: &TypeMethod, _: ()) {
+        visit::walk_ty_method(self, ty_method, ())
     }
 
-    fn visit_trait_method(@mut self, trait_method: &trait_method, _: ()) {
-        visit::visit_trait_method(self as @mut Visitor<()>, trait_method, ())
+    fn visit_trait_method(&mut self, trait_method: &trait_method, _: ()) {
+        visit::walk_trait_method(self, trait_method, ())
     }
 
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_def: @struct_def,
                         ident: ident,
                         generics: &Generics,
                         node_id: NodeId,
                         _: ()) {
-        visit::visit_struct_def(self as @mut Visitor<()>,
+        visit::walk_struct_def(self,
                                 struct_def,
                                 ident,
                                 generics,
@@ -361,8 +362,8 @@ impl Visitor<()> for Ctx {
                                 ())
     }
 
-    fn visit_struct_field(@mut self, struct_field: @struct_field, _: ()) {
-        visit::visit_struct_field(self as @mut Visitor<()>, struct_field, ())
+    fn visit_struct_field(&mut self, struct_field: @struct_field, _: ()) {
+        visit::walk_struct_field(self, struct_field, ())
     }
 }
 
@@ -372,7 +373,7 @@ pub fn map_crate(diag: @mut span_handler, c: &Crate) -> map {
         path: ~[],
         diag: diag,
     };
-    visit::visit_crate(cx as @mut Visitor<()>, c, ());
+    visit::walk_crate(cx, c, ());
     cx.map
 }
 
@@ -409,7 +410,7 @@ pub fn map_decoded_item(diag: @mut span_handler,
     }
 
     // visit the item / method contents and add those to the map:
-    ii.accept((), cx as @mut Visitor<()>);
+    ii.accept((), cx);
 }
 
 pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 02eaf432b54..cfbe61ca65e 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -298,7 +298,7 @@ pub fn struct_field_visibility(field: ast::struct_field) -> visibility {
 pub trait inlined_item_utils {
     fn ident(&self) -> ident;
     fn id(&self) -> ast::NodeId;
-    fn accept<E: Clone>(&self, e: E, v: @mut Visitor<E>);
+    fn accept<E: Clone, V:Visitor<E>>(&self, e: E, v: &mut V);
 }
 
 impl inlined_item_utils for inlined_item {
@@ -318,11 +318,11 @@ impl inlined_item_utils for inlined_item {
         }
     }
 
-    fn accept<E: Clone>(&self, e: E, v: @mut Visitor<E>) {
+    fn accept<E: Clone, V:Visitor<E>>(&self, e: E, v: &mut V) {
         match *self {
             ii_item(i) => v.visit_item(i, e),
             ii_foreign(i) => v.visit_foreign_item(i, e),
-            ii_method(_, _, m) => visit::visit_method_helper(v, m, e),
+            ii_method(_, _, m) => visit::walk_method_helper(v, m, e),
         }
     }
 }
@@ -390,14 +390,24 @@ impl id_range {
     }
 }
 
-struct IdVisitor {
+pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool)
+                  -> @mut Visitor<()> {
+    let visitor = @mut IdVisitor {
+        visit_callback: vfn,
+        pass_through_items: pass_through_items,
+        visited_outermost: false,
+    };
+    visitor as @mut Visitor<()>
+}
+
+pub struct IdVisitor {
     visit_callback: @fn(NodeId),
     pass_through_items: bool,
     visited_outermost: bool,
 }
 
 impl IdVisitor {
-    fn visit_generics_helper(@mut self, generics: &Generics) {
+    fn visit_generics_helper(&self, generics: &Generics) {
         for type_parameter in generics.ty_params.iter() {
             (self.visit_callback)(type_parameter.id)
         }
@@ -408,16 +418,16 @@ impl IdVisitor {
 }
 
 impl Visitor<()> for IdVisitor {
-    fn visit_mod(@mut self,
+    fn visit_mod(&mut self,
                  module: &_mod,
                  _span: span,
                  node_id: NodeId,
                  env: ()) {
         (self.visit_callback)(node_id);
-        visit::visit_mod(self as @mut Visitor<()>, module, env)
+        visit::walk_mod(self, module, env)
     }
 
-    fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
+    fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
         match view_item.node {
             view_item_extern_mod(_, _, _, node_id) => {
                 (self.visit_callback)(node_id)
@@ -439,15 +449,15 @@ impl Visitor<()> for IdVisitor {
                 }
             }
         }
-        visit::visit_view_item(self as @mut Visitor<()>, view_item, env)
+        visit::walk_view_item(self, view_item, env)
     }
 
-    fn visit_foreign_item(@mut self, foreign_item: @foreign_item, env: ()) {
+    fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
         (self.visit_callback)(foreign_item.id);
-        visit::visit_foreign_item(self as @mut Visitor<()>, foreign_item, env)
+        visit::walk_foreign_item(self, foreign_item, env)
     }
 
-    fn visit_item(@mut self, item: @item, env: ()) {
+    fn visit_item(&mut self, item: @item, env: ()) {
         if !self.pass_through_items {
             if self.visited_outermost {
                 return
@@ -466,42 +476,42 @@ impl Visitor<()> for IdVisitor {
             _ => {}
         }
 
-        visit::visit_item(self as @mut Visitor<()>, item, env);
+        visit::walk_item(self, item, env);
 
         self.visited_outermost = false
     }
 
-    fn visit_local(@mut self, local: @Local, env: ()) {
+    fn visit_local(&mut self, local: @Local, env: ()) {
         (self.visit_callback)(local.id);
-        visit::visit_local(self as @mut Visitor<()>, local, env)
+        visit::walk_local(self, local, env)
     }
 
-    fn visit_block(@mut self, block: &Block, env: ()) {
+    fn visit_block(&mut self, block: &Block, env: ()) {
         (self.visit_callback)(block.id);
-        visit::visit_block(self as @mut Visitor<()>, block, env)
+        visit::walk_block(self, block, env)
     }
 
-    fn visit_stmt(@mut self, statement: @stmt, env: ()) {
+    fn visit_stmt(&mut self, statement: @stmt, env: ()) {
         (self.visit_callback)(ast_util::stmt_id(statement));
-        visit::visit_stmt(self as @mut Visitor<()>, statement, env)
+        visit::walk_stmt(self, statement, env)
     }
 
     // XXX: Default
-    fn visit_arm(@mut self, arm: &arm, env: ()) {
-        visit::visit_arm(self as @mut Visitor<()>, arm, env)
+    fn visit_arm(&mut self, arm: &arm, env: ()) {
+        visit::walk_arm(self, arm, env)
     }
 
-    fn visit_pat(@mut self, pattern: @pat, env: ()) {
+    fn visit_pat(&mut self, pattern: @pat, env: ()) {
         (self.visit_callback)(pattern.id);
-        visit::visit_pat(self as @mut Visitor<()>, pattern, env)
+        visit::walk_pat(self, pattern, env)
     }
 
     // XXX: Default
-    fn visit_decl(@mut self, declaration: @decl, env: ()) {
-        visit::visit_decl(self as @mut Visitor<()>, declaration, env)
+    fn visit_decl(&mut self, declaration: @decl, env: ()) {
+        visit::walk_decl(self, declaration, env)
     }
 
-    fn visit_expr(@mut self, expression: @expr, env: ()) {
+    fn visit_expr(&mut self, expression: @expr, env: ()) {
         {
             let optional_callee_id = expression.get_callee_id();
             for callee_id in optional_callee_id.iter() {
@@ -509,29 +519,29 @@ impl Visitor<()> for IdVisitor {
             }
         }
         (self.visit_callback)(expression.id);
-        visit::visit_expr(self as @mut Visitor<()>, expression, env)
+        visit::walk_expr(self, expression, env)
     }
 
     // XXX: Default
-    fn visit_expr_post(@mut self, _: @expr, _: ()) {
+    fn visit_expr_post(&mut self, _: @expr, _: ()) {
         // Empty!
     }
 
-    fn visit_ty(@mut self, typ: &Ty, env: ()) {
+    fn visit_ty(&mut self, typ: &Ty, env: ()) {
         (self.visit_callback)(typ.id);
         match typ.node {
             ty_path(_, _, id) => (self.visit_callback)(id),
             _ => {}
         }
-        visit::visit_ty(self as @mut Visitor<()>, typ, env)
+        visit::walk_ty(self, typ, env)
     }
 
-    fn visit_generics(@mut self, generics: &Generics, env: ()) {
+    fn visit_generics(&mut self, generics: &Generics, env: ()) {
         self.visit_generics_helper(generics);
-        visit::visit_generics(self as @mut Visitor<()>, generics, env)
+        visit::walk_generics(self, generics, env)
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &visit::fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
@@ -563,7 +573,7 @@ impl Visitor<()> for IdVisitor {
             (self.visit_callback)(argument.id)
         }
 
-        visit::visit_fn(self as @mut Visitor<()>,
+        visit::walk_fn(self,
                         function_kind,
                         function_declaration,
                         block,
@@ -580,23 +590,23 @@ impl Visitor<()> for IdVisitor {
     }
 
     // XXX: Default
-    fn visit_ty_method(@mut self, type_method: &TypeMethod, env: ()) {
-        visit::visit_ty_method(self as @mut Visitor<()>, type_method, env)
+    fn visit_ty_method(&mut self, type_method: &TypeMethod, env: ()) {
+        visit::walk_ty_method(self, type_method, env)
     }
 
     // XXX: Default
-    fn visit_trait_method(@mut self, trait_method: &trait_method, env: ()) {
-        visit::visit_trait_method(self as @mut Visitor<()>, trait_method, env)
+    fn visit_trait_method(&mut self, trait_method: &trait_method, env: ()) {
+        visit::walk_trait_method(self, trait_method, env)
     }
 
     // XXX: Default
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_definition: @struct_def,
                         identifier: ident,
                         generics: &Generics,
                         node_id: NodeId,
                         env: ()) {
-        visit::visit_struct_def(self as @mut Visitor<()>,
+        visit::walk_struct_def(self,
                                 struct_definition,
                                 identifier,
                                 generics,
@@ -604,24 +614,19 @@ impl Visitor<()> for IdVisitor {
                                 env)
     }
 
-    fn visit_struct_field(@mut self, struct_field: @struct_field, env: ()) {
+    fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
         (self.visit_callback)(struct_field.node.id);
-        visit::visit_struct_field(self as @mut Visitor<()>, struct_field, env)
+        visit::walk_struct_field(self, struct_field, env)
     }
 }
 
-pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool)
-                  -> @mut Visitor<()> {
-    let visitor = @mut IdVisitor {
+pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) {
+    let mut id_visitor = IdVisitor {
         visit_callback: vfn,
-        pass_through_items: pass_through_items,
+        pass_through_items: true,
         visited_outermost: false,
     };
-    visitor as @mut Visitor<()>
-}
-
-pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) {
-    item.accept((), id_visitor(|id| vfn(id), true));
+    item.accept((), &mut id_visitor);
 }
 
 pub fn compute_id_range(visit_ids_fn: &fn(@fn(NodeId))) -> id_range {
@@ -680,49 +685,49 @@ struct EachViewItemData {
 }
 
 impl SimpleVisitor for EachViewItemData {
-    fn visit_mod(@mut self, _: &_mod, _: span, _: NodeId) {
+    fn visit_mod(&mut self, _: &_mod, _: span, _: NodeId) {
         // XXX: Default method.
     }
-    fn visit_view_item(@mut self, view_item: &view_item) {
+    fn visit_view_item(&mut self, view_item: &view_item) {
         let _ = (self.callback)(view_item);
     }
-    fn visit_foreign_item(@mut self, _: @foreign_item) {
+    fn visit_foreign_item(&mut self, _: @foreign_item) {
         // XXX: Default method.
     }
-    fn visit_item(@mut self, _: @item) {
+    fn visit_item(&mut self, _: @item) {
         // XXX: Default method.
     }
-    fn visit_local(@mut self, _: @Local) {
+    fn visit_local(&mut self, _: @Local) {
         // XXX: Default method.
     }
-    fn visit_block(@mut self, _: &Block) {
+    fn visit_block(&mut self, _: &Block) {
         // XXX: Default method.
     }
-    fn visit_stmt(@mut self, _: @stmt) {
+    fn visit_stmt(&mut self, _: @stmt) {
         // XXX: Default method.
     }
-    fn visit_arm(@mut self, _: &arm) {
+    fn visit_arm(&mut self, _: &arm) {
         // XXX: Default method.
     }
-    fn visit_pat(@mut self, _: @pat) {
+    fn visit_pat(&mut self, _: @pat) {
         // XXX: Default method.
     }
-    fn visit_decl(@mut self, _: @decl) {
+    fn visit_decl(&mut self, _: @decl) {
         // XXX: Default method.
     }
-    fn visit_expr(@mut self, _: @expr) {
+    fn visit_expr(&mut self, _: @expr) {
         // XXX: Default method.
     }
-    fn visit_expr_post(@mut self, _: @expr) {
+    fn visit_expr_post(&mut self, _: @expr) {
         // XXX: Default method.
     }
-    fn visit_ty(@mut self, _: &Ty) {
+    fn visit_ty(&mut self, _: &Ty) {
         // XXX: Default method.
     }
-    fn visit_generics(@mut self, _: &Generics) {
+    fn visit_generics(&mut self, _: &Generics) {
         // XXX: Default method.
     }
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 _: &visit::fn_kind,
                 _: &fn_decl,
                 _: &Block,
@@ -730,23 +735,23 @@ impl SimpleVisitor for EachViewItemData {
                 _: NodeId) {
         // XXX: Default method.
     }
-    fn visit_ty_method(@mut self, _: &TypeMethod) {
+    fn visit_ty_method(&mut self, _: &TypeMethod) {
         // XXX: Default method.
     }
-    fn visit_trait_method(@mut self, _: &trait_method) {
+    fn visit_trait_method(&mut self, _: &trait_method) {
         // XXX: Default method.
     }
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         _: @struct_def,
                         _: ident,
                         _: &Generics,
                         _: NodeId) {
         // XXX: Default method.
     }
-    fn visit_struct_field(@mut self, _: @struct_field) {
+    fn visit_struct_field(&mut self, _: @struct_field) {
         // XXX: Default method.
     }
-    fn visit_struct_method(@mut self, _: @method) {
+    fn visit_struct_method(&mut self, _: @method) {
         // XXX: Default method.
     }
 }
@@ -759,7 +764,7 @@ impl EachViewItem for ast::Crate {
         let visitor = @mut SimpleVisitorVisitor {
             simple_visitor: data as @mut SimpleVisitor,
         };
-        visit::visit_crate(visitor as @mut Visitor<()>, self, ());
+        visit::walk_crate(visitor, self, ());
         true
     }
 }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 1547446957e..c188326a4f1 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -522,7 +522,7 @@ struct NewNameFinderContext {
 }
 
 impl Visitor<()> for NewNameFinderContext {
-    fn visit_pat(@mut self, pattern: @ast::pat, _: ()) {
+    fn visit_pat(&mut self, pattern: @ast::pat, _: ()) {
         match *pattern {
             // we found a pat_ident!
             ast::pat {
@@ -548,74 +548,74 @@ impl Visitor<()> for NewNameFinderContext {
                 }
             }
             // use the default traversal for non-pat_idents
-            _ => visit::visit_pat(self as @mut Visitor<()>, pattern, ())
+            _ => visit::walk_pat(self, pattern, ())
         }
     }
 
     // XXX: Methods below can become default methods.
 
-    fn visit_mod(@mut self, module: &ast::_mod, _: span, _: NodeId, _: ()) {
-        visit::visit_mod(self as @mut Visitor<()>, module, ())
+    fn visit_mod(&mut self, module: &ast::_mod, _: span, _: NodeId, _: ()) {
+        visit::walk_mod(self, module, ())
     }
 
-    fn visit_view_item(@mut self, view_item: &ast::view_item, _: ()) {
-        visit::visit_view_item(self as @mut Visitor<()>, view_item, ())
+    fn visit_view_item(&mut self, view_item: &ast::view_item, _: ()) {
+        visit::walk_view_item(self, view_item, ())
     }
 
-    fn visit_item(@mut self, item: @ast::item, _: ()) {
-        visit::visit_item(self as @mut Visitor<()>, item, ())
+    fn visit_item(&mut self, item: @ast::item, _: ()) {
+        visit::walk_item(self, item, ())
     }
 
-    fn visit_foreign_item(@mut self,
+    fn visit_foreign_item(&mut self,
                           foreign_item: @ast::foreign_item,
                           _: ()) {
-        visit::visit_foreign_item(self as @mut Visitor<()>, foreign_item, ())
+        visit::walk_foreign_item(self, foreign_item, ())
     }
 
-    fn visit_local(@mut self, local: @ast::Local, _: ()) {
-        visit::visit_local(self as @mut Visitor<()>, local, ())
+    fn visit_local(&mut self, local: @ast::Local, _: ()) {
+        visit::walk_local(self, local, ())
     }
 
-    fn visit_block(@mut self, block: &ast::Block, _: ()) {
-        visit::visit_block(self as @mut Visitor<()>, block, ())
+    fn visit_block(&mut self, block: &ast::Block, _: ()) {
+        visit::walk_block(self, block, ())
     }
 
-    fn visit_stmt(@mut self, stmt: @ast::stmt, _: ()) {
-        visit::visit_stmt(self as @mut Visitor<()>, stmt, ())
+    fn visit_stmt(&mut self, stmt: @ast::stmt, _: ()) {
+        visit::walk_stmt(self, stmt, ())
     }
 
-    fn visit_arm(@mut self, arm: &ast::arm, _: ()) {
-        visit::visit_arm(self as @mut Visitor<()>, arm, ())
+    fn visit_arm(&mut self, arm: &ast::arm, _: ()) {
+        visit::walk_arm(self, arm, ())
     }
 
-    fn visit_decl(@mut self, decl: @ast::decl, _: ()) {
-        visit::visit_decl(self as @mut Visitor<()>, decl, ())
+    fn visit_decl(&mut self, decl: @ast::decl, _: ()) {
+        visit::walk_decl(self, decl, ())
     }
 
-    fn visit_expr(@mut self, expr: @ast::expr, _: ()) {
-        visit::visit_expr(self as @mut Visitor<()>, expr, ())
+    fn visit_expr(&mut self, expr: @ast::expr, _: ()) {
+        visit::walk_expr(self, expr, ())
     }
 
-    fn visit_expr_post(@mut self, _: @ast::expr, _: ()) {
+    fn visit_expr_post(&mut self, _: @ast::expr, _: ()) {
         // Empty!
     }
 
-    fn visit_ty(@mut self, typ: &ast::Ty, _: ()) {
-        visit::visit_ty(self as @mut Visitor<()>, typ, ())
+    fn visit_ty(&mut self, typ: &ast::Ty, _: ()) {
+        visit::walk_ty(self, typ, ())
     }
 
-    fn visit_generics(@mut self, generics: &ast::Generics, _: ()) {
-        visit::visit_generics(self as @mut Visitor<()>, generics, ())
+    fn visit_generics(&mut self, generics: &ast::Generics, _: ()) {
+        visit::walk_generics(self, generics, ())
     }
 
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &visit::fn_kind,
                 function_declaration: &ast::fn_decl,
                 block: &ast::Block,
                 span: span,
                 node_id: NodeId,
                 _: ()) {
-        visit::visit_fn(self as @mut Visitor<()>,
+        visit::walk_fn(self,
                         function_kind,
                         function_declaration,
                         block,
@@ -624,23 +624,23 @@ impl Visitor<()> for NewNameFinderContext {
                         ())
     }
 
-    fn visit_ty_method(@mut self, ty_method: &ast::TypeMethod, _: ()) {
-        visit::visit_ty_method(self as @mut Visitor<()>, ty_method, ())
+    fn visit_ty_method(&mut self, ty_method: &ast::TypeMethod, _: ()) {
+        visit::walk_ty_method(self, ty_method, ())
     }
 
-    fn visit_trait_method(@mut self,
+    fn visit_trait_method(&mut self,
                           trait_method: &ast::trait_method,
                           _: ()) {
-        visit::visit_trait_method(self as @mut Visitor<()>, trait_method, ())
+        visit::walk_trait_method(self, trait_method, ())
     }
 
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_def: @ast::struct_def,
                         ident: ident,
                         generics: &ast::Generics,
                         node_id: NodeId,
                         _: ()) {
-        visit::visit_struct_def(self as @mut Visitor<()>,
+        visit::walk_struct_def(self,
                                 struct_def,
                                 ident,
                                 generics,
@@ -648,10 +648,10 @@ impl Visitor<()> for NewNameFinderContext {
                                 ())
     }
 
-    fn visit_struct_field(@mut self,
+    fn visit_struct_field(&mut self,
                           struct_field: @ast::struct_field,
                           _: ()) {
-        visit::visit_struct_field(self as @mut Visitor<()>, struct_field, ())
+        visit::walk_struct_field(self, struct_field, ())
     }
 }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index c3a5ba7116d..8178e7f3760 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -66,33 +66,97 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics {
     }
 }
 
-pub trait Visitor<E> {
-    fn visit_mod(@mut self, &_mod, span, NodeId, E);
-    fn visit_view_item(@mut self, &view_item, E);
-    fn visit_foreign_item(@mut self, @foreign_item, E);
-    fn visit_item(@mut self, @item, E);
-    fn visit_local(@mut self, @Local, E);
-    fn visit_block(@mut self, &Block, E);
-    fn visit_stmt(@mut self, @stmt, E);
-    fn visit_arm(@mut self, &arm, E);
-    fn visit_pat(@mut self, @pat, E);
-    fn visit_decl(@mut self, @decl, E);
-    fn visit_expr(@mut self, @expr, E);
-    fn visit_expr_post(@mut self, @expr, E);
-    fn visit_ty(@mut self, &Ty, E);
-    fn visit_generics(@mut self, &Generics, E);
-    fn visit_fn(@mut self, &fn_kind, &fn_decl, &Block, span, NodeId, E);
-    fn visit_ty_method(@mut self, &TypeMethod, E);
-    fn visit_trait_method(@mut self, &trait_method, E);
-    fn visit_struct_def(@mut self, @struct_def, ident, &Generics, NodeId, E);
-    fn visit_struct_field(@mut self, @struct_field, E);
+pub trait Visitor<E:Clone> {
+    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:&view_item, e:E) { walk_view_item(self, i, e) }
+    fn visit_foreign_item(&mut self, i:@foreign_item, 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) { }
+    fn visit_generics(&mut self, g:&Generics, e:E) { walk_generics(self, g, e) }
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:span, n:NodeId, e:E) {
+        walk_fn(self, fk, fd, b, s, n , e)
+    }
+    fn visit_ty_method(&mut self, t:&TypeMethod, e:E) { walk_ty_method(self, t, e) }
+    fn visit_trait_method(&mut self, t:&trait_method, e:E) { walk_trait_method(self, t, e) }
+    fn visit_struct_def(&mut self, s:@struct_def, i:ident, g:&Generics, n:NodeId, e:E) {
+        walk_struct_def(self, s, i, g, n, e)
+    }
+    fn visit_struct_field(&mut self, s:@struct_field, e:E) { walk_struct_field(self, s, e) }
 }
 
-pub fn visit_crate<E:Clone>(visitor: @mut Visitor<E>, crate: &Crate, env: E) {
+impl<E:Clone> Visitor<E> for @mut Visitor<E> {
+    fn visit_mod(&mut self, a:&_mod, b:span, c:NodeId, e:E) {
+        (*self).visit_mod(a, b, c, e)
+    }
+    fn visit_view_item(&mut self, a:&view_item, e:E) {
+        (*self).visit_view_item(a, e)
+    }
+    fn visit_foreign_item(&mut self, a:@foreign_item, e:E) {
+        (*self).visit_foreign_item(a, e)
+    }
+    fn visit_item(&mut self, a:@item, e:E) {
+        (*self).visit_item(a, e)
+    }
+    fn visit_local(&mut self, a:@Local, e:E) {
+        (*self).visit_local(a, e)
+    }
+    fn visit_block(&mut self, a:&Block, e:E) {
+        (*self).visit_block(a, e)
+    }
+    fn visit_stmt(&mut self, a:@stmt, e:E) {
+        (*self).visit_stmt(a, e)
+    }
+    fn visit_arm(&mut self, a:&arm, e:E) {
+        (*self).visit_arm(a, e)
+    }
+    fn visit_pat(&mut self, a:@pat, e:E) {
+        (*self).visit_pat(a, e)
+    }
+    fn visit_decl(&mut self, a:@decl, e:E) {
+        (*self).visit_decl(a, e)
+    }
+    fn visit_expr(&mut self, a:@expr, e:E) {
+        (*self).visit_expr(a, e)
+    }
+    fn visit_expr_post(&mut self, a:@expr, e:E) {
+        (*self).visit_expr_post(a, e)
+    }
+    fn visit_ty(&mut self, a:&Ty, e:E) {
+        (*self).visit_ty(a, e)
+    }
+    fn visit_generics(&mut self, a:&Generics, e:E) {
+        (*self).visit_generics(a, e)
+    }
+    fn visit_fn(&mut self, a:&fn_kind, b:&fn_decl, c:&Block, d:span, f:NodeId, e:E) {
+        (*self).visit_fn(a, b, c, d, f, e)
+    }
+    fn visit_ty_method(&mut self, a:&TypeMethod, e:E) {
+        (*self).visit_ty_method(a, e)
+    }
+    fn visit_trait_method(&mut self, a:&trait_method, e:E) {
+        (*self).visit_trait_method(a, e)
+    }
+    fn visit_struct_def(&mut self, a:@struct_def, b:ident, c:&Generics, d:NodeId, e:E) {
+        (*self).visit_struct_def(a, b, c, d, e)
+    }
+    fn visit_struct_field(&mut self, a:@struct_field, e:E) {
+        (*self).visit_struct_field(a, e)
+    }
+}
+
+pub fn walk_crate<E:Clone, V:Visitor<E>>(visitor: &mut V, crate: &Crate, env: E) {
     visitor.visit_mod(&crate.module, crate.span, CRATE_NODE_ID, env)
 }
 
-pub fn visit_mod<E:Clone>(visitor: @mut Visitor<E>, module: &_mod, env: E) {
+pub fn walk_mod<E:Clone, V:Visitor<E>>(visitor: &mut V, module: &_mod, env: E) {
     for view_item in module.view_items.iter() {
         visitor.visit_view_item(view_item, env.clone())
     }
@@ -101,11 +165,11 @@ pub fn visit_mod<E:Clone>(visitor: @mut Visitor<E>, module: &_mod, env: E) {
     }
 }
 
-pub fn visit_view_item<E:Clone>(_: @mut Visitor<E>, _: &view_item, _: E) {
+pub fn walk_view_item<E:Clone, V:Visitor<E>>(_: &mut V, _: &view_item, _: E) {
     // Empty!
 }
 
-pub fn visit_local<E:Clone>(visitor: @mut Visitor<E>, local: &Local, env: E) {
+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());
     match local.init {
@@ -114,13 +178,13 @@ pub fn visit_local<E:Clone>(visitor: @mut Visitor<E>, local: &Local, env: E) {
     }
 }
 
-fn visit_trait_ref<E:Clone>(visitor: @mut Visitor<E>,
+fn walk_trait_ref<E:Clone, V:Visitor<E>>(visitor: &mut V,
                             trait_ref: &ast::trait_ref,
                             env: E) {
-    visit_path(visitor, &trait_ref.path, env)
+    walk_path(visitor, &trait_ref.path, env)
 }
 
-pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
+pub fn walk_item<E:Clone, V:Visitor<E>>(visitor: &mut V, item: &item, env: E) {
     match item.node {
         item_static(ref typ, _, expr) => {
             visitor.visit_ty(typ, env.clone());
@@ -151,7 +215,7 @@ pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
         }
         item_enum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters, env.clone());
-            visit_enum_def(visitor, enum_definition, type_parameters, env)
+            walk_enum_def(visitor, enum_definition, type_parameters, env)
         }
         item_impl(ref type_parameters,
                   ref trait_references,
@@ -159,11 +223,11 @@ pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
                   ref methods) => {
             visitor.visit_generics(type_parameters, env.clone());
             for trait_reference in trait_references.iter() {
-                visit_trait_ref(visitor, trait_reference, env.clone())
+                walk_trait_ref(visitor, trait_reference, env.clone())
             }
             visitor.visit_ty(typ, env.clone());
             for method in methods.iter() {
-                visit_method_helper(visitor, *method, env.clone())
+                walk_method_helper(visitor, *method, env.clone())
             }
         }
         item_struct(struct_definition, ref generics) => {
@@ -177,17 +241,17 @@ pub fn visit_item<E:Clone>(visitor: @mut Visitor<E>, item: &item, env: E) {
         item_trait(ref generics, ref trait_paths, ref methods) => {
             visitor.visit_generics(generics, env.clone());
             for trait_path in trait_paths.iter() {
-                visit_path(visitor, &trait_path.path, env.clone())
+                walk_path(visitor, &trait_path.path, env.clone())
             }
             for method in methods.iter() {
                 visitor.visit_trait_method(method, env.clone())
             }
         }
-        item_mac(ref macro) => visit_mac(visitor, macro, env),
+        item_mac(ref macro) => walk_mac(visitor, macro, env),
     }
 }
 
-pub fn visit_enum_def<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_enum_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                enum_definition: &ast::enum_def,
                                generics: &Generics,
                                env: E) {
@@ -209,11 +273,11 @@ pub fn visit_enum_def<E:Clone>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn skip_ty<E>(_: @mut Visitor<E>, _: &Ty, _: E) {
+pub fn skip_ty<E, V:Visitor<E>>(_: &mut V, _: &Ty, _: E) {
     // Empty!
 }
 
-pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
+pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
     match typ.node {
         ty_box(ref mutable_type) | ty_uniq(ref mutable_type) |
         ty_vec(ref mutable_type) | ty_ptr(ref mutable_type) |
@@ -231,7 +295,7 @@ pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
              }
              visitor.visit_ty(&function_declaration.decl.output, env.clone());
              for bounds in function_declaration.bounds.iter() {
-                visit_ty_param_bounds(visitor, bounds, env.clone())
+                walk_ty_param_bounds(visitor, bounds, env.clone())
              }
         }
         ty_bare_fn(ref function_declaration) => {
@@ -241,9 +305,9 @@ pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
             visitor.visit_ty(&function_declaration.decl.output, env.clone())
         }
         ty_path(ref path, ref bounds, _) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for bounds in bounds.iter() {
-                visit_ty_param_bounds(visitor, bounds, env.clone())
+                walk_ty_param_bounds(visitor, bounds, env.clone())
             }
         }
         ty_fixed_length_vec(ref mutable_type, expression) => {
@@ -254,16 +318,16 @@ pub fn visit_ty<E:Clone>(visitor: @mut Visitor<E>, typ: &Ty, env: E) {
     }
 }
 
-pub fn visit_path<E:Clone>(visitor: @mut Visitor<E>, path: &Path, env: E) {
+pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
     for typ in path.types.iter() {
         visitor.visit_ty(typ, env.clone())
     }
 }
 
-pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
+pub fn walk_pat<E:Clone, V:Visitor<E>>(visitor: &mut V, pattern: &pat, env: E) {
     match pattern.node {
         pat_enum(ref path, ref children) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for children in children.iter() {
                 for child in children.iter() {
                     visitor.visit_pat(*child, env.clone())
@@ -271,7 +335,7 @@ pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
             }
         }
         pat_struct(ref path, ref fields, _) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for field in fields.iter() {
                 visitor.visit_pat(field.pat, env.clone())
             }
@@ -287,7 +351,7 @@ pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
             visitor.visit_pat(subpattern, env)
         }
         pat_ident(_, ref path, ref optional_subpattern) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             match *optional_subpattern {
                 None => {}
                 Some(subpattern) => visitor.visit_pat(subpattern, env),
@@ -313,40 +377,40 @@ pub fn visit_pat<E:Clone>(visitor: @mut Visitor<E>, pattern: &pat, env: E) {
     }
 }
 
-pub fn visit_foreign_item<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_foreign_item<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                    foreign_item: &foreign_item,
                                    env: E) {
     match foreign_item.node {
         foreign_item_fn(ref function_declaration, ref generics) => {
-            visit_fn_decl(visitor, function_declaration, env.clone());
+            walk_fn_decl(visitor, function_declaration, env.clone());
             visitor.visit_generics(generics, env)
         }
         foreign_item_static(ref typ, _) => visitor.visit_ty(typ, env),
     }
 }
 
-pub fn visit_ty_param_bounds<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_ty_param_bounds<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                       bounds: &OptVec<TyParamBound>,
                                       env: E) {
     for bound in bounds.iter() {
         match *bound {
             TraitTyParamBound(ref typ) => {
-                visit_trait_ref(visitor, typ, env.clone())
+                walk_trait_ref(visitor, typ, env.clone())
             }
             RegionTyParamBound => {}
         }
     }
 }
 
-pub fn visit_generics<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_generics<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                generics: &Generics,
                                env: E) {
     for type_parameter in generics.ty_params.iter() {
-        visit_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
+        walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
     }
 }
 
-pub fn visit_fn_decl<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_fn_decl<E:Clone, V:Visitor<E>>(visitor: &mut V,
                               function_declaration: &fn_decl,
                               env: E) {
     for argument in function_declaration.inputs.iter() {
@@ -360,7 +424,7 @@ pub fn visit_fn_decl<E:Clone>(visitor: @mut Visitor<E>,
 // visit_fn() and check for fk_method().  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 visit_method_helper<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_method_helper<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                     method: &method,
                                     env: E) {
     visitor.visit_fn(&fk_method(method.ident, &method.generics, method),
@@ -371,20 +435,20 @@ pub fn visit_method_helper<E:Clone>(visitor: @mut Visitor<E>,
                      env)
 }
 
-pub fn visit_fn<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_fn<E:Clone, V:Visitor<E>>(visitor: &mut V,
                          function_kind: &fn_kind,
                          function_declaration: &fn_decl,
                          function_body: &Block,
                          _: span,
                          _: NodeId,
                          env: E) {
-    visit_fn_decl(visitor, function_declaration, env.clone());
+    walk_fn_decl(visitor, function_declaration, env.clone());
     let generics = generics_of_fn(function_kind);
     visitor.visit_generics(&generics, env.clone());
     visitor.visit_block(function_body, env)
 }
 
-pub fn visit_ty_method<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_ty_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                 method_type: &TypeMethod,
                                 env: E) {
     for argument_type in method_type.decl.inputs.iter() {
@@ -394,18 +458,18 @@ pub fn visit_ty_method<E:Clone>(visitor: @mut Visitor<E>,
     visitor.visit_ty(&method_type.decl.output, env.clone())
 }
 
-pub fn visit_trait_method<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_trait_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                    trait_method: &trait_method,
                                    env: E) {
     match *trait_method {
         required(ref method_type) => {
             visitor.visit_ty_method(method_type, env)
         }
-        provided(method) => visit_method_helper(visitor, method, env),
+        provided(method) => walk_method_helper(visitor, method, env),
     }
 }
 
-pub fn visit_struct_def<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_struct_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                  struct_definition: @struct_def,
                                  _: ast::ident,
                                  _: &Generics,
@@ -416,40 +480,40 @@ pub fn visit_struct_def<E:Clone>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn visit_struct_field<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_struct_field<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                    struct_field: &struct_field,
                                    env: E) {
     visitor.visit_ty(&struct_field.node.ty, env)
 }
 
-pub fn visit_block<E:Clone>(visitor: @mut Visitor<E>, block: &Block, env: E) {
+pub fn walk_block<E:Clone, V:Visitor<E>>(visitor: &mut V, block: &Block, env: E) {
     for view_item in block.view_items.iter() {
         visitor.visit_view_item(view_item, env.clone())
     }
     for statement in block.stmts.iter() {
         visitor.visit_stmt(*statement, env.clone())
     }
-    visit_expr_opt(visitor, block.expr, env)
+    walk_expr_opt(visitor, block.expr, env)
 }
 
-pub fn visit_stmt<E>(visitor: @mut Visitor<E>, statement: &stmt, env: E) {
+pub fn walk_stmt<E:Clone, V:Visitor<E>>(visitor: &mut V, statement: &stmt, env: E) {
     match statement.node {
         stmt_decl(declaration, _) => visitor.visit_decl(declaration, env),
         stmt_expr(expression, _) | stmt_semi(expression, _) => {
             visitor.visit_expr(expression, env)
         }
-        stmt_mac(ref macro, _) => visit_mac(visitor, macro, env),
+        stmt_mac(ref macro, _) => walk_mac(visitor, macro, env),
     }
 }
 
-pub fn visit_decl<E:Clone>(visitor: @mut Visitor<E>, declaration: &decl, env: E) {
+pub fn walk_decl<E:Clone, V:Visitor<E>>(visitor: &mut V, declaration: &decl, env: E) {
     match declaration.node {
         decl_local(ref local) => visitor.visit_local(*local, env),
         decl_item(item) => visitor.visit_item(item, env),
     }
 }
 
-pub fn visit_expr_opt<E>(visitor: @mut Visitor<E>,
+pub fn walk_expr_opt<E:Clone, V:Visitor<E>>(visitor: &mut V,
                          optional_expression: Option<@expr>,
                          env: E) {
     match optional_expression {
@@ -458,7 +522,7 @@ pub fn visit_expr_opt<E>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn visit_exprs<E:Clone>(visitor: @mut Visitor<E>,
+pub fn walk_exprs<E:Clone, V:Visitor<E>>(visitor: &mut V,
                             expressions: &[@expr],
                             env: E) {
     for expression in expressions.iter() {
@@ -466,28 +530,28 @@ pub fn visit_exprs<E:Clone>(visitor: @mut Visitor<E>,
     }
 }
 
-pub fn visit_mac<E>(_: @mut Visitor<E>, _: &mac, _: E) {
+pub fn walk_mac<E, V:Visitor<E>>(_: &mut V, _: &mac, _: E) {
     // Empty!
 }
 
-pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E) {
+pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @expr, env: E) {
     match expression.node {
         expr_vstore(subexpression, _) => {
             visitor.visit_expr(subexpression, env.clone())
         }
         expr_vec(ref subexpressions, _) => {
-            visit_exprs(visitor, *subexpressions, env.clone())
+            walk_exprs(visitor, *subexpressions, env.clone())
         }
         expr_repeat(element, count, _) => {
             visitor.visit_expr(element, env.clone());
             visitor.visit_expr(count, env.clone())
         }
         expr_struct(ref path, ref fields, optional_base) => {
-            visit_path(visitor, path, env.clone());
+            walk_path(visitor, path, env.clone());
             for field in fields.iter() {
                 visitor.visit_expr(field.expr, env.clone())
             }
-            visit_expr_opt(visitor, optional_base, env.clone())
+            walk_expr_opt(visitor, optional_base, env.clone())
         }
         expr_tup(ref subexpressions) => {
             for subexpression in subexpressions.iter() {
@@ -501,7 +565,7 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
             visitor.visit_expr(callee_expression, env.clone())
         }
         expr_method_call(_, callee, _, ref types, ref arguments, _) => {
-            visit_exprs(visitor, *arguments, env.clone());
+            walk_exprs(visitor, *arguments, env.clone());
             for typ in types.iter() {
                 visitor.visit_ty(typ, env.clone())
             }
@@ -524,7 +588,7 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
         expr_if(head_expression, ref if_block, optional_else) => {
             visitor.visit_expr(head_expression, env.clone());
             visitor.visit_block(if_block, env.clone());
-            visit_expr_opt(visitor, optional_else, env.clone())
+            walk_expr_opt(visitor, optional_else, env.clone())
         }
         expr_while(subexpression, ref block) => {
             visitor.visit_expr(subexpression, env.clone());
@@ -569,16 +633,16 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
             visitor.visit_expr(main_expression, env.clone());
             visitor.visit_expr(index_expression, env.clone())
         }
-        expr_path(ref path) => visit_path(visitor, path, env.clone()),
+        expr_path(ref path) => walk_path(visitor, path, env.clone()),
         expr_self | expr_break(_) | expr_again(_) => {}
         expr_ret(optional_expression) => {
-            visit_expr_opt(visitor, optional_expression, env.clone())
+            walk_expr_opt(visitor, optional_expression, env.clone())
         }
         expr_log(level, subexpression) => {
             visitor.visit_expr(level, env.clone());
             visitor.visit_expr(subexpression, env.clone());
         }
-        expr_mac(ref macro) => visit_mac(visitor, macro, env.clone()),
+        expr_mac(ref macro) => walk_mac(visitor, macro, env.clone()),
         expr_paren(subexpression) => {
             visitor.visit_expr(subexpression, env.clone())
         }
@@ -595,11 +659,11 @@ pub fn visit_expr<E:Clone>(visitor: @mut Visitor<E>, expression: @expr, env: E)
     visitor.visit_expr_post(expression, env.clone())
 }
 
-pub fn visit_arm<E:Clone>(visitor: @mut Visitor<E>, arm: &arm, env: E) {
+pub fn walk_arm<E:Clone, V:Visitor<E>>(visitor: &mut V, arm: &arm, env: E) {
     for pattern in arm.pats.iter() {
         visitor.visit_pat(*pattern, env.clone())
     }
-    visit_expr_opt(visitor, arm.guard, env.clone());
+    walk_expr_opt(visitor, arm.guard, env.clone());
     visitor.visit_block(&arm.body, env)
 }
 
@@ -607,26 +671,26 @@ pub fn visit_arm<E:Clone>(visitor: @mut Visitor<E>, arm: &arm, env: E) {
 // calls the given functions on the nodes.
 
 pub trait SimpleVisitor {
-    fn visit_mod(@mut self, &_mod, span, NodeId);
-    fn visit_view_item(@mut self, &view_item);
-    fn visit_foreign_item(@mut self, @foreign_item);
-    fn visit_item(@mut self, @item);
-    fn visit_local(@mut self, @Local);
-    fn visit_block(@mut self, &Block);
-    fn visit_stmt(@mut self, @stmt);
-    fn visit_arm(@mut self, &arm);
-    fn visit_pat(@mut self, @pat);
-    fn visit_decl(@mut self, @decl);
-    fn visit_expr(@mut self, @expr);
-    fn visit_expr_post(@mut self, @expr);
-    fn visit_ty(@mut self, &Ty);
-    fn visit_generics(@mut self, &Generics);
-    fn visit_fn(@mut self, &fn_kind, &fn_decl, &Block, span, NodeId);
-    fn visit_ty_method(@mut self, &TypeMethod);
-    fn visit_trait_method(@mut self, &trait_method);
-    fn visit_struct_def(@mut self, @struct_def, ident, &Generics, NodeId);
-    fn visit_struct_field(@mut self, @struct_field);
-    fn visit_struct_method(@mut self, @method);
+    fn visit_mod(&mut self, &_mod, span, NodeId);
+    fn visit_view_item(&mut self, &view_item);
+    fn visit_foreign_item(&mut self, @foreign_item);
+    fn visit_item(&mut self, @item);
+    fn visit_local(&mut self, @Local);
+    fn visit_block(&mut self, &Block);
+    fn visit_stmt(&mut self, @stmt);
+    fn visit_arm(&mut self, &arm);
+    fn visit_pat(&mut self, @pat);
+    fn visit_decl(&mut self, @decl);
+    fn visit_expr(&mut self, @expr);
+    fn visit_expr_post(&mut self, @expr);
+    fn visit_ty(&mut self, &Ty);
+    fn visit_generics(&mut self, &Generics);
+    fn visit_fn(&mut self, &fn_kind, &fn_decl, &Block, span, NodeId);
+    fn visit_ty_method(&mut self, &TypeMethod);
+    fn visit_trait_method(&mut self, &trait_method);
+    fn visit_struct_def(&mut self, @struct_def, ident, &Generics, NodeId);
+    fn visit_struct_field(&mut self, @struct_field);
+    fn visit_struct_method(&mut self, @method);
 }
 
 pub struct SimpleVisitorVisitor {
@@ -634,66 +698,66 @@ pub struct SimpleVisitorVisitor {
 }
 
 impl Visitor<()> for SimpleVisitorVisitor {
-    fn visit_mod(@mut self,
+    fn visit_mod(&mut self,
                  module: &_mod,
                  span: span,
                  node_id: NodeId,
                  env: ()) {
         self.simple_visitor.visit_mod(module, span, node_id);
-        visit_mod(self as @mut Visitor<()>, module, env)
+        walk_mod(self, module, env)
     }
-    fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
+    fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
         self.simple_visitor.visit_view_item(view_item);
-        visit_view_item(self as @mut Visitor<()>, view_item, env)
+        walk_view_item(self, view_item, env)
     }
-    fn visit_foreign_item(@mut self, foreign_item: @foreign_item, env: ()) {
+    fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
         self.simple_visitor.visit_foreign_item(foreign_item);
-        visit_foreign_item(self as @mut Visitor<()>, foreign_item, env)
+        walk_foreign_item(self, foreign_item, env)
     }
-    fn visit_item(@mut self, item: @item, env: ()) {
+    fn visit_item(&mut self, item: @item, env: ()) {
         self.simple_visitor.visit_item(item);
-        visit_item(self as @mut Visitor<()>, item, env)
+        walk_item(self, item, env)
     }
-    fn visit_local(@mut self, local: @Local, env: ()) {
+    fn visit_local(&mut self, local: @Local, env: ()) {
         self.simple_visitor.visit_local(local);
-        visit_local(self as @mut Visitor<()>, local, env)
+        walk_local(self, local, env)
     }
-    fn visit_block(@mut self, block: &Block, env: ()) {
+    fn visit_block(&mut self, block: &Block, env: ()) {
         self.simple_visitor.visit_block(block);
-        visit_block(self as @mut Visitor<()>, block, env)
+        walk_block(self, block, env)
     }
-    fn visit_stmt(@mut self, statement: @stmt, env: ()) {
+    fn visit_stmt(&mut self, statement: @stmt, env: ()) {
         self.simple_visitor.visit_stmt(statement);
-        visit_stmt(self as @mut Visitor<()>, statement, env)
+        walk_stmt(self, statement, env)
     }
-    fn visit_arm(@mut self, arm: &arm, env: ()) {
+    fn visit_arm(&mut self, arm: &arm, env: ()) {
         self.simple_visitor.visit_arm(arm);
-        visit_arm(self as @mut Visitor<()>, arm, env)
+        walk_arm(self, arm, env)
     }
-    fn visit_pat(@mut self, pattern: @pat, env: ()) {
+    fn visit_pat(&mut self, pattern: @pat, env: ()) {
         self.simple_visitor.visit_pat(pattern);
-        visit_pat(self as @mut Visitor<()>, pattern, env)
+        walk_pat(self, pattern, env)
     }
-    fn visit_decl(@mut self, declaration: @decl, env: ()) {
+    fn visit_decl(&mut self, declaration: @decl, env: ()) {
         self.simple_visitor.visit_decl(declaration);
-        visit_decl(self as @mut Visitor<()>, declaration, env)
+        walk_decl(self, declaration, env)
     }
-    fn visit_expr(@mut self, expression: @expr, env: ()) {
+    fn visit_expr(&mut self, expression: @expr, env: ()) {
         self.simple_visitor.visit_expr(expression);
-        visit_expr(self as @mut Visitor<()>, expression, env)
+        walk_expr(self, expression, env)
     }
-    fn visit_expr_post(@mut self, expression: @expr, _: ()) {
+    fn visit_expr_post(&mut self, expression: @expr, _: ()) {
         self.simple_visitor.visit_expr_post(expression)
     }
-    fn visit_ty(@mut self, typ: &Ty, env: ()) {
+    fn visit_ty(&mut self, typ: &Ty, env: ()) {
         self.simple_visitor.visit_ty(typ);
-        visit_ty(self as @mut Visitor<()>, typ, env)
+        walk_ty(self, typ, env)
     }
-    fn visit_generics(@mut self, generics: &Generics, env: ()) {
+    fn visit_generics(&mut self, generics: &Generics, env: ()) {
         self.simple_visitor.visit_generics(generics);
-        visit_generics(self as @mut Visitor<()>, generics, env)
+        walk_generics(self, generics, env)
     }
-    fn visit_fn(@mut self,
+    fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
                 block: &Block,
@@ -705,7 +769,7 @@ impl Visitor<()> for SimpleVisitorVisitor {
                                      block,
                                      span,
                                      node_id);
-        visit_fn(self as @mut Visitor<()>,
+        walk_fn(self,
                  function_kind,
                  function_declaration,
                  block,
@@ -713,15 +777,15 @@ impl Visitor<()> for SimpleVisitorVisitor {
                  node_id,
                  env)
     }
-    fn visit_ty_method(@mut self, method_type: &TypeMethod, env: ()) {
+    fn visit_ty_method(&mut self, method_type: &TypeMethod, env: ()) {
         self.simple_visitor.visit_ty_method(method_type);
-        visit_ty_method(self as @mut Visitor<()>, method_type, env)
+        walk_ty_method(self, method_type, env)
     }
-    fn visit_trait_method(@mut self, trait_method: &trait_method, env: ()) {
+    fn visit_trait_method(&mut self, trait_method: &trait_method, env: ()) {
         self.simple_visitor.visit_trait_method(trait_method);
-        visit_trait_method(self as @mut Visitor<()>, trait_method, env)
+        walk_trait_method(self, trait_method, env)
     }
-    fn visit_struct_def(@mut self,
+    fn visit_struct_def(&mut self,
                         struct_definition: @struct_def,
                         identifier: ident,
                         generics: &Generics,
@@ -731,16 +795,16 @@ impl Visitor<()> for SimpleVisitorVisitor {
                                              identifier,
                                              generics,
                                              node_id);
-        visit_struct_def(self as @mut Visitor<()>,
+        walk_struct_def(self,
                          struct_definition,
                          identifier,
                          generics,
                          node_id,
                          env)
     }
-    fn visit_struct_field(@mut self, struct_field: @struct_field, env: ()) {
+    fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
         self.simple_visitor.visit_struct_field(struct_field);
-        visit_struct_field(self as @mut Visitor<()>, struct_field, env)
+        walk_struct_field(self, struct_field, env)
     }
 }