diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index c185b5cda34..0fccf50e009 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -163,7 +163,8 @@ pub fn phase_1_parse_input(sess: Session, cfg: ast::CrateConfig, input: &input)
 /// standard library and prelude.
 pub fn phase_2_configure_and_expand(sess: Session,
                                     cfg: ast::CrateConfig,
-                                    mut crate: ast::Crate) -> ast::Crate {
+                                    mut crate: ast::Crate)
+                                    -> (ast::Crate, syntax::ast_map::map) {
     let time_passes = sess.time_passes();
 
     sess.building_library.set(session::building_library(sess.opts, &crate));
@@ -201,10 +202,8 @@ pub fn phase_2_configure_and_expand(sess: Session,
     crate = time(time_passes, "std injection", crate, |crate|
                  front::std_inject::maybe_inject_libstd_ref(sess, crate));
 
-    crate = time(time_passes, "assigning node ids", crate, |crate|
-                 front::assign_node_ids::assign_node_ids(sess, crate));
-
-    return crate;
+    time(time_passes, "assinging node ids and indexing ast", crate, |crate|
+         front::assign_node_ids_and_map::assign_node_ids_and_map(sess, crate))
 }
 
 pub struct CrateAnalysis {
@@ -219,13 +218,11 @@ pub struct CrateAnalysis {
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes(sess: Session,
-                                   crate: &ast::Crate) -> CrateAnalysis {
+                                   crate: &ast::Crate,
+                                   ast_map: syntax::ast_map::map) -> CrateAnalysis {
 
     let time_passes = sess.time_passes();
 
-    let ast_map = time(time_passes, "ast indexing", (), |_|
-                       syntax::ast_map::map_crate(sess.diagnostic(), crate));
-
     time(time_passes, "external crate/lib resolution", (), |_|
          creader::read_crates(sess, crate,
                               session::sess_os_to_meta_os(sess.targ_cfg.os),
@@ -260,8 +257,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
                             region_map, lang_items);
 
     // passes are timed inside typeck
-    let (method_map, vtable_map) = typeck::check_crate(
-        ty_cx, trait_map, crate);
+    let (method_map, vtable_map) = typeck::check_crate(ty_cx, trait_map, crate);
 
     // These next two const passes can probably be merged
     time(time_passes, "const marking", (), |_|
@@ -489,7 +485,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
     // large chunks of memory alive and we want to free them as soon as
     // possible to keep the peak memory usage low
     let (outputs, trans) = {
-        let expanded_crate = {
+        let (expanded_crate, ast_map) = {
             let crate = phase_1_parse_input(sess, cfg.clone(), input);
             if stop_after_phase_1(sess) { return; }
             phase_2_configure_and_expand(sess, cfg, crate)
@@ -501,7 +497,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
 
         if stop_after_phase_2(sess) { return; }
 
-        let analysis = phase_3_run_analysis_passes(sess, &expanded_crate);
+        let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
         if stop_after_phase_3(sess) { return; }
         let trans = phase_4_translate_to_llvm(sess, expanded_crate,
                                               &analysis, outputs);
@@ -578,11 +574,12 @@ pub fn pretty_print_input(sess: Session,
                           ppm: PpMode) {
     let crate = phase_1_parse_input(sess, cfg.clone(), input);
 
-    let (crate, is_expanded) = match ppm {
+    let (crate, ast_map, is_expanded) = match ppm {
         PpmExpanded | PpmExpandedIdentified | PpmTyped => {
-            (phase_2_configure_and_expand(sess, cfg, crate), true)
+            let (crate, ast_map) = phase_2_configure_and_expand(sess, cfg, crate);
+            (crate, Some(ast_map), true)
         }
-        _ => (crate, false)
+        _ => (crate, None, false)
     };
 
     let annotation = match ppm {
@@ -592,7 +589,8 @@ pub fn pretty_print_input(sess: Session,
             } as @pprust::pp_ann
         }
         PpmTyped => {
-            let analysis = phase_3_run_analysis_passes(sess, &crate);
+            let ast_map = ast_map.expect("--pretty=typed missing ast_map");
+            let analysis = phase_3_run_analysis_passes(sess, &crate, ast_map);
             @TypedAnnotation {
                 analysis: analysis
             } as @pprust::pp_ann
diff --git a/src/librustc/front/assign_node_ids.rs b/src/librustc/front/assign_node_ids_and_map.rs
similarity index 59%
rename from src/librustc/front/assign_node_ids.rs
rename to src/librustc/front/assign_node_ids_and_map.rs
index 74e8e0de1d8..bf950f1d686 100644
--- a/src/librustc/front/assign_node_ids.rs
+++ b/src/librustc/front/assign_node_ids_and_map.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -11,22 +11,19 @@
 use driver::session::Session;
 
 use syntax::ast;
-use syntax::fold::ast_fold;
+use syntax::ast_map;
 
 struct NodeIdAssigner {
-    sess: Session,
+    sess: Session
 }
 
-impl ast_fold for NodeIdAssigner {
-    fn new_id(&mut self, old_id: ast::NodeId) -> ast::NodeId {
+impl ast_map::FoldOps for NodeIdAssigner {
+    fn new_id(&self, old_id: ast::NodeId) -> ast::NodeId {
         assert_eq!(old_id, ast::DUMMY_NODE_ID);
         self.sess.next_node_id()
     }
 }
 
-pub fn assign_node_ids(sess: Session, crate: ast::Crate) -> ast::Crate {
-    let mut fold = NodeIdAssigner {
-        sess: sess,
-    };
-    fold.fold_crate(crate)
+pub fn assign_node_ids_and_map(sess: Session, crate: ast::Crate) -> (ast::Crate, ast_map::map) {
+    ast_map::map_crate(sess.diagnostic(), crate, NodeIdAssigner { sess: sess })
 }
diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs
index fa0be72b830..9f9d931cc13 100644
--- a/src/librustc/front/feature_gate.rs
+++ b/src/librustc/front/feature_gate.rs
@@ -119,7 +119,7 @@ impl Visitor<()> for Context {
         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 "thread_local" == attr.name() {
                 self.gate_feature("thread_local", i.span,
@@ -187,7 +187,7 @@ impl Visitor<()> for Context {
         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, _) |
             ast::ExprVstore(_, ast::ExprVstoreBox) => {
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 0807668fc4d..b3a2bb5b72c 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -81,7 +81,7 @@ pub mod front {
     pub mod config;
     pub mod test;
     pub mod std_inject;
-    pub mod assign_node_ids;
+    pub mod assign_node_ids_and_map;
     pub mod feature_gate;
 }
 
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index cb6d5e3c99c..7f4e5b5d9ab 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -58,11 +58,11 @@ struct ReadCrateVisitor<'a> {
 }
 
 impl<'a> visit::Visitor<()> for ReadCrateVisitor<'a> {
-    fn visit_view_item(&mut self, a:&ast::view_item, _:()) {
+    fn visit_view_item(&mut self, a: &ast::view_item, _: ()) {
         visit_view_item(self.e, 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.e, a);
         visit::walk_item(self, a, ());
     }
@@ -164,7 +164,7 @@ fn visit_view_item(e: &mut Env, i: &ast::view_item) {
   }
 }
 
-fn visit_item(e: &Env, i: @ast::item) {
+fn visit_item(e: &Env, i: &ast::item) {
     match i.node {
         ast::item_foreign_mod(ref fm) => {
             if fm.abis.is_rust() || fm.abis.is_intrinsic() {
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 3b2c77c2ba4..33a34c3f5ba 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -50,10 +50,17 @@ use writer = extra::ebml::writer;
 // used by astencode:
 type abbrev_map = @RefCell<HashMap<ty::t, tyencode::ty_abbrev>>;
 
+/// A borrowed version of ast::inlined_item.
+pub enum InlinedItemRef<'a> {
+    ii_item_ref(&'a ast::item),
+    ii_method_ref(ast::DefId, bool, &'a ast::method),
+    ii_foreign_ref(&'a ast::foreign_item)
+}
+
 pub type encode_inlined_item<'a> = 'a |ecx: &EncodeContext,
-                                             ebml_w: &mut writer::Encoder,
-                                             path: &[ast_map::path_elt],
-                                             ii: ast::inlined_item|;
+                                       ebml_w: &mut writer::Encoder,
+                                       path: &[ast_map::path_elt],
+                                       ii: InlinedItemRef|;
 
 pub struct EncodeParams<'a> {
     diag: @SpanHandler,
@@ -837,13 +844,13 @@ fn encode_info_for_method(ecx: &EncodeContext,
         None => ()
     }
 
-    for ast_method in ast_method_opt.iter() {
+    for &ast_method in ast_method_opt.iter() {
         let num_params = tpt.generics.type_param_defs.len();
         if num_params > 0u || is_default_impl
             || should_inline(ast_method.attrs) {
             (ecx.encode_inlined_item)(
                 ecx, ebml_w, impl_path,
-                ii_method(local_def(parent_id), false, *ast_method));
+                ii_method_ref(local_def(parent_id), false, ast_method));
         } else {
             encode_symbol(ecx, ebml_w, m.def_id.node);
         }
@@ -915,13 +922,13 @@ fn encode_extension_implementations(ecx: &EncodeContext,
 
 fn encode_info_for_item(ecx: &EncodeContext,
                         ebml_w: &mut writer::Encoder,
-                        item: @item,
+                        item: &item,
                         index: @RefCell<~[entry<i64>]>,
                         path: &[ast_map::path_elt],
                         vis: ast::visibility) {
     let tcx = ecx.tcx;
 
-    fn add_to_index(item: @item, ebml_w: &writer::Encoder,
+    fn add_to_index(item: &item, ebml_w: &writer::Encoder,
                      index: @RefCell<~[entry<i64>]>) {
         let mut index = index.borrow_mut();
         index.get().push(entry {
@@ -958,7 +965,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         }
 
         if !non_inlineable {
-            (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
+            (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item_ref(item));
         }
         encode_visibility(ebml_w, vis);
         ebml_w.end_tag();
@@ -974,7 +981,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
         encode_attributes(ebml_w, item.attrs);
         if tps_len > 0u || should_inline(item.attrs) {
-            (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
+            (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item_ref(item));
         } else {
             encode_symbol(ecx, ebml_w, item.id);
         }
@@ -1032,7 +1039,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         for v in (*enum_definition).variants.iter() {
             encode_variant_id(ebml_w, local_def(v.node.id));
         }
-        (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
+        (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item_ref(item));
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
 
         // Encode inherent implementations for this enumeration.
@@ -1077,7 +1084,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         needs to know*/
         encode_struct_fields(ecx, ebml_w, struct_def);
 
-        (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
+        (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item_ref(item));
 
         // Encode inherent implementations for this structure.
         encode_inherent_implementations(ecx, ebml_w, def_id);
@@ -1272,7 +1279,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                     encode_method_sort(ebml_w, 'p');
                     (ecx.encode_inlined_item)(
                         ecx, ebml_w, path,
-                        ii_method(def_id, true, m));
+                        ii_method_ref(def_id, true, m));
                 }
             }
 
@@ -1288,7 +1295,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
 fn encode_info_for_foreign_item(ecx: &EncodeContext,
                                 ebml_w: &mut writer::Encoder,
-                                nitem: @foreign_item,
+                                nitem: &foreign_item,
                                 index: @RefCell<~[entry<i64>]>,
                                 path: &ast_map::path,
                                 abi: AbiSet) {
@@ -1309,7 +1316,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));
         encode_name(ecx, ebml_w, nitem.ident);
         if abi.is_intrinsic() {
-            (ecx.encode_inlined_item)(ecx, ebml_w, *path, ii_foreign(nitem));
+            (ecx.encode_inlined_item)(ecx, ebml_w, *path, ii_foreign_ref(nitem));
         } else {
             encode_symbol(ecx, ebml_w, nitem.id);
         }
@@ -1331,9 +1338,9 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
     ebml_w.end_tag();
 }
 
-fn my_visit_expr(_e:@Expr) { }
+fn my_visit_expr(_e: &Expr) { }
 
-fn my_visit_item(i: @item,
+fn my_visit_item(i: &item,
                  items: ast_map::map,
                  ebml_w: &mut writer::Encoder,
                  ecx_ptr: *int,
@@ -1352,7 +1359,7 @@ fn my_visit_item(i: @item,
     }
 }
 
-fn my_visit_foreign_item(ni: @foreign_item,
+fn my_visit_foreign_item(ni: &foreign_item,
                          items: ast_map::map,
                          ebml_w: &mut writer::Encoder,
                          ecx_ptr:*int,
@@ -1391,11 +1398,11 @@ struct EncodeVisitor<'a,'b> {
 }
 
 impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> {
-    fn visit_expr(&mut self, ex:@Expr, _:()) {
+    fn visit_expr(&mut self, ex: &Expr, _: ()) {
         visit::walk_expr(self, ex, ());
         my_visit_expr(ex);
     }
-    fn visit_item(&mut self, i:@item, _:()) {
+    fn visit_item(&mut self, i: &item, _: ()) {
         visit::walk_item(self, i, ());
         my_visit_item(i,
                       self.items,
@@ -1403,7 +1410,7 @@ impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> {
                       self.ecx_ptr,
                       self.index);
     }
-    fn visit_foreign_item(&mut self, ni:@foreign_item, _:()) {
+    fn visit_foreign_item(&mut self, ni: &foreign_item, _: ()) {
         visit::walk_foreign_item(self, ni, ());
         my_visit_foreign_item(ni,
                               self.items,
@@ -1692,7 +1699,7 @@ struct ImplVisitor<'a,'b> {
 }
 
 impl<'a,'b> Visitor<()> for ImplVisitor<'a,'b> {
-    fn visit_item(&mut self, item: @item, _: ()) {
+    fn visit_item(&mut self, item: &item, _: ()) {
         match item.node {
             item_impl(_, Some(ref trait_ref), _, _) => {
                 let def_map = self.ecx.tcx.def_map;
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 2e18b9a7244..640d69432fc 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -24,14 +24,10 @@ use middle::{ty, typeck, moves};
 use middle;
 use util::ppaux::ty_to_str;
 
-use syntax::ast;
-use syntax::ast_map;
-use syntax::ast_util::inlined_item_utils;
-use syntax::ast_util;
+use syntax::{ast, ast_map, ast_util, codemap, fold};
 use syntax::codemap::Span;
-use syntax::codemap;
-use syntax::fold::*;
-use syntax::fold;
+use syntax::diagnostic::SpanHandler;
+use syntax::fold::ast_fold;
 use syntax::parse::token;
 use syntax;
 
@@ -84,24 +80,30 @@ trait tr_intern {
 pub fn encode_inlined_item(ecx: &e::EncodeContext,
                            ebml_w: &mut writer::Encoder,
                            path: &[ast_map::path_elt],
-                           ii: ast::inlined_item,
+                           ii: e::InlinedItemRef,
                            maps: Maps) {
+    let ident = match ii {
+        e::ii_item_ref(i) => i.ident,
+        e::ii_foreign_ref(i) => i.ident,
+        e::ii_method_ref(_, _, m) => m.ident,
+    };
     debug!("> Encoding inlined item: {}::{} ({})",
            ast_map::path_to_str(path, token::get_ident_interner()),
-           ecx.tcx.sess.str_of(ii.ident()),
+           ecx.tcx.sess.str_of(ident),
            ebml_w.writer.tell());
 
+    let ii = simplify_ast(ii);
     let id_range = ast_util::compute_id_range_for_inlined_item(&ii);
 
     ebml_w.start_tag(c::tag_ast as uint);
     id_range.encode(ebml_w);
-    encode_ast(ebml_w, simplify_ast(&ii));
+    encode_ast(ebml_w, ii);
     encode_side_tables_for_ii(ecx, maps, ebml_w, &ii);
     ebml_w.end_tag();
 
     debug!("< Encoded inlined fn: {}::{} ({})",
            ast_map::path_to_str(path, token::get_ident_interner()),
-           ecx.tcx.sess.str_of(ii.ident()),
+           ecx.tcx.sess.str_of(ident),
            ebml_w.writer.tell());
 }
 
@@ -130,15 +132,20 @@ pub fn decode_inlined_item(cdata: @cstore::crate_metadata,
             to_id_range: to_id_range
         };
         let raw_ii = decode_ast(ast_doc);
-        let ii = renumber_ast(xcx, raw_ii);
-        debug!("Fn named: {}", tcx.sess.str_of(ii.ident()));
+        let ii = renumber_and_map_ast(xcx,
+                                      tcx.sess.diagnostic(),
+                                      dcx.tcx.items,
+                                      path.to_owned(),
+                                      raw_ii);
+        let ident = match ii {
+            ast::ii_item(i) => i.ident,
+            ast::ii_foreign(i) => i.ident,
+            ast::ii_method(_, _, m) => m.ident,
+        };
+        debug!("Fn named: {}", tcx.sess.str_of(ident));
         debug!("< Decoded inlined fn: {}::{}",
                ast_map::path_to_str(path, token::get_ident_interner()),
-               tcx.sess.str_of(ii.ident()));
-        ast_map::map_decoded_item(tcx.sess.diagnostic(),
-                                  dcx.tcx.items,
-                                  path.to_owned(),
-                                  &ii);
+               tcx.sess.str_of(ident));
         decode_side_tables(xcx, ast_doc);
         match ii {
           ast::ii_item(i) => {
@@ -295,11 +302,9 @@ fn encode_ast(ebml_w: &mut writer::Encoder, item: ast::inlined_item) {
     ebml_w.end_tag();
 }
 
-struct NestedItemsDropper {
-    contents: (),
-}
+struct NestedItemsDropper;
 
-impl fold::ast_fold for NestedItemsDropper {
+impl ast_fold for NestedItemsDropper {
     fn fold_block(&mut self, blk: ast::P<ast::Block>) -> ast::P<ast::Block> {
         let stmts_sans_items = blk.stmts.iter().filter_map(|stmt| {
             match stmt.node {
@@ -338,18 +343,15 @@ impl fold::ast_fold for NestedItemsDropper {
 // As it happens, trans relies on the fact that we do not export
 // nested items, as otherwise it would get confused when translating
 // inlined items.
-fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
-    let mut fld = NestedItemsDropper {
-        contents: (),
-    };
+fn simplify_ast(ii: e::InlinedItemRef) -> ast::inlined_item {
+    let mut fld = NestedItemsDropper;
 
-    match *ii {
-        //hack: we're not dropping items
-        ast::ii_item(i) => ast::ii_item(fld.fold_item(i)
-                                        .expect_one("expected one item")),
-        ast::ii_method(d, is_provided, m) =>
-          ast::ii_method(d, is_provided, fld.fold_method(m)),
-        ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
+    match ii {
+        // HACK we're not dropping items.
+        e::ii_item_ref(i) => ast::ii_item(fold::noop_fold_item(i, &mut fld)
+                                          .expect_one("expected one item")),
+        e::ii_method_ref(d, p, m) => ast::ii_method(d, p, fold::noop_fold_method(m, &mut fld)),
+        e::ii_foreign_ref(i) => ast::ii_foreign(fold::noop_fold_foreign_item(i, &mut fld))
     }
 }
 
@@ -363,27 +365,31 @@ struct AstRenumberer {
     xcx: @ExtendedDecodeContext,
 }
 
-impl fold::ast_fold for AstRenumberer {
-    fn new_id(&mut self, id: ast::NodeId) -> ast::NodeId {
+impl ast_map::FoldOps for AstRenumberer {
+    fn new_id(&self, id: ast::NodeId) -> ast::NodeId {
         self.xcx.tr_id(id)
     }
-    fn new_span(&mut self, span: Span) -> Span {
+    fn new_span(&self, span: Span) -> Span {
         self.xcx.tr_span(span)
     }
 }
 
-fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
-    -> ast::inlined_item {
-    let mut fld = AstRenumberer {
-        xcx: xcx,
-    };
-    match ii {
-        ast::ii_item(i) => ast::ii_item(fld.fold_item(i)
-                                        .expect_one("expected one item")),
-        ast::ii_method(d, is_provided, m) =>
-          ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m)),
-        ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)),
-    }
+fn renumber_and_map_ast(xcx: @ExtendedDecodeContext,
+                        diag: @SpanHandler,
+                        map: ast_map::map,
+                        path: ast_map::path,
+                        ii: ast::inlined_item) -> ast::inlined_item {
+    ast_map::map_decoded_item(diag, map, path, AstRenumberer { xcx: xcx }, |fld| {
+        match ii {
+            ast::ii_item(i) => {
+                ast::ii_item(fld.fold_item(i).expect_one("expected one item"))
+            }
+            ast::ii_method(d, is_provided, m) => {
+                ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m))
+            }
+            ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
+        }
+    })
 }
 
 // ______________________________________________________________________
@@ -1504,13 +1510,14 @@ fn test_more() {
 #[test]
 fn test_simplification() {
     let cx = mk_ctxt();
-    let item_in = ast::ii_item(quote_item!(cx,
+    let item = quote_item!(cx,
         fn new_int_alist<B>() -> alist<int, B> {
             fn eq_int(a: int, b: int) -> bool { a == b }
             return alist {eq_fn: eq_int, data: ~[]};
         }
-    ).unwrap());
-    let item_out = simplify_ast(&item_in);
+    ).unwrap();
+    let item_in = e::ii_item_ref(item);
+    let item_out = simplify_ast(item_in);
     let item_exp = ast::ii_item(quote_item!(cx,
         fn new_int_alist<B>() -> alist<int, B> {
             return alist {eq_fn: eq_int, data: ~[]};
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index c26efbcb498..cf5a02d48e0 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -30,30 +30,29 @@ use syntax::visit::Visitor;
 use syntax::visit;
 use util::ppaux::Repr;
 
-#[deriving(Clone)]
 struct CheckLoanCtxt<'a> {
     bccx: &'a BorrowckCtxt,
     dfcx_loans: &'a LoanDataFlow,
-    move_data: @move_data::FlowedMoveData,
+    move_data: move_data::FlowedMoveData,
     all_loans: &'a [Loan],
 }
 
 impl<'a> Visitor<()> for CheckLoanCtxt<'a> {
 
-    fn visit_expr(&mut self, ex:@ast::Expr, _:()) {
+    fn visit_expr(&mut self, ex: &ast::Expr, _: ()) {
         check_loans_in_expr(self, ex);
     }
-    fn visit_local(&mut self, l:@ast::Local, _:()) {
+    fn visit_local(&mut self, l: &ast::Local, _: ()) {
         check_loans_in_local(self, l);
     }
-    fn visit_block(&mut self, b:ast::P<ast::Block>, _:()) {
+    fn visit_block(&mut self, b: &ast::Block, _: ()) {
         check_loans_in_block(self, b);
     }
-    fn visit_pat(&mut self, p:&ast::Pat, _:()) {
+    fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
         check_loans_in_pat(self, p);
     }
-    fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
-                b:ast::P<ast::Block>, s:Span, n:ast::NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &ast::fn_decl,
+                b: &ast::Block, s: Span, n: ast::NodeId, _: ()) {
         check_loans_in_fn(self, fk, fd, b, s, n);
     }
 
@@ -65,13 +64,13 @@ pub fn check_loans(bccx: &BorrowckCtxt,
                    dfcx_loans: &LoanDataFlow,
                    move_data: move_data::FlowedMoveData,
                    all_loans: &[Loan],
-                   body: ast::P<ast::Block>) {
+                   body: &ast::Block) {
     debug!("check_loans(body id={:?})", body.id);
 
     let mut clcx = CheckLoanCtxt {
         bccx: bccx,
         dfcx_loans: dfcx_loans,
-        move_data: @move_data,
+        move_data: move_data,
         all_loans: all_loans,
     };
 
@@ -107,9 +106,9 @@ impl<'a> CheckLoanCtxt<'a> {
         //! Like `each_issued_loan()`, but only considers loans that are
         //! currently in scope.
 
-        let region_maps = self.tcx().region_maps;
+        let tcx = self.tcx();
         self.each_issued_loan(scope_id, |loan| {
-            if region_maps.is_subscope_of(scope_id, loan.kill_scope) {
+            if tcx.region_maps.is_subscope_of(scope_id, loan.kill_scope) {
                 op(loan)
             } else {
                 true
@@ -190,9 +189,8 @@ impl<'a> CheckLoanCtxt<'a> {
                new_loan.repr(self.tcx()));
 
         // Should only be called for loans that are in scope at the same time.
-        let region_maps = self.tcx().region_maps;
-        assert!(region_maps.scopes_intersect(old_loan.kill_scope,
-                                             new_loan.kill_scope));
+        assert!(self.tcx().region_maps.scopes_intersect(old_loan.kill_scope,
+                                                        new_loan.kill_scope));
 
         self.report_error_if_loan_conflicts_with_restriction(
             old_loan, new_loan, old_loan, new_loan) &&
@@ -290,7 +288,7 @@ impl<'a> CheckLoanCtxt<'a> {
         });
     }
 
-    pub fn check_assignment(&self, expr: @ast::Expr) {
+    pub fn check_assignment(&self, expr: &ast::Expr) {
         // We don't use cat_expr() here because we don't want to treat
         // auto-ref'd parameters in overloaded operators as rvalues.
         let adj = {
@@ -401,7 +399,7 @@ impl<'a> CheckLoanCtxt<'a> {
         }
 
         fn check_for_aliasable_mutable_writes(this: &CheckLoanCtxt,
-                                              expr: @ast::Expr,
+                                              expr: &ast::Expr,
                                               cmt: mc::cmt) -> bool {
             //! Safety checks related to writes to aliasable, mutable locations
 
@@ -422,7 +420,7 @@ impl<'a> CheckLoanCtxt<'a> {
         }
 
         fn check_for_aliasability_violation(this: &CheckLoanCtxt,
-                                            expr: @ast::Expr,
+                                            expr: &ast::Expr,
                                             cmt: mc::cmt) -> bool {
             let mut cmt = cmt;
 
@@ -467,7 +465,7 @@ impl<'a> CheckLoanCtxt<'a> {
 
         fn check_for_assignment_to_restricted_or_frozen_location(
             this: &CheckLoanCtxt,
-            expr: @ast::Expr,
+            expr: &ast::Expr,
             cmt: mc::cmt) -> bool
         {
             //! Check for assignments that violate the terms of an
@@ -601,7 +599,7 @@ impl<'a> CheckLoanCtxt<'a> {
     }
 
     pub fn report_illegal_mutation(&self,
-                                   expr: @ast::Expr,
+                                   expr: &ast::Expr,
                                    loan_path: &LoanPath,
                                    loan: &Loan) {
         self.bccx.span_err(
@@ -614,7 +612,7 @@ impl<'a> CheckLoanCtxt<'a> {
                  self.bccx.loan_path_to_str(loan_path)));
     }
 
-    fn check_move_out_from_expr(&self, expr: @ast::Expr) {
+    fn check_move_out_from_expr(&self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprFnBlock(..) | ast::ExprProc(..) => {
                 // moves due to capture clauses are checked
@@ -668,7 +666,7 @@ impl<'a> CheckLoanCtxt<'a> {
     }
 
     pub fn check_call(&self,
-                      _expr: @ast::Expr,
+                      _expr: &ast::Expr,
                       _callee: Option<@ast::Expr>,
                       _callee_id: ast::NodeId,
                       _callee_span: Span,
@@ -686,7 +684,7 @@ impl<'a> CheckLoanCtxt<'a> {
 fn check_loans_in_fn<'a>(this: &mut CheckLoanCtxt<'a>,
                          fk: &visit::fn_kind,
                          decl: &ast::fn_decl,
-                         body: ast::P<ast::Block>,
+                         body: &ast::Block,
                          sp: Span,
                          id: ast::NodeId) {
     match *fk {
@@ -746,12 +744,12 @@ fn check_loans_in_fn<'a>(this: &mut CheckLoanCtxt<'a>,
 }
 
 fn check_loans_in_local<'a>(this: &mut CheckLoanCtxt<'a>,
-                            local: @ast::Local) {
+                            local: &ast::Local) {
     visit::walk_local(this, local, ());
 }
 
 fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
-                           expr: @ast::Expr) {
+                           expr: &ast::Expr) {
     visit::walk_expr(this, expr, ());
 
     debug!("check_loans_in_expr(expr={})",
@@ -818,7 +816,7 @@ fn check_loans_in_pat<'a>(this: &mut CheckLoanCtxt<'a>,
 }
 
 fn check_loans_in_block<'a>(this: &mut CheckLoanCtxt<'a>,
-                            blk: ast::P<ast::Block>)
+                            blk: &ast::Block)
 {
     visit::walk_block(this, blk, ());
     this.check_for_conflicting_loans(blk.id);
diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
index 3b16d7e7e1c..9ba8e00dc8e 100644
--- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs
@@ -33,18 +33,16 @@ pub fn gather_decl(bccx: &BorrowckCtxt,
 
 pub fn gather_move_from_expr(bccx: &BorrowckCtxt,
                              move_data: &MoveData,
-                             move_expr: @ast::Expr,
+                             move_expr: &ast::Expr,
                              cmt: mc::cmt) {
-    gather_move_from_expr_or_pat(bccx, move_data, move_expr.id,
-                                 MoveExpr(move_expr), cmt);
+    gather_move_from_expr_or_pat(bccx, move_data, move_expr.id, MoveExpr, cmt);
 }
 
 pub fn gather_move_from_pat(bccx: &BorrowckCtxt,
                             move_data: &MoveData,
-                            move_pat: @ast::Pat,
+                            move_pat: &ast::Pat,
                             cmt: mc::cmt) {
-    gather_move_from_expr_or_pat(bccx, move_data, move_pat.id,
-                                 MovePat(move_pat), cmt);
+    gather_move_from_expr_or_pat(bccx, move_data, move_pat.id, MovePat, cmt);
 }
 
 fn gather_move_from_expr_or_pat(bccx: &BorrowckCtxt,
@@ -68,7 +66,7 @@ fn gather_move_from_expr_or_pat(bccx: &BorrowckCtxt,
 
 pub fn gather_captures(bccx: &BorrowckCtxt,
                        move_data: &MoveData,
-                       closure_expr: @ast::Expr) {
+                       closure_expr: &ast::Expr) {
     let capture_map = bccx.capture_map.borrow();
     let captured_vars = capture_map.get().get(&closure_expr.id);
     for captured_var in captured_vars.iter() {
@@ -77,7 +75,7 @@ pub fn gather_captures(bccx: &BorrowckCtxt,
                 let fvar_id = ast_util::def_id_of_def(captured_var.def).node;
                 let loan_path = @LpVar(fvar_id);
                 move_data.add_move(bccx.tcx, loan_path, closure_expr.id,
-                                   Captured(closure_expr));
+                                   Captured);
             }
             moves::CapCopy | moves::CapRef => {}
         }
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index 86ccfda90c9..accbd4d8ccb 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -33,7 +33,7 @@ use syntax::codemap::Span;
 use syntax::print::pprust;
 use syntax::visit;
 use syntax::visit::{Visitor, fn_kind};
-use syntax::ast::{P, Expr, fn_decl, Block, NodeId, Stmt, Pat, Local};
+use syntax::ast::{Expr, fn_decl, Block, NodeId, Stmt, Pat, Local};
 
 mod lifetime;
 mod restrictions;
@@ -68,50 +68,50 @@ mod gather_moves;
 struct GatherLoanCtxt<'a> {
     bccx: &'a BorrowckCtxt,
     id_range: id_range,
-    move_data: @move_data::MoveData,
+    move_data: move_data::MoveData,
     all_loans: @RefCell<~[Loan]>,
     item_ub: ast::NodeId,
     repeating_ids: ~[ast::NodeId]
 }
 
 impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
-    fn visit_expr(&mut self, ex:@Expr, _:()) {
+    fn visit_expr(&mut self, ex: &Expr, _: ()) {
         gather_loans_in_expr(self, ex);
     }
-    fn visit_block(&mut self, b:P<Block>, _:()) {
+    fn visit_block(&mut self, b: &Block, _: ()) {
         gather_loans_in_block(self, b);
     }
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>,
-                s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &fn_kind, fd: &fn_decl, b: &Block,
+                s: Span, n: NodeId, _: ()) {
         gather_loans_in_fn(self, fk, fd, b, s, n);
     }
-    fn visit_stmt(&mut self, s:@Stmt, _:()) {
+    fn visit_stmt(&mut self, s: &Stmt, _: ()) {
         visit::walk_stmt(self, s, ());
     }
-    fn visit_pat(&mut self, p:&Pat, _:()) {
+    fn visit_pat(&mut self, p: &Pat, _: ()) {
         add_pat_to_id_range(self, p);
     }
-    fn visit_local(&mut self, l:@Local, _:()) {
+    fn visit_local(&mut self, l: &Local, _: ()) {
         gather_loans_in_local(self, l);
     }
 
     // #7740: Do not visit items here, not even fn items nor methods
     // of impl items; the outer loop in borrowck/mod will visit them
     // for us in turn.  Thus override visit_item's walk with a no-op.
-    fn visit_item(&mut self, _:@ast::item, _:()) { }
+    fn visit_item(&mut self, _: &ast::item, _: ()) { }
 }
 
 pub fn gather_loans(bccx: &BorrowckCtxt,
                     decl: &ast::fn_decl,
-                    body: ast::P<ast::Block>)
-                    -> (id_range, @RefCell<~[Loan]>, @move_data::MoveData) {
+                    body: &ast::Block)
+                    -> (id_range, @RefCell<~[Loan]>, move_data::MoveData) {
     let mut glcx = GatherLoanCtxt {
         bccx: bccx,
         id_range: id_range::max(),
         all_loans: @RefCell::new(~[]),
         item_ub: body.id,
         repeating_ids: ~[body.id],
-        move_data: @MoveData::new()
+        move_data: MoveData::new()
     };
     glcx.gather_fn_arg_patterns(decl, body);
 
@@ -132,7 +132,7 @@ fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
 fn gather_loans_in_fn(this: &mut GatherLoanCtxt,
                       fk: &fn_kind,
                       decl: &ast::fn_decl,
-                      body: ast::P<ast::Block>,
+                      body: &ast::Block,
                       sp: Span,
                       id: ast::NodeId) {
     match fk {
@@ -151,20 +151,20 @@ fn gather_loans_in_fn(this: &mut GatherLoanCtxt,
 }
 
 fn gather_loans_in_block(this: &mut GatherLoanCtxt,
-                         blk: ast::P<ast::Block>) {
+                         blk: &ast::Block) {
     this.id_range.add(blk.id);
     visit::walk_block(this, blk, ());
 }
 
 fn gather_loans_in_local(this: &mut GatherLoanCtxt,
-                         local: @ast::Local) {
+                         local: &ast::Local) {
     match local.init {
         None => {
             // Variable declarations without initializers are considered "moves":
             let tcx = this.bccx.tcx;
             pat_util::pat_bindings(tcx.def_map, local.pat, |_, id, span, _| {
                 gather_moves::gather_decl(this.bccx,
-                                          this.move_data,
+                                          &this.move_data,
                                           id,
                                           span,
                                           id);
@@ -175,7 +175,7 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
             let tcx = this.bccx.tcx;
             pat_util::pat_bindings(tcx.def_map, local.pat, |_, id, span, _| {
                 gather_moves::gather_assignment(this.bccx,
-                                                this.move_data,
+                                                &this.move_data,
                                                 id,
                                                 span,
                                                 @LpVar(id),
@@ -191,7 +191,7 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
 
 
 fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
-                        ex: @ast::Expr) {
+                        ex: &ast::Expr) {
     let bccx = this.bccx;
     let tcx = bccx.tcx;
 
@@ -220,7 +220,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
     if this.bccx.is_move(ex.id) {
         let cmt = this.bccx.cat_expr(ex);
         gather_moves::gather_move_from_expr(
-            this.bccx, this.move_data, ex, cmt);
+            this.bccx, &this.move_data, ex, cmt);
     }
 
     // Special checks for various kinds of expressions:
@@ -247,7 +247,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
           let l_cmt = this.bccx.cat_expr(l);
           match opt_loan_path(l_cmt) {
               Some(l_lp) => {
-                  gather_moves::gather_assignment(this.bccx, this.move_data,
+                  gather_moves::gather_assignment(this.bccx, &this.move_data,
                                                   ex.id, ex.span,
                                                   l_lp, l.id);
               }
@@ -309,7 +309,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
       }
 
       ast::ExprFnBlock(..) | ast::ExprProc(..) => {
-          gather_moves::gather_captures(this.bccx, this.move_data, ex);
+          gather_moves::gather_captures(this.bccx, &this.move_data, ex);
           visit::walk_expr(this, ex, ());
       }
 
@@ -318,7 +318,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
               let out_cmt = this.bccx.cat_expr(out);
               match opt_loan_path(out_cmt) {
                   Some(out_lp) => {
-                      gather_moves::gather_assignment(this.bccx, this.move_data,
+                      gather_moves::gather_assignment(this.bccx, &this.move_data,
                                                       ex.id, ex.span,
                                                       out_lp, out.id);
                   }
@@ -349,7 +349,7 @@ impl<'a> GatherLoanCtxt<'a> {
     }
 
     pub fn guarantee_adjustments(&mut self,
-                                 expr: @ast::Expr,
+                                 expr: &ast::Expr,
                                  adjustment: &ty::AutoAdjustment) {
         debug!("guarantee_adjustments(expr={}, adjustment={:?})",
                expr.repr(self.tcx()), adjustment);
@@ -639,8 +639,7 @@ impl<'a> GatherLoanCtxt<'a> {
         //! notably method arguments, the loan may be introduced only
         //! later, once it comes into scope.
 
-        let rm = self.bccx.tcx.region_maps;
-        if rm.is_subscope_of(borrow_id, loan_scope) {
+        if self.bccx.tcx.region_maps.is_subscope_of(borrow_id, loan_scope) {
             borrow_id
         } else {
             loan_scope
@@ -668,12 +667,11 @@ impl<'a> GatherLoanCtxt<'a> {
         //! with immutable `&` pointers, because borrows of such pointers
         //! do not require restrictions and hence do not cause a loan.
 
-        let rm = self.bccx.tcx.region_maps;
-        let lexical_scope = rm.encl_scope(lp.node_id());
-        if rm.is_subscope_of(lexical_scope, loan_scope) {
+        let lexical_scope = self.bccx.tcx.region_maps.encl_scope(lp.node_id());
+        if self.bccx.tcx.region_maps.is_subscope_of(lexical_scope, loan_scope) {
             lexical_scope
         } else {
-            assert!(rm.is_subscope_of(loan_scope, lexical_scope));
+            assert!(self.bccx.tcx.region_maps.is_subscope_of(loan_scope, lexical_scope));
             loan_scope
         }
     }
@@ -704,7 +702,7 @@ impl<'a> GatherLoanCtxt<'a> {
 
     fn gather_pat(&mut self,
                   discr_cmt: mc::cmt,
-                  root_pat: @ast::Pat,
+                  root_pat: &ast::Pat,
                   arm_match_ids: Option<(ast::NodeId, ast::NodeId)>) {
         /*!
          * Walks patterns, examining the bindings to determine if they
@@ -755,7 +753,7 @@ impl<'a> GatherLoanCtxt<'a> {
                       // No borrows here, but there may be moves
                       if self.bccx.is_move(pat.id) {
                           gather_moves::gather_move_from_pat(
-                              self.bccx, self.move_data, pat, cmt);
+                              self.bccx, &self.move_data, pat, cmt);
                       }
                   }
                 }
@@ -804,7 +802,7 @@ impl<'a> GatherLoanCtxt<'a> {
         })
     }
 
-    pub fn vec_slice_info(&self, pat: @ast::Pat, slice_ty: ty::t)
+    pub fn vec_slice_info(&self, pat: &ast::Pat, slice_ty: ty::t)
                           -> (ast::Mutability, ty::Region) {
         /*!
          *
@@ -831,8 +829,7 @@ impl<'a> GatherLoanCtxt<'a> {
         }
     }
 
-    pub fn pat_is_binding(&self, pat: @ast::Pat) -> bool {
+    pub fn pat_is_binding(&self, pat: &ast::Pat) -> bool {
         pat_util::pat_is_binding(self.bccx.tcx.def_map, pat)
     }
 }
-
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 6193c6fc898..dc645bc9a6f 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -29,7 +29,7 @@ use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit;
 use syntax::visit::{Visitor,fn_kind};
-use syntax::ast::{P,fn_decl,Block,NodeId};
+use syntax::ast::{fn_decl,Block,NodeId};
 
 macro_rules! if_ok(
     ($inp: expr) => (
@@ -61,8 +61,8 @@ impl Clone for LoanDataFlowOperator {
 pub type LoanDataFlow = DataFlowContext<LoanDataFlowOperator>;
 
 impl Visitor<()> for BorrowckCtxt {
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl,
-                b:P<Block>, s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &fn_kind, fd: &fn_decl,
+                b: &Block, s: Span, n: NodeId, _: ()) {
         borrowck_fn(self, fk, fd, b, s, n);
     }
 }
@@ -116,7 +116,7 @@ pub fn check_crate(tcx: ty::ctxt,
 fn borrowck_fn(this: &mut BorrowckCtxt,
                fk: &visit::fn_kind,
                decl: &ast::fn_decl,
-               body: ast::P<ast::Block>,
+               body: &ast::Block,
                sp: Span,
                id: ast::NodeId) {
     match fk {
@@ -455,17 +455,17 @@ impl BorrowckCtxt {
         moves_map.get().contains(&id)
     }
 
-    pub fn cat_expr(&self, expr: @ast::Expr) -> mc::cmt {
+    pub fn cat_expr(&self, expr: &ast::Expr) -> mc::cmt {
         mc::cat_expr(self.tcx, self.method_map, expr)
     }
 
-    pub fn cat_expr_unadjusted(&self, expr: @ast::Expr) -> mc::cmt {
+    pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> mc::cmt {
         mc::cat_expr_unadjusted(self.tcx, self.method_map, expr)
     }
 
     pub fn cat_expr_autoderefd(&self,
-                               expr: @ast::Expr,
-                               adj: @ty::AutoAdjustment)
+                               expr: &ast::Expr,
+                               adj: &ty::AutoAdjustment)
                                -> mc::cmt {
         match *adj {
             ty::AutoAddEnv(..) | ty::AutoObject(..) => {
@@ -504,8 +504,8 @@ impl BorrowckCtxt {
 
     pub fn cat_pattern(&self,
                        cmt: mc::cmt,
-                       pat: @ast::Pat,
-                       op: |mc::cmt, @ast::Pat|) {
+                       pat: &ast::Pat,
+                       op: |mc::cmt, &ast::Pat|) {
         let mc = self.mc_ctxt();
         mc.cat_pattern(cmt, pat, op);
     }
@@ -550,34 +550,48 @@ impl BorrowckCtxt {
         match move.kind {
             move_data::Declared => {}
 
-            move_data::MoveExpr(expr) => {
-                let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
+            move_data::MoveExpr => {
+                let items = self.tcx.items.borrow();
+                let (expr_ty, expr_span) = match items.get().find(&move.id) {
+                    Some(&ast_map::node_expr(expr)) => {
+                        (ty::expr_ty_adjusted(self.tcx, expr), expr.span)
+                    }
+                    r => self.tcx.sess.bug(format!("MoveExpr({:?}) maps to {:?}, not Expr",
+                                                   move.id, r))
+                };
                 let suggestion = move_suggestion(self.tcx, expr_ty,
                         "moved by default (use `copy` to override)");
                 self.tcx.sess.span_note(
-                    expr.span,
+                    expr_span,
                     format!("`{}` moved here because it has type `{}`, which is {}",
                          self.loan_path_to_str(moved_lp),
                          expr_ty.user_string(self.tcx), suggestion));
             }
 
-            move_data::MovePat(pat) => {
-                let pat_ty = ty::node_id_to_type(self.tcx, pat.id);
+            move_data::MovePat => {
+                let pat_ty = ty::node_id_to_type(self.tcx, move.id);
                 self.tcx.sess.span_note(
-                    pat.span,
+                    ast_map::node_span(self.tcx.items, move.id),
                     format!("`{}` moved here because it has type `{}`, \
                           which is moved by default (use `ref` to override)",
                          self.loan_path_to_str(moved_lp),
                          pat_ty.user_string(self.tcx)));
             }
 
-            move_data::Captured(expr) => {
-                let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
+            move_data::Captured => {
+                let items = self.tcx.items.borrow();
+                let (expr_ty, expr_span) = match items.get().find(&move.id) {
+                    Some(&ast_map::node_expr(expr)) => {
+                        (ty::expr_ty_adjusted(self.tcx, expr), expr.span)
+                    }
+                    r => self.tcx.sess.bug(format!("Captured({:?}) maps to {:?}, not Expr",
+                                                   move.id, r))
+                };
                 let suggestion = move_suggestion(self.tcx, expr_ty,
                         "moved by default (make a copy and \
                          capture that instead to override)");
                 self.tcx.sess.span_note(
-                    expr.span,
+                    expr_span,
                     format!("`{}` moved into closure environment here because it \
                           has type `{}`, which is {}",
                          self.loan_path_to_str(moved_lp),
@@ -757,7 +771,7 @@ impl BorrowckCtxt {
             LpVar(id) => {
                 let items = self.tcx.items.borrow();
                 match items.get().find(&id) {
-                    Some(&ast_map::node_local(ref ident)) => {
+                    Some(&ast_map::node_local(ref ident, _)) => {
                         out.push_str(token::ident_to_str(ident));
                     }
                     r => {
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index a59b58e96c0..f6d1417d0de 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -53,12 +53,7 @@ pub struct MoveData {
 }
 
 pub struct FlowedMoveData {
-    move_data: @MoveData,
-    //         ^~~~~~~~~
-    // It makes me sad to use @ here, except that due to
-    // the old visitor design, this is what gather_loans
-    // used to have to produce, and this code hasn't been
-    // updated.
+    move_data: MoveData,
 
     dfcx_moves: MoveDataFlow,
 
@@ -120,10 +115,10 @@ pub struct MovePath {
 }
 
 pub enum MoveKind {
-    Declared,               // When declared, variables start out "moved".
-    MoveExpr(@ast::Expr),   // Expression or binding that moves a variable
-    MovePat(@ast::Pat),     // By-move binding
-    Captured(@ast::Expr),   // Closure creation that moves a value
+    Declared,   // When declared, variables start out "moved".
+    MoveExpr,   // Expression or binding that moves a variable
+    MovePat,    // By-move binding
+    Captured    // Closure creation that moves a value
 }
 
 pub struct Move {
@@ -137,7 +132,7 @@ pub struct Move {
     kind: MoveKind,
 
     /// Next node in linked list of moves from `path`, or `InvalidMoveIndex`
-    next_move: MoveIndex,
+    next_move: MoveIndex
 }
 
 pub struct Assignment {
@@ -568,7 +563,7 @@ impl MoveData {
 }
 
 impl FlowedMoveData {
-    pub fn new(move_data: @MoveData,
+    pub fn new(move_data: MoveData,
                tcx: ty::ctxt,
                method_map: typeck::method_map,
                id_range: ast_util::id_range,
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index c56a268c48f..1e373d1f82d 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -15,7 +15,6 @@ use middle::ty;
 use middle::typeck;
 use util::ppaux;
 
-use std::cell::RefCell;
 use syntax::ast::*;
 use syntax::codemap;
 use syntax::{ast_util, ast_map};
@@ -31,13 +30,13 @@ struct CheckCrateVisitor {
 }
 
 impl Visitor<bool> for CheckCrateVisitor {
-    fn visit_item(&mut self, i:@item, env:bool) {
+    fn visit_item(&mut self, i: &item, env: bool) {
         check_item(self, self.sess, self.ast_map, self.def_map, i, env);
     }
-    fn visit_pat(&mut self, p:&Pat, env:bool) {
+    fn visit_pat(&mut self, p: &Pat, env: bool) {
         check_pat(self, p, env);
     }
-    fn visit_expr(&mut self, ex:@Expr, env:bool) {
+    fn visit_expr(&mut self, ex: &Expr, env: bool) {
         check_expr(self, self.sess, self.def_map, self.method_map,
                    self.tcx, ex, env);
     }
@@ -64,7 +63,7 @@ pub fn check_item(v: &mut CheckCrateVisitor,
                   sess: Session,
                   ast_map: ast_map::map,
                   def_map: resolve::DefMap,
-                  it: @item,
+                  it: &item,
                   _is_const: bool) {
     match it.node {
       item_static(_, _, ex) => {
@@ -111,7 +110,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
                   def_map: resolve::DefMap,
                   method_map: typeck::method_map,
                   tcx: ty::ctxt,
-                  e: @Expr,
+                  e: &Expr,
                   is_const: bool) {
     if is_const {
         match e.node {
@@ -211,17 +210,12 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
     visit::walk_expr(v, e, is_const);
 }
 
-#[deriving(Clone)]
-struct env {
-    root_it: @item,
+struct CheckItemRecursionVisitor<'a> {
+    root_it: &'a item,
     sess: Session,
     ast_map: ast_map::map,
     def_map: resolve::DefMap,
-    idstack: @RefCell<~[NodeId]>,
-}
-
-struct CheckItemRecursionVisitor {
-    env: env,
+    idstack: ~[NodeId]
 }
 
 // Make sure a const item doesn't recursively refer to itself
@@ -229,44 +223,36 @@ struct CheckItemRecursionVisitor {
 pub fn check_item_recursion(sess: Session,
                             ast_map: ast_map::map,
                             def_map: resolve::DefMap,
-                            it: @item) {
-    let env = env {
+                            it: &item) {
+
+    let mut visitor = CheckItemRecursionVisitor {
         root_it: it,
         sess: sess,
         ast_map: ast_map,
         def_map: def_map,
-        idstack: @RefCell::new(~[]),
+        idstack: ~[]
     };
-
-    let mut visitor = CheckItemRecursionVisitor { env: env };
     visitor.visit_item(it, ());
 }
 
-impl Visitor<()> for CheckItemRecursionVisitor {
-    fn visit_item(&mut self, it: @item, _: ()) {
-        {
-            let mut idstack = self.env.idstack.borrow_mut();
-            if idstack.get().iter().any(|x| x == &(it.id)) {
-                self.env.sess.span_fatal(self.env.root_it.span,
-                                         "recursive constant");
-            }
-            idstack.get().push(it.id);
+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, ());
-        {
-            let mut idstack = self.env.idstack.borrow_mut();
-            idstack.get().pop();
-        }
+        self.idstack.pop();
     }
 
-    fn visit_expr(&mut self, e: @Expr, _: ()) {
+    fn visit_expr(&mut self, e: &Expr, _: ()) {
         match e.node {
             ExprPath(..) => {
-                let def_map = self.env.def_map.borrow();
+                let def_map = self.def_map.borrow();
                 match def_map.get().find(&e.id) {
                     Some(&DefStatic(def_id, _)) if
                             ast_util::is_local(def_id) => {
-                        let ast_map = self.env.ast_map.borrow();
+                        let ast_map = self.ast_map.borrow();
                         match ast_map.get().get_copy(&def_id.node) {
                             ast_map::node_item(it, _) => {
                                 self.visit_item(it, ());
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index 332e63288a1..456c9341654 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -29,11 +29,11 @@ pub fn check_crate(tcx: ty::ctxt, crate: &ast::Crate) {
 }
 
 impl Visitor<Context> for CheckLoopVisitor {
-    fn visit_item(&mut self, i: @ast::item, _cx: Context) {
+    fn visit_item(&mut self, i: &ast::item, _cx: Context) {
         visit::walk_item(self, i, Normal);
     }
 
-    fn visit_expr(&mut self, e: @ast::Expr, cx:Context) {
+    fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
         match e.node {
             ast::ExprWhile(e, b) => {
                 self.visit_expr(e, cx);
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 079c2750268..4688760d6c1 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -38,14 +38,14 @@ struct CheckMatchVisitor {
 }
 
 impl Visitor<()> for CheckMatchVisitor {
-    fn visit_expr(&mut self, ex:@Expr, e:()) {
-        check_expr(self, self.cx, ex, e);
+    fn visit_expr(&mut self, ex: &Expr, _: ()) {
+        check_expr(self, self.cx, ex, ());
     }
-    fn visit_local(&mut self, l:@Local, e:()) {
-        check_local(self, self.cx, l, e);
+    fn visit_local(&mut self, l: &Local, _: ()) {
+        check_local(self, self.cx, l, ());
     }
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, e:()) {
-        check_fn(self, self.cx, fk, fd, b, s, n, e);
+    fn visit_fn(&mut self, fk: &fn_kind, fd: &fn_decl, b: &Block, s: Span, n: NodeId, _: ()) {
+        check_fn(self, self.cx, fk, fd, b, s, n, ());
     }
 }
 
@@ -65,7 +65,7 @@ pub fn check_crate(tcx: ty::ctxt,
 
 fn check_expr(v: &mut CheckMatchVisitor,
                   cx: @MatchCheckCtxt,
-                  ex: @Expr,
+                  ex: &Expr,
                   s: ()) {
     visit::walk_expr(v, ex, s);
     match ex.node {
@@ -830,7 +830,7 @@ fn default(cx: &MatchCheckCtxt, r: &[@Pat]) -> Option<~[@Pat]> {
 
 fn check_local(v: &mut CheckMatchVisitor,
                    cx: &MatchCheckCtxt,
-                   loc: @Local,
+                   loc: &Local,
                    s: ()) {
     visit::walk_local(v, loc, s);
     if is_refutable(cx, loc.pat) {
@@ -846,7 +846,7 @@ fn check_fn(v: &mut CheckMatchVisitor,
                 cx: &MatchCheckCtxt,
                 kind: &visit::fn_kind,
                 decl: &fn_decl,
-                body: P<Block>,
+                body: &Block,
                 sp: Span,
                 id: NodeId,
                 s: ()) {
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 20db51861d6..bd27900e9cc 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -296,7 +296,7 @@ impl ConstEvalVisitor {
 }
 
 impl Visitor<()> for ConstEvalVisitor {
-    fn visit_expr_post(&mut self, e:@Expr, _:()) {
+    fn visit_expr_post(&mut self, e: &Expr, _: ()) {
         self.classify(e);
     }
 }
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index b0ca03181f8..ab19cdf627f 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -753,7 +753,6 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
         //! concern items that are going out of scope).
 
         let tcx = self.tcx();
-        let region_maps = tcx.region_maps;
 
         debug!("pop_scopes(from_expr={}, to_scope={:?}, in_out={})",
                from_expr.repr(tcx), to_scope.loop_id,
@@ -763,7 +762,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
         while id != to_scope.loop_id {
             self.dfcx.apply_kill(id, in_out);
 
-            match region_maps.opt_encl_scope(id) {
+            match tcx.region_maps.opt_encl_scope(id) {
                 Some(i) => { id = i; }
                 None => {
                     tcx.sess.span_bug(
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 2bdbce9b763..307eb57805c 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -174,7 +174,7 @@ impl MarkSymbolVisitor {
 
 impl Visitor<()> for MarkSymbolVisitor {
 
-    fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
+    fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
         match expr.node {
             ast::ExprMethodCall(..) => {
                 self.lookup_and_handle_method(&expr.id, expr.span);
@@ -190,7 +190,7 @@ impl Visitor<()> for MarkSymbolVisitor {
         visit::walk_path(self, path, ());
     }
 
-    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.
     }
@@ -204,7 +204,7 @@ struct TraitMethodSeeder {
 }
 
 impl Visitor<()> for TraitMethodSeeder {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         match item.node {
             ast::item_impl(_, Some(ref _trait_ref), _, ref methods) => {
                 for method in methods.iter() {
@@ -265,7 +265,7 @@ fn find_live(tcx: ty::ctxt,
     symbol_visitor.live_symbols
 }
 
-fn should_warn(item: @ast::item) -> bool {
+fn should_warn(item: &ast::item) -> bool {
     match item.node {
         ast::item_static(..)
         | ast::item_fn(..)
@@ -335,7 +335,7 @@ impl DeadVisitor {
 }
 
 impl Visitor<()> for DeadVisitor {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    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);
@@ -343,7 +343,7 @@ impl Visitor<()> for DeadVisitor {
         visit::walk_item(self, item, ());
     }
 
-    fn visit_foreign_item(&mut self, fi: @ast::foreign_item, _: ()) {
+    fn visit_foreign_item(&mut self, fi: &ast::foreign_item, _: ()) {
         if !self.symbol_is_live(fi.id, None) {
             self.warn_dead_code(fi.id, fi.span, &fi.ident);
         }
@@ -351,7 +351,7 @@ impl Visitor<()> for DeadVisitor {
     }
 
     fn visit_fn(&mut self, fk: &visit::fn_kind,
-                _: &ast::fn_decl, block: ast::P<ast::Block>,
+                _: &ast::fn_decl, block: &ast::Block,
                 span: codemap::Span, id: ast::NodeId, _: ()) {
         // Have to warn method here because methods are not ast::item
         match *fk {
@@ -367,7 +367,7 @@ impl Visitor<()> for DeadVisitor {
     }
 
     // Overwrite so that we don't warn the trait method itself.
-    fn visit_trait_method(&mut self, trait_method :&ast::trait_method, _: ()) {
+    fn visit_trait_method(&mut self, trait_method: &ast::trait_method, _: ()) {
         match *trait_method {
             ast::provided(method) => visit::walk_block(self, method.body, ()),
             ast::required(_) => ()
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index d4c566d4a60..86e590d3326 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -82,7 +82,7 @@ impl EffectCheckVisitor {
 
 impl Visitor<()> for EffectCheckVisitor {
     fn visit_fn(&mut self, fn_kind: &visit::fn_kind, fn_decl: &ast::fn_decl,
-                block: ast::P<ast::Block>, span: Span, node_id: ast::NodeId, _:()) {
+                block: &ast::Block, span: Span, node_id: ast::NodeId, _:()) {
 
         let (is_item_fn, is_unsafe_fn) = match *fn_kind {
             visit::fk_item_fn(_, _, purity, _) =>
@@ -104,7 +104,7 @@ impl Visitor<()> for EffectCheckVisitor {
         self.unsafe_context = old_unsafe_context
     }
 
-    fn visit_block(&mut self, block: ast::P<ast::Block>, _:()) {
+    fn visit_block(&mut self, block: &ast::Block, _:()) {
         let old_unsafe_context = self.unsafe_context;
         let is_unsafe = match block.rules {
             ast::UnsafeBlock(..) => true, ast::DefaultBlock => false
@@ -118,7 +118,7 @@ impl Visitor<()> for EffectCheckVisitor {
         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(callee_id, _, _, _, _, _) => {
                 let base_type = ty::node_id_to_type(self.tcx, callee_id);
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 89cb902cf10..4688818c055 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -39,7 +39,7 @@ struct EntryContext {
 }
 
 impl Visitor<()> for EntryContext {
-    fn visit_item(&mut self, item:@item, _:()) {
+    fn visit_item(&mut self, item: &item, _:()) {
         find_item(item, self);
     }
 }
@@ -70,7 +70,7 @@ pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map)
     configure_main(&mut ctxt);
 }
 
-fn find_item(item: @item, ctxt: &mut EntryContext) {
+fn find_item(item: &item, ctxt: &mut EntryContext) {
     match item.node {
         item_fn(..) => {
             if item.ident.name == special_idents::main.name {
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
index 9d7dc6fdc7e..de951193cda 100644
--- a/src/librustc/middle/freevars.rs
+++ b/src/librustc/middle/freevars.rs
@@ -40,45 +40,44 @@ struct CollectFreevarsVisitor {
 
 impl Visitor<int> for CollectFreevarsVisitor {
 
-    fn visit_item(&mut self, _:@item, _:int) {
+    fn visit_item(&mut self, _: &item, _: int) {
         // ignore_item
     }
 
-    fn visit_expr(&mut self, expr:@ast::Expr, depth:int) {
-
-            match expr.node {
-              ast::ExprFnBlock(..) | ast::ExprProc(..) => {
+    fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
+        match expr.node {
+            ast::ExprFnBlock(..) | ast::ExprProc(..) => {
                 visit::walk_expr(self, expr, depth + 1)
-              }
-              ast::ExprPath(..) | ast::ExprSelf => {
-                  let mut i = 0;
-                  let def_map = self.def_map.borrow();
-                  match def_map.get().find(&expr.id) {
+            }
+            ast::ExprPath(..) | ast::ExprSelf => {
+                let mut i = 0;
+                let def_map = self.def_map.borrow();
+                match def_map.get().find(&expr.id) {
                     None => fail!("path not found"),
                     Some(&df) => {
-                      let mut def = df;
-                      while i < depth {
-                        match def {
-                          ast::DefUpvar(_, inner, _, _) => { def = *inner; }
-                          _ => break
+                        let mut def = df;
+                        while i < depth {
+                            match def {
+                                ast::DefUpvar(_, inner, _, _) => { def = *inner; }
+                                _ => break
+                            }
+                            i += 1;
                         }
-                        i += 1;
-                      }
-                      if i == depth { // Made it to end of loop
-                        let dnum = ast_util::def_id_of_def(def).node;
-                        if !self.seen.contains_key(&dnum) {
-                            self.refs.push(@freevar_entry {
-                                def: def,
-                                span: expr.span,
-                            });
-                            self.seen.insert(dnum, ());
+                        if i == depth { // Made it to end of loop
+                            let dnum = ast_util::def_id_of_def(def).node;
+                            if !self.seen.contains_key(&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, depth)
+        }
     }
 
 
@@ -89,8 +88,7 @@ impl Visitor<int> for CollectFreevarsVisitor {
 // Since we want to be able to collect upvars in some arbitrary piece
 // of the AST, we take a walker function that we invoke with a visitor
 // in order to start the search.
-fn collect_freevars(def_map: resolve::DefMap, blk: ast::P<ast::Block>)
-    -> freevar_info {
+fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block) -> freevar_info {
     let seen = HashMap::new();
     let refs = ~[];
 
@@ -114,8 +112,8 @@ struct AnnotateFreevarsVisitor {
 }
 
 impl Visitor<()> for AnnotateFreevarsVisitor {
-    fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
-                blk:ast::P<ast::Block>, s:Span, nid:ast::NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &ast::fn_decl,
+                blk: &ast::Block, s: Span, nid: ast::NodeId, _: ()) {
         let vars = collect_freevars(self.def_map, blk);
         self.freevars.insert(nid, vars);
         visit::walk_fn(self, fk, fd, blk, s, nid, ());
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 49e57306c12..4b78fef699c 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -58,18 +58,19 @@ pub struct Context {
 
 impl Visitor<()> for Context {
 
-    fn visit_expr(&mut self, ex:@Expr, _:()) {
+    fn visit_expr(&mut self, ex: &Expr, _: ()) {
         check_expr(self, ex);
     }
 
-    fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &fn_decl,
+                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);
     }
 }
@@ -115,7 +116,7 @@ fn check_struct_safe_for_destructor(cx: &mut Context,
     }
 }
 
-fn check_impl_of_trait(cx: &mut Context, it: @item, trait_ref: &trait_ref, self_type: &Ty) {
+fn check_impl_of_trait(cx: &mut Context, it: &item, trait_ref: &trait_ref, self_type: &Ty) {
     let def_map = cx.tcx.def_map.borrow();
     let ast_trait_def = def_map.get()
                                .find(&trait_ref.ref_id)
@@ -158,7 +159,7 @@ fn check_impl_of_trait(cx: &mut Context, it: @item, trait_ref: &trait_ref, self_
     }
 }
 
-fn check_item(cx: &mut Context, item: @item) {
+fn check_item(cx: &mut Context, item: &item) {
     if !attr::contains_name(item.attrs, "unsafe_destructor") {
         match item.node {
             item_impl(_, Some(ref trait_ref), self_type, _) => {
@@ -247,7 +248,7 @@ fn check_fn(
     cx: &mut Context,
     fk: &visit::fn_kind,
     decl: &fn_decl,
-    body: P<Block>,
+    body: &Block,
     sp: Span,
     fn_id: NodeId) {
 
@@ -262,7 +263,7 @@ fn check_fn(
     visit::walk_fn(cx, fk, decl, body, sp, fn_id, ());
 }
 
-pub fn check_expr(cx: &mut Context, e: @Expr) {
+pub fn check_expr(cx: &mut Context, e: &Expr) {
     debug!("kind::check_expr({})", expr_to_str(e, cx.tcx.sess.intr()));
 
     // Handle any kind bounds on type parameters
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 8e86fa4611f..844a27668db 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -109,7 +109,7 @@ struct LanguageItemVisitor<'a> {
 }
 
 impl<'a> Visitor<()> for LanguageItemVisitor<'a> {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         match extract(item.attrs) {
             Some(value) => {
                 let item_index = self.this.item_refs.find_equiv(&value).map(|x| *x);
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 666c7d84a9a..c5fdf3a1351 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -1303,7 +1303,7 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
 }
 
 impl<'a> Visitor<()> for Context<'a> {
-    fn visit_item(&mut self, it: @ast::item, _: ()) {
+    fn visit_item(&mut self, it: &ast::item, _: ()) {
         self.with_lint_attrs(it.attrs, |cx| {
             check_item_ctypes(cx, it);
             check_item_non_camel_case_types(cx, it);
@@ -1318,7 +1318,7 @@ impl<'a> Visitor<()> for Context<'a> {
         })
     }
 
-    fn visit_foreign_item(&mut self, it: @ast::foreign_item, _: ()) {
+    fn visit_foreign_item(&mut self, it: &ast::foreign_item, _: ()) {
         self.with_lint_attrs(it.attrs, |cx| {
             check_attrs_usage(cx, it.attrs);
             visit::walk_foreign_item(cx, it, ());
@@ -1339,7 +1339,7 @@ impl<'a> Visitor<()> for Context<'a> {
         visit::walk_pat(self, p, ());
     }
 
-    fn visit_expr(&mut self, e: @ast::Expr, _: ()) {
+    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
         match e.node {
             ast::ExprUnary(_, ast::UnNeg, expr) => {
                 // propagate negation, if the negation itself isn't negated
@@ -1365,14 +1365,14 @@ impl<'a> Visitor<()> for Context<'a> {
         visit::walk_expr(self, e, ());
     }
 
-    fn visit_stmt(&mut self, s: @ast::Stmt, _: ()) {
+    fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) {
         check_path_statement(self, s);
 
         visit::walk_stmt(self, s, ());
     }
 
     fn visit_fn(&mut self, fk: &visit::fn_kind, decl: &ast::fn_decl,
-                body: ast::P<ast::Block>, span: Span, id: ast::NodeId, _: ()) {
+                body: &ast::Block, span: Span, id: ast::NodeId, _: ()) {
         let recurse = |this: &mut Context| {
             visit::walk_fn(this, fk, decl, body, span, id, ());
         };
@@ -1404,7 +1404,7 @@ impl<'a> Visitor<()> for Context<'a> {
     }
 
     fn visit_struct_def(&mut self,
-                        s: @ast::struct_def,
+                        s: &ast::struct_def,
                         i: ast::Ident,
                         g: &ast::Generics,
                         id: ast::NodeId,
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 2cc61c51dcc..3f82974c8aa 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -164,12 +164,12 @@ fn live_node_kind_to_str(lnk: LiveNodeKind, cx: ty::ctxt) -> ~str {
 struct LivenessVisitor;
 
 impl Visitor<@IrMaps> for LivenessVisitor {
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, e:@IrMaps) {
+    fn visit_fn(&mut self, fk: &fn_kind, fd: &fn_decl, b: &Block, s: Span, n: NodeId, e: @IrMaps) {
         visit_fn(self, fk, fd, b, s, n, e);
     }
-    fn visit_local(&mut self, l:@Local, e:@IrMaps) { visit_local(self, l, e); }
-    fn visit_expr(&mut self, ex:@Expr, e:@IrMaps) { visit_expr(self, ex, e); }
-    fn visit_arm(&mut self, a:&Arm, e:@IrMaps) { visit_arm(self, a, e); }
+    fn visit_local(&mut self, l: &Local, e: @IrMaps) { visit_local(self, l, e); }
+    fn visit_expr(&mut self, ex: &Expr, e: @IrMaps) { visit_expr(self, ex, e); }
+    fn visit_arm(&mut self, a: &Arm, e: @IrMaps) { visit_arm(self, a, e); }
 }
 
 pub fn check_crate(tcx: ty::ctxt,
@@ -364,16 +364,16 @@ impl IrMaps {
 }
 
 impl Visitor<()> for Liveness {
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &fn_kind, fd: &fn_decl, 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);
     }
 }
@@ -381,7 +381,7 @@ impl Visitor<()> for Liveness {
 fn visit_fn(v: &mut LivenessVisitor,
             fk: &visit::fn_kind,
             decl: &fn_decl,
-            body: P<Block>,
+            body: &Block,
             sp: Span,
             id: NodeId,
             this: @IrMaps) {
@@ -443,7 +443,7 @@ fn visit_fn(v: &mut LivenessVisitor,
     lsets.warn_about_unused_args(decl, entry_ln);
 }
 
-fn visit_local(v: &mut LivenessVisitor, local: @Local, this: @IrMaps) {
+fn visit_local(v: &mut LivenessVisitor, local: &Local, this: @IrMaps) {
     let def_map = this.tcx.def_map;
     pat_util::pat_bindings(def_map, local.pat, |bm, p_id, sp, path| {
         debug!("adding local variable {}", p_id);
@@ -490,7 +490,7 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @IrMaps) {
     visit::walk_arm(v, arm, this);
 }
 
-fn visit_expr(v: &mut LivenessVisitor, expr: @Expr, this: @IrMaps) {
+fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
       ExprPath(_) | ExprSelf => {
@@ -1472,7 +1472,7 @@ impl Liveness {
 // _______________________________________________________________________
 // Checking for error conditions
 
-fn check_local(this: &mut Liveness, local: @Local) {
+fn check_local(this: &mut Liveness, local: &Local) {
     match local.init {
       Some(_) => {
         this.warn_about_unused_or_dead_vars_in_pat(local.pat);
@@ -1508,7 +1508,7 @@ fn check_arm(this: &mut Liveness, arm: &Arm) {
     visit::walk_arm(this, arm, ());
 }
 
-fn check_expr(this: &mut Liveness, expr: @Expr) {
+fn check_expr(this: &mut Liveness, expr: &Expr) {
     match expr.node {
       ExprAssign(l, r) => {
         this.check_lvalue(l);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 1d677d790eb..645c2e79a56 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -216,7 +216,7 @@ pub fn deref_kind(tcx: ty::ctxt, t: ty::t) -> deref_kind {
 
 pub fn cat_expr(tcx: ty::ctxt,
                 method_map: typeck::method_map,
-                expr: @ast::Expr)
+                expr: &ast::Expr)
              -> cmt {
     let mcx = &mem_categorization_ctxt {
         tcx: tcx, method_map: method_map
@@ -226,7 +226,7 @@ pub fn cat_expr(tcx: ty::ctxt,
 
 pub fn cat_expr_unadjusted(tcx: ty::ctxt,
                            method_map: typeck::method_map,
-                           expr: @ast::Expr)
+                           expr: &ast::Expr)
                         -> cmt {
     let mcx = &mem_categorization_ctxt {
         tcx: tcx, method_map: method_map
@@ -237,7 +237,7 @@ pub fn cat_expr_unadjusted(tcx: ty::ctxt,
 pub fn cat_expr_autoderefd(
     tcx: ty::ctxt,
     method_map: typeck::method_map,
-    expr: @ast::Expr,
+    expr: &ast::Expr,
     autoderefs: uint) -> cmt
 {
     let mcx = &mem_categorization_ctxt {
@@ -265,12 +265,12 @@ pub trait ast_node {
     fn span(&self) -> Span;
 }
 
-impl ast_node for @ast::Expr {
+impl ast_node for ast::Expr {
     fn id(&self) -> ast::NodeId { self.id }
     fn span(&self) -> Span { self.span }
 }
 
-impl ast_node for @ast::Pat {
+impl ast_node for ast::Pat {
     fn id(&self) -> ast::NodeId { self.id }
     fn span(&self) -> Span { self.span }
 }
@@ -325,15 +325,15 @@ impl MutabilityCategory {
 }
 
 impl mem_categorization_ctxt {
-    pub fn expr_ty(&self, expr: @ast::Expr) -> ty::t {
+    pub fn expr_ty(&self, expr: &ast::Expr) -> ty::t {
         ty::expr_ty(self.tcx, expr)
     }
 
-    pub fn pat_ty(&self, pat: @ast::Pat) -> ty::t {
+    pub fn pat_ty(&self, pat: &ast::Pat) -> ty::t {
         ty::node_id_to_type(self.tcx, pat.id)
     }
 
-    pub fn cat_expr(&self, expr: @ast::Expr) -> cmt {
+    pub fn cat_expr(&self, expr: &ast::Expr) -> cmt {
         let adjustments = self.tcx.adjustments.borrow();
         match adjustments.get().find(&expr.id) {
             None => {
@@ -375,7 +375,7 @@ impl mem_categorization_ctxt {
         }
     }
 
-    pub fn cat_expr_autoderefd(&self, expr: @ast::Expr, autoderefs: uint)
+    pub fn cat_expr_autoderefd(&self, expr: &ast::Expr, autoderefs: uint)
                                -> cmt {
         let mut cmt = self.cat_expr_unadjusted(expr);
         for deref in range(1u, autoderefs + 1) {
@@ -384,7 +384,7 @@ impl mem_categorization_ctxt {
         return cmt;
     }
 
-    pub fn cat_expr_unadjusted(&self, expr: @ast::Expr) -> cmt {
+    pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt {
         debug!("cat_expr: id={} expr={}",
                expr.id, pprust::expr_to_str(expr, self.tcx.sess.intr()));
 
@@ -577,7 +577,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_rvalue_node<N:ast_node>(&self,
-                                       node: N,
+                                       node: &N,
                                        expr_ty: ty::t) -> cmt {
         self.cat_rvalue(node.id(),
                         node.span(),
@@ -614,7 +614,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_field<N:ast_node>(&self,
-                                 node: N,
+                                 node: &N,
                                  base_cmt: cmt,
                                  f_name: ast::Ident,
                                  f_ty: ty::t)
@@ -629,7 +629,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_deref_fn_or_obj<N:ast_node>(&self,
-                                           node: N,
+                                           node: &N,
                                            base_cmt: cmt,
                                            deref_cnt: uint)
                                            -> cmt {
@@ -644,7 +644,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_deref<N:ast_node>(&self,
-                                 node: N,
+                                 node: &N,
                                  base_cmt: cmt,
                                  deref_cnt: uint)
                                  -> cmt {
@@ -662,7 +662,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_deref_common<N:ast_node>(&self,
-                                        node: N,
+                                        node: &N,
                                         base_cmt: cmt,
                                         deref_cnt: uint,
                                         deref_ty: ty::t)
@@ -706,7 +706,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_index<N:ast_node>(&self,
-                                 elt: N,
+                                 elt: &N,
                                  base_cmt: cmt,
                                  derefs: uint)
                                  -> cmt {
@@ -786,7 +786,7 @@ impl mem_categorization_ctxt {
           }
         };
 
-        fn interior<N: ast_node>(elt: N,
+        fn interior<N: ast_node>(elt: &N,
                                  of_cmt: cmt,
                                  vec_ty: ty::t,
                                  mutbl: MutabilityCategory,
@@ -803,7 +803,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_imm_interior<N:ast_node>(&self,
-                                        node: N,
+                                        node: &N,
                                         base_cmt: cmt,
                                         interior_ty: ty::t,
                                         interior: InteriorKind)
@@ -818,7 +818,7 @@ impl mem_categorization_ctxt {
     }
 
     pub fn cat_downcast<N:ast_node>(&self,
-                                    node: N,
+                                    node: &N,
                                     base_cmt: cmt,
                                     downcast_ty: ty::t)
                                     -> cmt {
@@ -833,8 +833,8 @@ impl mem_categorization_ctxt {
 
     pub fn cat_pattern(&self,
                        cmt: cmt,
-                       pat: @ast::Pat,
-                       op: |cmt, @ast::Pat|) {
+                       pat: &ast::Pat,
+                       op: |cmt, &ast::Pat|) {
         // Here, `cmt` is the categorization for the value being
         // matched and pat is the pattern it is being matched against.
         //
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index f4f0c5c8073..007a26b40ce 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -193,14 +193,14 @@ enum UseMode {
 }
 
 impl visit::Visitor<()> for VisitContext {
-    fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl,
-                b:P<Block>, s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &fn_decl,
+                b: &Block, s: Span, n: NodeId, _: ()) {
         compute_modes_for_fn(self, fk, fd, b, s, n);
     }
-    fn visit_expr(&mut self, ex:@Expr, _:()) {
+    fn visit_expr(&mut self, ex: &Expr, _: ()) {
         compute_modes_for_expr(self, ex);
     }
-    fn visit_local(&mut self, l:@Local, _:()) {
+    fn visit_local(&mut self, l: &Local, _: ()) {
         compute_modes_for_local(self, l);
     }
     // FIXME(#10894) should continue recursing
@@ -240,7 +240,7 @@ pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
 // Expressions
 
 fn compute_modes_for_local<'a>(cx: &mut VisitContext,
-                               local: @Local) {
+                               local: &Local) {
     cx.use_pat(local.pat);
     for &init in local.init.iter() {
         cx.use_expr(init, Read);
@@ -250,7 +250,7 @@ fn compute_modes_for_local<'a>(cx: &mut VisitContext,
 fn compute_modes_for_fn(cx: &mut VisitContext,
                         fk: &visit::fn_kind,
                         decl: &fn_decl,
-                        body: P<Block>,
+                        body: &Block,
                         span: Span,
                         id: NodeId) {
     for a in decl.inputs.iter() {
@@ -260,7 +260,7 @@ fn compute_modes_for_fn(cx: &mut VisitContext,
 }
 
 fn compute_modes_for_expr(cx: &mut VisitContext,
-                          expr: @Expr)
+                          expr: &Expr)
 {
     cx.consume_expr(expr);
 }
@@ -272,7 +272,7 @@ impl VisitContext {
         }
     }
 
-    pub fn consume_expr(&mut self, expr: @Expr) {
+    pub fn consume_expr(&mut self, expr: &Expr) {
         /*!
          * Indicates that the value of `expr` will be consumed,
          * meaning either copied or moved depending on its type.
@@ -311,7 +311,7 @@ impl VisitContext {
     }
 
     pub fn use_expr(&mut self,
-                    expr: @Expr,
+                    expr: &Expr,
                     expr_mode: UseMode) {
         /*!
          * Indicates that `expr` is used with a given mode.  This will
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index bc2be163bfa..5e095061b42 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -45,7 +45,7 @@ struct ParentVisitor {
 }
 
 impl Visitor<()> for ParentVisitor {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         self.parents.insert(item.id, self.curparent);
 
         let prev = self.curparent;
@@ -90,13 +90,13 @@ impl Visitor<()> for ParentVisitor {
         self.curparent = prev;
     }
 
-    fn visit_foreign_item(&mut self, a: @ast::foreign_item, _: ()) {
+    fn visit_foreign_item(&mut self, a: &ast::foreign_item, _: ()) {
         self.parents.insert(a.id, self.curparent);
         visit::walk_foreign_item(self, a, ());
     }
 
     fn visit_fn(&mut self, a: &visit::fn_kind, b: &ast::fn_decl,
-                c: ast::P<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.
@@ -106,7 +106,7 @@ impl Visitor<()> for ParentVisitor {
         visit::walk_fn(self, a, b, c, d, id, ());
     }
 
-    fn visit_struct_def(&mut self, s: @ast::struct_def, i: ast::Ident,
+    fn visit_struct_def(&mut self, s: &ast::struct_def, i: ast::Ident,
                         g: &ast::Generics, n: ast::NodeId, _: ()) {
         // Struct constructors are parented to their struct definitions because
         // they essentially are the struct definitions.
@@ -185,7 +185,7 @@ impl<'a> EmbargoVisitor<'a> {
 }
 
 impl<'a> Visitor<()> for EmbargoVisitor<'a> {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         let orig_all_pub = self.prev_exported;
         match item.node {
             // impls/extern blocks do not break the "public chain" because they
@@ -307,7 +307,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
         self.prev_exported = orig_all_pub;
     }
 
-    fn visit_foreign_item(&mut self, a: @ast::foreign_item, _: ()) {
+    fn visit_foreign_item(&mut self, a: &ast::foreign_item, _: ()) {
         if self.prev_exported && a.vis == ast::public {
             self.exported_items.insert(a.id);
         }
@@ -620,7 +620,7 @@ impl<'a> PrivacyVisitor<'a> {
 }
 
 impl<'a> Visitor<()> for PrivacyVisitor<'a> {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         // Do not check privacy inside items with the resolve_unexported
         // attribute. This is used for the test runner.
         if attr::contains_name(item.attrs, "!resolve_unexported") {
@@ -632,7 +632,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
         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(base, ident, _) => {
                 // Method calls are now a special syntactic form,
@@ -778,7 +778,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
         visit::walk_pat(self, pattern, ());
     }
 
-    fn visit_foreign_item(&mut self, fi: @ast::foreign_item, _: ()) {
+    fn visit_foreign_item(&mut self, fi: &ast::foreign_item, _: ()) {
         self.in_foreign = true;
         visit::walk_foreign_item(self, fi, ());
         self.in_foreign = false;
@@ -800,7 +800,7 @@ struct SanePrivacyVisitor {
 }
 
 impl Visitor<()> for SanePrivacyVisitor {
-    fn visit_item(&mut self, item: @ast::item, _: ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         if self.in_fn {
             self.check_all_inherited(item);
         } else {
@@ -816,7 +816,7 @@ impl Visitor<()> for SanePrivacyVisitor {
     }
 
     fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &ast::fn_decl,
-                b: ast::P<ast::Block>, s: Span, n: ast::NodeId, _: ()) {
+                b: &ast::Block, s: Span, n: ast::NodeId, _: ()) {
         // This catches both functions and methods
         let orig_in_fn = util::replace(&mut self.in_fn, true);
         visit::walk_fn(self, fk, fd, b, s, n, ());
@@ -829,7 +829,7 @@ impl SanePrivacyVisitor {
     /// ensures that there are no extraneous qualifiers that don't actually do
     /// anything. In theory these qualifiers wouldn't parse, but that may happen
     /// later on down the road...
-    fn check_sane_privacy(&self, item: @ast::item) {
+    fn check_sane_privacy(&self, item: &ast::item) {
         let tcx = self.tcx;
         let check_inherited = |sp: Span, vis: ast::visibility, note: &str| {
             if vis != ast::inherited {
@@ -941,7 +941,7 @@ impl SanePrivacyVisitor {
 
     /// When inside of something like a function or a method, visibility has no
     /// control over anything so this forbids any mention of any visibility
-    fn check_all_inherited(&self, item: @ast::item) {
+    fn check_all_inherited(&self, item: &ast::item) {
         let tcx = self.tcx;
         let check_inherited = |sp: Span, vis: ast::visibility| {
             if vis != ast::inherited {
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 5e50017b93e..3165527b326 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -44,7 +44,7 @@ fn generics_require_inlining(generics: &ast::Generics) -> bool {
 // Returns true if the given item must be inlined because it may be
 // monomorphized or it was marked with `#[inline]`. This will only return
 // true for functions.
-fn item_might_be_inlined(item: @ast::item) -> bool {
+fn item_might_be_inlined(item: &ast::item) -> bool {
     if attributes_specify_inlining(item.attrs) {
         return true
     }
@@ -105,7 +105,7 @@ struct MarkSymbolVisitor {
 
 impl Visitor<()> for MarkSymbolVisitor {
 
-    fn visit_expr(&mut self, expr:@ast::Expr, _:()) {
+    fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
 
         match expr.node {
             ast::ExprPath(_) => {
@@ -187,7 +187,7 @@ impl Visitor<()> for MarkSymbolVisitor {
         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.
     }
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 3f8f2f35100..05d9ee42afa 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -30,7 +30,7 @@ use std::hashmap::{HashMap, HashSet};
 use syntax::codemap::Span;
 use syntax::{ast, visit};
 use syntax::visit::{Visitor,fn_kind};
-use syntax::ast::{P,Block,item,fn_decl,NodeId,Arm,Pat,Stmt,Expr,Local};
+use syntax::ast::{Block,item,fn_decl,NodeId,Arm,Pat,Stmt,Expr,Local};
 
 /**
 The region maps encode information about region relationships.
@@ -69,7 +69,7 @@ struct RegionResolutionVisitor {
     sess: Session,
 
     // Generated maps:
-    region_maps: @RegionMaps,
+    region_maps: RegionMaps,
 }
 
 
@@ -333,7 +333,7 @@ fn parent_to_expr(visitor: &mut RegionResolutionVisitor,
 }
 
 fn resolve_block(visitor: &mut RegionResolutionVisitor,
-                 blk: ast::P<ast::Block>,
+                 blk: &ast::Block,
                  cx: Context) {
     // Record the parent of this block.
     parent_to_expr(visitor, cx, blk.id, blk.span);
@@ -359,7 +359,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor,
 }
 
 fn resolve_stmt(visitor: &mut RegionResolutionVisitor,
-                stmt: @ast::Stmt,
+                stmt: &ast::Stmt,
                 cx: Context) {
     match stmt.node {
         ast::StmtDecl(..) => {
@@ -376,7 +376,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor,
 }
 
 fn resolve_expr(visitor: &mut RegionResolutionVisitor,
-                expr: @ast::Expr,
+                expr: &ast::Expr,
                 cx: Context) {
     parent_to_expr(visitor, cx, expr.id, expr.span);
 
@@ -417,7 +417,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
 }
 
 fn resolve_local(visitor: &mut RegionResolutionVisitor,
-                 local: @ast::Local,
+                 local: &ast::Local,
                  cx: Context) {
     assert_eq!(cx.var_parent, cx.parent);
     parent_to_expr(visitor, cx, local.id, local.span);
@@ -425,7 +425,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
 }
 
 fn resolve_item(visitor: &mut RegionResolutionVisitor,
-                item: @ast::item,
+                item: &ast::item,
                 cx: Context) {
     // Items create a new outer block scope as far as we're concerned.
     let new_cx = Context {var_parent: None, parent: None, ..cx};
@@ -435,7 +435,7 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor,
 fn resolve_fn(visitor: &mut RegionResolutionVisitor,
               fk: &visit::fn_kind,
               decl: &ast::fn_decl,
-              body: ast::P<ast::Block>,
+              body: &ast::Block,
               sp: Span,
               id: ast::NodeId,
               cx: Context) {
@@ -476,47 +476,46 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
 
 impl Visitor<Context> for RegionResolutionVisitor {
 
-    fn visit_block(&mut self, b:P<Block>, cx:Context) {
+    fn visit_block(&mut self, b: &Block, cx: Context) {
         resolve_block(self, b, cx);
     }
 
-    fn visit_item(&mut self, i:@item, cx:Context) {
+    fn visit_item(&mut self, i: &item, cx: Context) {
         resolve_item(self, i, cx);
     }
 
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, cx:Context) {
+    fn visit_fn(&mut self, fk: &fn_kind, fd: &fn_decl,
+                b: &Block, s: Span, n: NodeId, cx: Context) {
         resolve_fn(self, fk, fd, b, s, n, cx);
     }
-    fn visit_arm(&mut self, a:&Arm, cx:Context) {
+    fn visit_arm(&mut self, a: &Arm, cx: Context) {
         resolve_arm(self, a, cx);
     }
-    fn visit_pat(&mut self, p:&Pat, cx:Context) {
+    fn visit_pat(&mut self, p: &Pat, cx: Context) {
         resolve_pat(self, p, cx);
     }
-    fn visit_stmt(&mut self, s:@Stmt, cx:Context) {
+    fn visit_stmt(&mut self, s: &Stmt, cx: Context) {
         resolve_stmt(self, s, cx);
     }
-    fn visit_expr(&mut self, ex:@Expr, cx:Context) {
+    fn visit_expr(&mut self, ex: &Expr, cx: Context) {
         resolve_expr(self, ex, cx);
     }
-    fn visit_local(&mut self, l:@Local, cx:Context) {
+    fn visit_local(&mut self, l: &Local, cx: Context) {
         resolve_local(self, l, cx);
     }
 }
 
-pub fn resolve_crate(sess: Session, crate: &ast::Crate) -> @RegionMaps {
-    let region_maps = @RegionMaps {
-        scope_map: RefCell::new(HashMap::new()),
-        free_region_map: RefCell::new(HashMap::new()),
-        cleanup_scopes: RefCell::new(HashSet::new()),
-    };
-    let cx = Context {parent: None,
-                      var_parent: None};
+pub fn resolve_crate(sess: Session, crate: &ast::Crate) -> RegionMaps {
     let mut visitor = RegionResolutionVisitor {
         sess: sess,
-        region_maps: region_maps,
+        region_maps: RegionMaps {
+            scope_map: RefCell::new(HashMap::new()),
+            free_region_map: RefCell::new(HashMap::new()),
+            cleanup_scopes: RefCell::new(HashSet::new())
+        }
     };
+    let cx = Context { parent: None, var_parent: None };
     visit::walk_crate(&mut visitor, crate, cx);
-    return region_maps;
+    return visitor.region_maps;
 }
 
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 3dc7bf59453..fb0bdfe963e 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -137,22 +137,22 @@ enum SelfBinding {
 }
 
 impl Visitor<()> for Resolver {
-    fn visit_item(&mut self, item:@item, _:()) {
+    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:P<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);
     }
 }
@@ -898,13 +898,13 @@ struct BuildReducedGraphVisitor<'a> {
 
 impl<'a> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a> {
 
-    fn visit_item(&mut self, item:@item, context:ReducedGraphParent) {
+    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_foreign_item(&mut self, foreign_item: @foreign_item,
-                          context:ReducedGraphParent) {
+    fn visit_foreign_item(&mut self, foreign_item: &foreign_item,
+                          context: ReducedGraphParent) {
         self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
                                                            context,
                                                            |r, c| {
@@ -913,11 +913,11 @@ impl<'a> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a> {
         })
     }
 
-    fn visit_view_item(&mut self, view_item:&view_item, context:ReducedGraphParent) {
+    fn visit_view_item(&mut self, view_item: &view_item, context: ReducedGraphParent) {
         self.resolver.build_reduced_graph_for_view_item(view_item, context);
     }
 
-    fn visit_block(&mut self, block:P<Block>, context:ReducedGraphParent) {
+    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);
     }
@@ -927,7 +927,7 @@ impl<'a> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a> {
 struct UnusedImportCheckVisitor<'a> { resolver: &'a Resolver }
 
 impl<'a> Visitor<()> for UnusedImportCheckVisitor<'a> {
-    fn visit_view_item(&mut self, vi:&view_item, _:()) {
+    fn visit_view_item(&mut self, vi: &view_item, _: ()) {
         self.resolver.check_for_item_unused_imports(vi);
         visit::walk_view_item(self, vi, ());
     }
@@ -1141,7 +1141,7 @@ impl Resolver {
 
     /// Constructs the reduced graph for one item.
     fn build_reduced_graph_for_item(&mut self,
-                                        item: @item,
+                                        item: &item,
                                         parent: ReducedGraphParent)
                                             -> ReducedGraphParent
     {
@@ -1550,7 +1550,7 @@ impl Resolver {
 
     /// Constructs the reduced graph for one foreign item.
     fn build_reduced_graph_for_foreign_item(&mut self,
-                                            foreign_item: @foreign_item,
+                                            foreign_item: &foreign_item,
                                             parent: ReducedGraphParent,
                                             f: |&mut Resolver,
                                                 ReducedGraphParent|) {
@@ -3633,7 +3633,7 @@ impl Resolver {
         visit::walk_crate(self, crate, ());
     }
 
-    fn resolve_item(&mut self, item: @item) {
+    fn resolve_item(&mut self, item: &item) {
         debug!("(resolving item) resolving {}",
                self.session.str_of(item.ident));
 
@@ -4170,7 +4170,7 @@ impl Resolver {
         visit::walk_mod(self, module_, ());
     }
 
-    fn resolve_local(&mut self, local: @Local) {
+    fn resolve_local(&mut self, local: &Local) {
         // Resolve the type.
         self.resolve_type(local.ty);
 
@@ -4268,7 +4268,7 @@ impl Resolver {
         value_ribs.get().pop();
     }
 
-    fn resolve_block(&mut self, block: P<Block>) {
+    fn resolve_block(&mut self, block: &Block) {
         debug!("(resolving block) entering block");
         {
             let mut value_ribs = self.value_ribs.borrow_mut();
@@ -5152,7 +5152,7 @@ impl Resolver {
         }
     }
 
-    fn resolve_expr(&mut self, expr: @Expr) {
+    fn resolve_expr(&mut self, expr: &Expr) {
         // First, record candidate traits for this expression if it could
         // result in the invocation of a method call.
 
@@ -5324,8 +5324,7 @@ impl Resolver {
         }
     }
 
-    fn record_candidate_traits_for_expr_if_necessary(&mut self,
-                                                         expr: @Expr) {
+    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
         match expr.node {
             ExprField(_, ident, _) => {
                 // FIXME(#6890): Even though you can't treat a method like a
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index d62a58460d0..929661122ab 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -57,7 +57,7 @@ pub fn crate(sess: session::Session, crate: &ast::Crate)
 
 impl<'a> Visitor<&'a ScopeChain<'a>> for LifetimeContext {
     fn visit_item(&mut self,
-                  item: @ast::item,
+                  item: &ast::item,
                   _: &'a ScopeChain<'a>) {
         let scope = match item.node {
             ast::item_fn(..) | // fn lifetimes get added in visit_fn below
@@ -84,7 +84,7 @@ impl<'a> Visitor<&'a ScopeChain<'a>> for LifetimeContext {
     fn visit_fn(&mut self,
                 fk: &visit::fn_kind,
                 fd: &ast::fn_decl,
-                b: ast::P<ast::Block>,
+                b: &ast::Block,
                 s: Span,
                 n: ast::NodeId,
                 scope: &'a ScopeChain<'a>) {
@@ -132,7 +132,7 @@ impl<'a> Visitor<&'a ScopeChain<'a>> for LifetimeContext {
     }
 
     fn visit_block(&mut self,
-                   b: ast::P<ast::Block>,
+                   b: &ast::Block,
                    scope: &'a ScopeChain<'a>) {
         let scope1 = BlockScope(b.id, scope);
         debug!("pushing block scope {}", b.id);
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index f1897a08901..53abbba2e89 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2203,7 +2203,7 @@ pub struct TransItemVisitor {
 }
 
 impl Visitor<()> for TransItemVisitor {
-    fn visit_item(&mut self, i: @ast::item, _:()) {
+    fn visit_item(&mut self, i: &ast::item, _:()) {
         trans_item(self.ccx, i);
     }
 }
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 098b3c1ae73..2deff5bc5ee 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -331,7 +331,7 @@ pub fn create_captured_var_metadata(bcx: @Block,
         None => {
             cx.sess.span_bug(span, "debuginfo::create_captured_var_metadata() - NodeId not found");
         }
-        Some(ast_map::node_local(ident)) => ident,
+        Some(ast_map::node_local(ident, _)) => ident,
         Some(ast_map::node_arg(@ast::Pat { node: ast::PatIdent(_, ref path, _), .. })) => {
             ast_util::path_to_ident(path)
         }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index c8299b29289..5ab48a143ab 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -276,7 +276,7 @@ struct ctxt_ {
 
     named_region_map: @RefCell<resolve_lifetime::NamedRegionMap>,
 
-    region_maps: @middle::region::RegionMaps,
+    region_maps: middle::region::RegionMaps,
 
     // Stores the types for various nodes in the AST.  Note that this table
     // is not guaranteed to be populated until after typeck.  See
@@ -966,7 +966,7 @@ pub fn mk_ctxt(s: session::Session,
                named_region_map: @RefCell<resolve_lifetime::NamedRegionMap>,
                amap: ast_map::map,
                freevars: freevars::freevar_map,
-               region_maps: @middle::region::RegionMaps,
+               region_maps: middle::region::RegionMaps,
                lang_items: middle::lang_items::LanguageItems)
             -> ctxt {
     @ctxt_ {
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index a7f83a41da6..1cb2a32741e 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -26,8 +26,8 @@ use syntax::codemap::Span;
 use syntax::print::pprust;
 
 pub fn check_match(fcx: @FnCtxt,
-                   expr: @ast::Expr,
-                   discrim: @ast::Expr,
+                   expr: &ast::Expr,
+                   discrim: &ast::Expr,
                    arms: &[ast::Arm]) {
     let tcx = fcx.ccx.tcx;
 
@@ -106,7 +106,7 @@ pub struct pat_ctxt {
     map: PatIdMap,
 }
 
-pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::Pat, path: &ast::Path,
+pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
                          subpats: &Option<~[@ast::Pat]>, expected: ty::t) {
 
     // Typecheck the path.
@@ -418,7 +418,7 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt,
 
 // Pattern checking is top-down rather than bottom-up so that bindings get
 // their types immediately.
-pub fn check_pat(pcx: &pat_ctxt, pat: @ast::Pat, expected: ty::t) {
+pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
@@ -662,7 +662,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::Pat, expected: ty::t) {
 // Helper function to check @, ~ and & patterns
 pub fn check_pointer_pat(pcx: &pat_ctxt,
                          pointer_kind: PointerKind,
-                         inner: @ast::Pat,
+                         inner: &ast::Pat,
                          pat_id: ast::NodeId,
                          span: Span,
                          expected: ty::t) {
diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs
index 64b08d481e1..cf316ed284d 100644
--- a/src/librustc/middle/typeck/check/demand.rs
+++ b/src/librustc/middle/typeck/check/demand.rs
@@ -56,7 +56,7 @@ pub fn eqtype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
 }
 
 // Checks that the type `actual` can be coerced to `expected`.
-pub fn coerce(fcx: @FnCtxt, sp: Span, expected: ty::t, expr: @ast::Expr) {
+pub fn coerce(fcx: @FnCtxt, sp: Span, expected: ty::t, expr: &ast::Expr) {
     let expr_ty = fcx.expr_ty(expr);
     match fcx.mk_assignty(expr, expr_ty, expected) {
       result::Ok(()) => { /* ok */ }
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 90edeea9d84..3bd1f45a071 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -122,8 +122,8 @@ pub fn lookup(
         fcx: @FnCtxt,
 
         // In a call `a.b::<X, Y, ...>(...)`:
-        expr: @ast::Expr,                   // The expression `a.b(...)`.
-        self_expr: @ast::Expr,              // The expression `a`.
+        expr: &ast::Expr,                   // The expression `a.b(...)`.
+        self_expr: &ast::Expr,              // The expression `a`.
         callee_id: NodeId,                  /* Where to store `a.b`'s type,
                                              * also the scope of the call */
         m_name: ast::Name,                  // The name `b`.
@@ -170,8 +170,8 @@ pub fn lookup(
 
 pub struct LookupContext<'a> {
     fcx: @FnCtxt,
-    expr: @ast::Expr,
-    self_expr: @ast::Expr,
+    expr: &'a ast::Expr,
+    self_expr: &'a ast::Expr,
     callee_id: NodeId,
     m_name: ast::Name,
     supplied_tps: &'a [ty::t],
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 51a34ab2735..4ebf41b3d4d 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -305,7 +305,7 @@ impl ExprTyProvider for FnCtxt {
 struct CheckItemTypesVisitor { ccx: @CrateCtxt }
 
 impl Visitor<()> for CheckItemTypesVisitor {
-    fn visit_item(&mut self, i:@ast::item, _:()) {
+    fn visit_item(&mut self, i: &ast::item, _: ()) {
         check_item(self.ccx, i);
         visit::walk_item(self, i, ());
     }
@@ -318,7 +318,7 @@ pub fn check_item_types(ccx: @CrateCtxt, crate: &ast::Crate) {
 
 pub fn check_bare_fn(ccx: @CrateCtxt,
                      decl: &ast::fn_decl,
-                     body: ast::P<ast::Block>,
+                     body: &ast::Block,
                      id: ast::NodeId,
                      self_info: Option<SelfInfo>,
                      fty: ty::t,
@@ -365,7 +365,7 @@ impl GatherLocalsVisitor {
 
 impl Visitor<()> for GatherLocalsVisitor {
         // 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::ty_infer => None,
               _ => Some(self.fcx.to_ty(local.ty))
@@ -382,7 +382,7 @@ impl Visitor<()> for GatherLocalsVisitor {
 
     }
         // 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 path, _)
                   if pat_util::pat_is_binding(self.fcx.ccx.tcx.def_map, p) => {
@@ -401,17 +401,17 @@ impl Visitor<()> for GatherLocalsVisitor {
 
     }
 
-    fn visit_block(&mut self, b:ast::P<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.
         self.fcx.with_region_lb(b.id, || visit::walk_block(self, b, ()));
     }
 
-        // Don't descend into fns and items
-    fn visit_fn(&mut self, _:&visit::fn_kind, _:&ast::fn_decl,
-                _:ast::P<ast::Block>, _:Span, _:ast::NodeId, _:()) { }
-    fn visit_item(&mut self, _:@ast::item, _:()) { }
+    // Don't descend into fns and items
+    fn visit_fn(&mut self, _: &visit::fn_kind, _: &ast::fn_decl,
+                _: &ast::Block, _: Span, _: ast::NodeId, _: ()) { }
+    fn visit_item(&mut self, _: &ast::item, _: ()) { }
 
 }
 
@@ -421,7 +421,7 @@ pub fn check_fn(ccx: @CrateCtxt,
                 fn_sig: &ty::FnSig,
                 decl: &ast::fn_decl,
                 id: ast::NodeId,
-                body: ast::P<ast::Block>,
+                body: &ast::Block,
                 fn_kind: FnKind,
                 inherited: @Inherited) -> @FnCtxt
 {
@@ -507,7 +507,7 @@ pub fn check_fn(ccx: @CrateCtxt,
 
     fn gather_locals(fcx: @FnCtxt,
                      decl: &ast::fn_decl,
-                     body: ast::P<ast::Block>,
+                     body: &ast::Block,
                      arg_tys: &[ty::t],
                      opt_self_info: Option<SelfInfo>) {
         let tcx = fcx.ccx.tcx;
@@ -576,7 +576,7 @@ pub fn check_struct(ccx: @CrateCtxt, id: ast::NodeId, span: Span) {
     }
 }
 
-pub fn check_item(ccx: @CrateCtxt, it: @ast::item) {
+pub fn check_item(ccx: @CrateCtxt, it: &ast::item) {
     debug!("check_item(it.id={}, it.ident={})",
            it.id,
            ty::item_path_str(ccx.tcx, local_def(it.id)));
@@ -682,7 +682,7 @@ pub fn check_item(ccx: @CrateCtxt, it: @ast::item) {
 fn check_method_body(ccx: @CrateCtxt,
                      item_generics: &ty::Generics,
                      self_bound: Option<@ty::TraitRef>,
-                     method: @ast::method) {
+                     method: &ast::method) {
     /*!
      * Type checks a method body.
      *
@@ -1166,7 +1166,7 @@ impl FnCtxt {
         ast_ty_to_ty(self, &self.infcx(), ast_t)
     }
 
-    pub fn pat_to_str(&self, pat: @ast::Pat) -> ~str {
+    pub fn pat_to_str(&self, pat: &ast::Pat) -> ~str {
         pat.repr(self.tcx())
     }
 
@@ -1236,13 +1236,13 @@ impl FnCtxt {
     }
 
     pub fn mk_assignty(&self,
-                       expr: @ast::Expr,
+                       expr: &ast::Expr,
                        sub: ty::t,
                        sup: ty::t)
                        -> Result<(), ty::type_err> {
         match infer::mk_coercety(self.infcx(),
                                  false,
-                                 infer::ExprAssignable(expr),
+                                 infer::ExprAssignable(expr.span),
                                  sub,
                                  sup) {
             Ok(None) => result::Ok(()),
@@ -1378,7 +1378,7 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) {
 }
 
 // AST fragment checking
-pub fn check_lit(fcx: @FnCtxt, lit: @ast::lit) -> ty::t {
+pub fn check_lit(fcx: @FnCtxt, lit: &ast::lit) -> ty::t {
     let tcx = fcx.ccx.tcx;
 
     match lit.node {
@@ -1407,8 +1407,8 @@ pub fn check_lit(fcx: @FnCtxt, lit: @ast::lit) -> ty::t {
 }
 
 pub fn valid_range_bounds(ccx: @CrateCtxt,
-                          from: @ast::Expr,
-                          to: @ast::Expr)
+                          from: &ast::Expr,
+                          to: &ast::Expr)
                        -> Option<bool> {
     match const_eval::compare_lit_exprs(ccx.tcx, from, to) {
         Some(val) => Some(val <= 0),
@@ -1417,7 +1417,7 @@ pub fn valid_range_bounds(ccx: @CrateCtxt,
 }
 
 pub fn check_expr_has_type(
-    fcx: @FnCtxt, expr: @ast::Expr,
+    fcx: @FnCtxt, expr: &ast::Expr,
     expected: ty::t) {
     check_expr_with_unifier(fcx, expr, Some(expected), || {
         demand::suptype(fcx, expr.span, expected, fcx.expr_ty(expr));
@@ -1425,7 +1425,7 @@ pub fn check_expr_has_type(
 }
 
 pub fn check_expr_coercable_to_type(
-    fcx: @FnCtxt, expr: @ast::Expr,
+    fcx: @FnCtxt, expr: &ast::Expr,
     expected: ty::t) {
     check_expr_with_unifier(fcx, expr, Some(expected), || {
         demand::coerce(fcx, expr.span, expected, expr)
@@ -1433,18 +1433,18 @@ pub fn check_expr_coercable_to_type(
 }
 
 pub fn check_expr_with_hint(
-    fcx: @FnCtxt, expr: @ast::Expr,
+    fcx: @FnCtxt, expr: &ast::Expr,
     expected: ty::t) {
     check_expr_with_unifier(fcx, expr, Some(expected), || ())
 }
 
 pub fn check_expr_with_opt_hint(
-    fcx: @FnCtxt, expr: @ast::Expr,
+    fcx: @FnCtxt, expr: &ast::Expr,
     expected: Option<ty::t>)  {
     check_expr_with_unifier(fcx, expr, expected, || ())
 }
 
-pub fn check_expr(fcx: @FnCtxt, expr: @ast::Expr)  {
+pub fn check_expr(fcx: @FnCtxt, expr: &ast::Expr)  {
     check_expr_with_unifier(fcx, expr, None, || ())
 }
 
@@ -1651,7 +1651,7 @@ fn check_type_parameter_positions_in_path(function_context: @FnCtxt,
 /// that there are actually multiple representations for both `ty_err` and
 /// `ty_bot`, so avoid that when err and bot need to be handled differently.
 pub fn check_expr_with_unifier(fcx: @FnCtxt,
-                               expr: @ast::Expr,
+                               expr: &ast::Expr,
                                expected: Option<ty::t>,
                                unifier: ||) {
     debug!(">> typechecking");
@@ -1660,7 +1660,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
         fcx: @FnCtxt,
         sp: Span,
         method_fn_ty: ty::t,
-        callee_expr: @ast::Expr,
+        callee_expr: &ast::Expr,
         args: &[@ast::Expr],
         sugar: ast::CallSugar,
         deref_args: DerefArgs) -> ty::t
@@ -1689,7 +1689,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     fn check_argument_types(fcx: @FnCtxt,
                             sp: Span,
                             fn_inputs: &[ty::t],
-                            callee_expr: @ast::Expr,
+                            callee_expr: &ast::Expr,
                             args: &[@ast::Expr],
                             sugar: ast::CallSugar,
                             deref_args: DerefArgs,
@@ -1842,8 +1842,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
 
     // A generic function for checking assignment expressions
     fn check_assignment(fcx: @FnCtxt,
-                        lhs: @ast::Expr,
-                        rhs: @ast::Expr,
+                        lhs: &ast::Expr,
+                        rhs: &ast::Expr,
                         id: ast::NodeId) {
         check_expr(fcx, lhs);
         let lhs_type = fcx.expr_ty(lhs);
@@ -1853,7 +1853,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     }
 
     fn write_call(fcx: @FnCtxt,
-                  call_expr: @ast::Expr,
+                  call_expr: &ast::Expr,
                   output: ty::t,
                   sugar: ast::CallSugar) {
         let ret_ty = match sugar {
@@ -1875,8 +1875,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     // A generic function for doing all of the checking for call expressions
     fn check_call(fcx: @FnCtxt,
                   callee_id: ast::NodeId,
-                  call_expr: @ast::Expr,
-                  f: @ast::Expr,
+                  call_expr: &ast::Expr,
+                  f: &ast::Expr,
                   args: &[@ast::Expr],
                   sugar: ast::CallSugar) {
         // Index expressions need to be handled separately, to inform them
@@ -1937,8 +1937,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     // Checks a method call.
     fn check_method_call(fcx: @FnCtxt,
                          callee_id: ast::NodeId,
-                         expr: @ast::Expr,
-                         rcvr: @ast::Expr,
+                         expr: &ast::Expr,
+                         rcvr: &ast::Expr,
                          method_name: ast::Ident,
                          args: &[@ast::Expr],
                          tps: &[ast::P<ast::Ty>],
@@ -1997,7 +1997,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     // A generic function for checking the then and else in an if
     // or if-check
     fn check_then_else(fcx: @FnCtxt,
-                       cond_expr: @ast::Expr,
+                       cond_expr: &ast::Expr,
                        then_blk: &ast::Block,
                        opt_else_expr: Option<@ast::Expr>,
                        id: ast::NodeId,
@@ -2037,11 +2037,11 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
 
     fn lookup_op_method(fcx: @FnCtxt,
                         callee_id: ast::NodeId,
-                        op_ex: @ast::Expr,
-                        self_ex: @ast::Expr,
+                        op_ex: &ast::Expr,
+                        self_ex: &ast::Expr,
                         self_t: ty::t,
                         opname: ast::Name,
-                        args: ~[@ast::Expr],
+                        args: &[@ast::Expr],
                         deref_args: DerefArgs,
                         autoderef_receiver: AutoderefReceiverFlag,
                         unbound_method: ||,
@@ -2078,9 +2078,9 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     // could be either a expr_binop or an expr_assign_binop
     fn check_binop(fcx: @FnCtxt,
                    callee_id: ast::NodeId,
-                   expr: @ast::Expr,
+                   expr: &ast::Expr,
                    op: ast::BinOp,
-                   lhs: @ast::Expr,
+                   lhs: &ast::Expr,
                    rhs: @ast::Expr,
                    // Used only in the error case
                    expected_result: Option<ty::t>,
@@ -2166,8 +2166,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
 
     fn check_user_binop(fcx: @FnCtxt,
                         callee_id: ast::NodeId,
-                        ex: @ast::Expr,
-                        lhs_expr: @ast::Expr,
+                        ex: &ast::Expr,
+                        lhs_expr: &ast::Expr,
                         lhs_resolved_t: ty::t,
                         op: ast::BinOp,
                         rhs: @ast::Expr,
@@ -2184,7 +2184,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
                 };
                 return lookup_op_method(fcx, callee_id, ex, lhs_expr, lhs_resolved_t,
                                        token::intern(*name),
-                                       ~[rhs], DoDerefArgs, DontAutoderefReceiver, if_op_unbound,
+                                       &[rhs], DoDerefArgs, DontAutoderefReceiver, if_op_unbound,
                                        expected_result);
             }
             None => ()
@@ -2210,14 +2210,14 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
                        callee_id: ast::NodeId,
                        op_str: &str,
                        mname: &str,
-                       ex: @ast::Expr,
-                       rhs_expr: @ast::Expr,
+                       ex: &ast::Expr,
+                       rhs_expr: &ast::Expr,
                        rhs_t: ty::t,
                        expected_t: Option<ty::t>)
                     -> ty::t {
        lookup_op_method(
             fcx, callee_id, ex, rhs_expr, rhs_t,
-            token::intern(mname), ~[],
+            token::intern(mname), &[],
             DoDerefArgs, DontAutoderefReceiver,
             || {
                 fcx.type_error_message(ex.span, |actual| {
@@ -2248,7 +2248,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
     }
 
     fn check_expr_fn(fcx: @FnCtxt,
-                     expr: @ast::Expr,
+                     expr: &ast::Expr,
                      ast_sigil_opt: Option<ast::Sigil>,
                      decl: &ast::fn_decl,
                      body: ast::P<ast::Block>,
@@ -2354,8 +2354,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
 
     // Check field access expressions
     fn check_field(fcx: @FnCtxt,
-                   expr: @ast::Expr,
-                   base: @ast::Expr,
+                   expr: &ast::Expr,
+                   base: &ast::Expr,
                    field: ast::Name,
                    tys: &[ast::P<ast::Ty>]) {
         let tcx = fcx.ccx.tcx;
@@ -3263,7 +3263,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
                                                     base,
                                                     resolved,
                                                     index_ident.name,
-                                                    ~[idx],
+                                                    &[idx],
                                                     DoDerefArgs,
                                                     AutoderefReceiver,
                                                     error_message,
@@ -3298,13 +3298,13 @@ pub fn require_integral(fcx: @FnCtxt, sp: Span, t: ty::t) {
 
 pub fn check_decl_initializer(fcx: @FnCtxt,
                               nid: ast::NodeId,
-                              init: @ast::Expr)
+                              init: &ast::Expr)
                             {
     let local_ty = fcx.local_ty(init.span, nid);
     check_expr_coercable_to_type(fcx, init, local_ty)
 }
 
-pub fn check_decl_local(fcx: @FnCtxt, local: @ast::Local)  {
+pub fn check_decl_local(fcx: @FnCtxt, local: &ast::Local)  {
     let tcx = fcx.ccx.tcx;
 
     let t = fcx.local_ty(local.span, local.id);
@@ -3332,7 +3332,7 @@ pub fn check_decl_local(fcx: @FnCtxt, local: @ast::Local)  {
     }
 }
 
-pub fn check_stmt(fcx: @FnCtxt, stmt: @ast::Stmt)  {
+pub fn check_stmt(fcx: @FnCtxt, stmt: &ast::Stmt)  {
     let node_id;
     let mut saw_bot = false;
     let mut saw_err = false;
@@ -3465,7 +3465,7 @@ pub fn check_block_with_expected(fcx: @FnCtxt,
 
 pub fn check_const(ccx: @CrateCtxt,
                    sp: Span,
-                   e: @ast::Expr,
+                   e: &ast::Expr,
                    id: ast::NodeId) {
     let rty = ty::node_id_to_type(ccx.tcx, id);
     let fcx = blank_fn_ctxt(ccx, rty, e.id);
@@ -3478,7 +3478,7 @@ pub fn check_const(ccx: @CrateCtxt,
 
 pub fn check_const_with_ty(fcx: @FnCtxt,
                            _: Span,
-                           e: @ast::Expr,
+                           e: &ast::Expr,
                            declty: ty::t) {
     check_expr(fcx, e);
     let cty = fcx.expr_ty(e);
@@ -3907,7 +3907,7 @@ pub fn type_is_c_like_enum(fcx: @FnCtxt, sp: Span, typ: ty::t) -> bool {
 }
 
 pub fn ast_expr_vstore_to_vstore(fcx: @FnCtxt,
-                                 e: @ast::Expr,
+                                 e: &ast::Expr,
                                  v: ast::ExprVstore)
                               -> ty::vstore {
     match v {
@@ -3975,7 +3975,7 @@ pub fn check_bounds_are_used(ccx: @CrateCtxt,
     }
 }
 
-pub fn check_intrinsic_type(ccx: @CrateCtxt, it: @ast::foreign_item) {
+pub fn check_intrinsic_type(ccx: @CrateCtxt, it: &ast::foreign_item) {
     fn param(ccx: @CrateCtxt, n: uint) -> ty::t {
         ty::mk_param(ccx.tcx, n, local_def(0))
     }
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index aed9a406404..fb914779cce 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -128,7 +128,7 @@ impl Rcx {
     }
 
     /// Try to resolve the type for the given node.
-    pub fn resolve_expr_type_adjusted(&mut self, expr: @ast::Expr) -> ty::t {
+    pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> ty::t {
         let ty_unadjusted = self.resolve_node_type(expr.id);
         if ty::type_is_error(ty_unadjusted) || ty::type_is_bot(ty_unadjusted) {
             ty_unadjusted
@@ -143,7 +143,7 @@ impl Rcx {
     }
 }
 
-pub fn regionck_expr(fcx: @FnCtxt, e: @ast::Expr) {
+pub fn regionck_expr(fcx: @FnCtxt, e: &ast::Expr) {
     let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
                          repeating_scope: e.id };
     let rcx = &mut rcx;
@@ -154,7 +154,7 @@ pub fn regionck_expr(fcx: @FnCtxt, e: @ast::Expr) {
     fcx.infcx().resolve_regions();
 }
 
-pub fn regionck_fn(fcx: @FnCtxt, blk: ast::P<ast::Block>) {
+pub fn regionck_fn(fcx: @FnCtxt, blk: &ast::Block) {
     let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
                          repeating_scope: blk.id };
     let rcx = &mut rcx;
@@ -174,24 +174,24 @@ impl Visitor<()> for Rcx {
     // hierarchy, and in particular the relationships between free
     // regions, until regionck, as described in #3238.
 
-    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
+    //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::P<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) {
+fn visit_item(_rcx: &mut Rcx, _item: &ast::item) {
     // Ignore items
 }
 
-fn visit_block(rcx: &mut Rcx, b: ast::P<ast::Block>) {
+fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
     rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id);
     visit::walk_block(rcx, b, ());
 }
@@ -205,13 +205,13 @@ fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
     visit::walk_arm(rcx, arm, ());
 }
 
-fn visit_local(rcx: &mut Rcx, l: @ast::Local) {
+fn visit_local(rcx: &mut Rcx, l: &ast::Local) {
     // see above
     constrain_bindings_in_pat(l.pat, rcx);
     visit::walk_local(rcx, l, ());
 }
 
-fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: &mut Rcx) {
+fn constrain_bindings_in_pat(pat: &ast::Pat, rcx: &mut Rcx) {
     let tcx = rcx.fcx.tcx();
     debug!("regionck::visit_pat(pat={})", pat.repr(tcx));
     pat_util::pat_bindings(tcx.def_map, pat, |_, id, span, _| {
@@ -245,7 +245,7 @@ fn constrain_bindings_in_pat(pat: @ast::Pat, rcx: &mut Rcx) {
     })
 }
 
-fn visit_expr(rcx: &mut Rcx, expr: @ast::Expr) {
+fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
     debug!("regionck::visit_expr(e={}, repeating_scope={:?})",
            expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
 
@@ -479,7 +479,7 @@ fn visit_expr(rcx: &mut Rcx, expr: @ast::Expr) {
 }
 
 fn check_expr_fn_block(rcx: &mut Rcx,
-                       expr: @ast::Expr) {
+                       expr: &ast::Expr) {
     let tcx = rcx.fcx.tcx();
     match expr.node {
         ast::ExprFnBlock(_, ref body) | ast::ExprProc(_, ref body) => {
@@ -522,8 +522,8 @@ fn check_expr_fn_block(rcx: &mut Rcx,
 
 fn constrain_callee(rcx: &mut Rcx,
                     callee_id: ast::NodeId,
-                    call_expr: @ast::Expr,
-                    callee_expr: @ast::Expr)
+                    call_expr: &ast::Expr,
+                    callee_expr: &ast::Expr)
 {
     let call_region = ty::ReScope(call_expr.id);
 
@@ -549,7 +549,7 @@ fn constrain_call(rcx: &mut Rcx,
                   // might be expr_call, expr_method_call, or an overloaded
                   // operator
                   callee_id: ast::NodeId,
-                  call_expr: @ast::Expr,
+                  call_expr: &ast::Expr,
                   receiver: Option<@ast::Expr>,
                   arg_exprs: &[@ast::Expr],
                   implicitly_ref_args: bool)
@@ -618,7 +618,7 @@ fn constrain_call(rcx: &mut Rcx,
 }
 
 fn constrain_derefs(rcx: &mut Rcx,
-                    deref_expr: @ast::Expr,
+                    deref_expr: &ast::Expr,
                     derefs: uint,
                     mut derefd_ty: ty::t)
 {
@@ -662,7 +662,7 @@ pub fn mk_subregion_due_to_derefence(rcx: &mut Rcx,
 
 
 fn constrain_index(rcx: &mut Rcx,
-                   index_expr: @ast::Expr,
+                   index_expr: &ast::Expr,
                    indexed_ty: ty::t)
 {
     /*!
@@ -688,7 +688,7 @@ fn constrain_index(rcx: &mut Rcx,
 
 fn constrain_free_variables(rcx: &mut Rcx,
                             region: ty::Region,
-                            expr: @ast::Expr) {
+                            expr: &ast::Expr) {
     /*!
      * Make sure that all free variables referenced inside the closure
      * outlive the closure itself.
@@ -842,7 +842,7 @@ pub mod guarantor {
     use syntax::codemap::Span;
     use util::ppaux::{ty_to_str};
 
-    pub fn for_addr_of(rcx: &mut Rcx, expr: @ast::Expr, base: @ast::Expr) {
+    pub fn for_addr_of(rcx: &mut Rcx, expr: &ast::Expr, base: &ast::Expr) {
         /*!
          * Computes the guarantor for an expression `&base` and then
          * ensures that the lifetime of the resulting pointer is linked
@@ -855,7 +855,7 @@ pub mod guarantor {
         link(rcx, expr.span, expr.id, guarantor);
     }
 
-    pub fn for_match(rcx: &mut Rcx, discr: @ast::Expr, arms: &[ast::Arm]) {
+    pub fn for_match(rcx: &mut Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
         /*!
          * Computes the guarantors for any ref bindings in a match and
          * then ensures that the lifetime of the resulting pointer is
@@ -873,7 +873,7 @@ pub mod guarantor {
     }
 
     pub fn for_autoref(rcx: &mut Rcx,
-                       expr: @ast::Expr,
+                       expr: &ast::Expr,
                        autoderefs: uint,
                        autoref: &ty::AutoRef) {
         /*!
@@ -913,7 +913,7 @@ pub mod guarantor {
 
         fn maybe_make_subregion(
             rcx: &mut Rcx,
-            expr: @ast::Expr,
+            expr: &ast::Expr,
             sub_region: ty::Region,
             sup_region: Option<ty::Region>)
         {
@@ -925,7 +925,7 @@ pub mod guarantor {
     }
 
     pub fn for_by_ref(rcx: &mut Rcx,
-                      expr: @ast::Expr,
+                      expr: &ast::Expr,
                       callee_scope: ast::NodeId) {
         /*!
          * Computes the guarantor for cases where the `expr` is
@@ -1004,7 +1004,7 @@ pub mod guarantor {
         ty: ty::t
     }
 
-    fn guarantor(rcx: &mut Rcx, expr: @ast::Expr) -> Option<ty::Region> {
+    fn guarantor(rcx: &mut Rcx, expr: &ast::Expr) -> Option<ty::Region> {
         /*!
          *
          * Computes the guarantor of `expr`, or None if `expr` is
@@ -1076,7 +1076,7 @@ pub mod guarantor {
         }
     }
 
-    fn categorize(rcx: &mut Rcx, expr: @ast::Expr) -> ExprCategorization {
+    fn categorize(rcx: &mut Rcx, expr: &ast::Expr) -> ExprCategorization {
         debug!("categorize()");
 
         let mut expr_ct = categorize_unadjusted(rcx, expr);
@@ -1152,7 +1152,7 @@ pub mod guarantor {
     }
 
     fn categorize_unadjusted(rcx: &mut Rcx,
-                             expr: @ast::Expr)
+                             expr: &ast::Expr)
                           -> ExprCategorizationType {
         debug!("categorize_unadjusted()");
 
@@ -1177,7 +1177,7 @@ pub mod guarantor {
 
     fn apply_autoderefs(
         rcx: &mut Rcx,
-        expr: @ast::Expr,
+        expr: &ast::Expr,
         autoderefs: uint,
         ct: ExprCategorizationType)
      -> ExprCategorizationType {
@@ -1255,7 +1255,7 @@ pub mod guarantor {
 
     fn link_ref_bindings_in_pat(
         rcx: &mut Rcx,
-        pat: @ast::Pat,
+        pat: &ast::Pat,
         guarantor: Option<ty::Region>) {
         /*!
          *
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index fcf219323e1..e0e163f5400 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -544,28 +544,26 @@ fn insert_vtables(fcx: @FnCtxt,
     vtable_map.get().insert(callee_id, vtables);
 }
 
-pub fn location_info_for_expr(expr: @ast::Expr) -> LocationInfo {
+pub fn location_info_for_expr(expr: &ast::Expr) -> LocationInfo {
     LocationInfo {
         span: expr.span,
         id: expr.id
     }
 }
-pub fn location_info_for_item(item: @ast::item) -> LocationInfo {
+pub fn location_info_for_item(item: &ast::item) -> LocationInfo {
     LocationInfo {
         span: item.span,
         id: item.id
     }
 }
 
-pub fn early_resolve_expr(ex: @ast::Expr,
-                          fcx: @FnCtxt,
-                          is_early: bool) {
+pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) {
     debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
            ex.id, is_early, expr_to_str(ex, fcx.tcx().sess.intr()));
     let _indent = indenter();
 
     let cx = fcx.ccx;
-    let resolve_object_cast = |src: @ast::Expr, target_ty: ty::t| {
+    let resolve_object_cast = |src: &ast::Expr, target_ty: ty::t| {
       match ty::get(target_ty).sty {
           // Bounds of type's contents are not checked here, but in kind.rs.
           ty::ty_trait(target_def_id, ref target_substs, store,
@@ -753,15 +751,14 @@ pub fn early_resolve_expr(ex: @ast::Expr,
     }
 }
 
-fn resolve_expr(fcx: @FnCtxt,
-                ex: @ast::Expr) {
+fn resolve_expr(fcx: @FnCtxt, ex: &ast::Expr) {
     let mut fcx = fcx;
     early_resolve_expr(ex, fcx, false);
     visit::walk_expr(&mut fcx, ex, ());
 }
 
 pub fn resolve_impl(ccx: @CrateCtxt,
-                    impl_item: @ast::item,
+                    impl_item: &ast::item,
                     impl_generics: &ty::Generics,
                     impl_trait_ref: &ty::TraitRef) {
     let param_env = ty::construct_parameter_environment(
@@ -817,17 +814,16 @@ pub fn resolve_impl(ccx: @CrateCtxt,
 }
 
 impl visit::Visitor<()> for @FnCtxt {
-    fn visit_expr(&mut self, ex:@ast::Expr, _:()) {
+    fn visit_expr(&mut self, ex: &ast::Expr, _: ()) {
         resolve_expr(*self, ex);
     }
-    fn visit_item(&mut self, _:@ast::item, _:()) {
+    fn visit_item(&mut self, _: &ast::item, _: ()) {
         // no-op
     }
 }
 
 // Detect points where a trait-bounded type parameter is
 // instantiated, resolve the impls for the parameters.
-pub fn resolve_in_block(fcx: @FnCtxt, bl: ast::P<ast::Block>) {
-    let mut fcx = fcx;
+pub fn resolve_in_block(mut fcx: @FnCtxt, bl: &ast::Block) {
     visit::walk_block(&mut fcx, bl, ());
 }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index f84220da8e7..ce9f8ba2212 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -242,13 +242,13 @@ struct WbCtxt {
     success: bool,
 }
 
-fn visit_stmt(s: @ast::Stmt, wbcx: &mut WbCtxt) {
+fn visit_stmt(s: &ast::Stmt, wbcx: &mut WbCtxt) {
     if !wbcx.success { return; }
     resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
     visit::walk_stmt(wbcx, s, ());
 }
 
-fn visit_expr(e: @ast::Expr, wbcx: &mut WbCtxt) {
+fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
     if !wbcx.success {
         return;
     }
@@ -296,7 +296,7 @@ fn visit_expr(e: @ast::Expr, wbcx: &mut WbCtxt) {
     visit::walk_expr(wbcx, e, ());
 }
 
-fn visit_block(b: ast::P<ast::Block>, wbcx: &mut WbCtxt) {
+fn visit_block(b: &ast::Block, wbcx: &mut WbCtxt) {
     if !wbcx.success {
         return;
     }
@@ -319,7 +319,7 @@ fn visit_pat(p: &ast::Pat, wbcx: &mut WbCtxt) {
     visit::walk_pat(wbcx, p, ());
 }
 
-fn visit_local(l: @ast::Local, wbcx: &mut WbCtxt) {
+fn visit_local(l: &ast::Local, wbcx: &mut WbCtxt) {
     if !wbcx.success { return; }
     let var_ty = wbcx.fcx.local_ty(l.span, l.id);
     match resolve_type(wbcx.fcx.infcx(), var_ty, resolve_all | force_all) {
@@ -341,22 +341,22 @@ fn visit_local(l: @ast::Local, wbcx: &mut WbCtxt) {
     }
     visit::walk_local(wbcx, l, ());
 }
-fn visit_item(_item: @ast::item, _wbcx: &mut WbCtxt) {
+fn visit_item(_item: &ast::item, _wbcx: &mut WbCtxt) {
     // Ignore items
 }
 
 impl Visitor<()> for WbCtxt {
-    fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(i, self); }
-    fn visit_stmt(&mut self, s:@ast::Stmt, _:()) { visit_stmt(s, self); }
-    fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(ex, self); }
-    fn visit_block(&mut self, b:ast::P<ast::Block>, _:()) { visit_block(b, self); }
-    fn visit_pat(&mut self, p:&ast::Pat, _:()) { visit_pat(p, self); }
-    fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(l, self); }
+    fn visit_item(&mut self, i: &ast::item, _: ()) { visit_item(i, self); }
+    fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) { visit_stmt(s, self); }
+    fn visit_expr(&mut self, ex:&ast::Expr, _: ()) { visit_expr(ex, self); }
+    fn visit_block(&mut self, b: &ast::Block, _: ()) { visit_block(b, self); }
+    fn visit_pat(&mut self, p: &ast::Pat, _: ()) { visit_pat(p, self); }
+    fn visit_local(&mut self, l: &ast::Local, _: ()) { visit_local(l, self); }
     // FIXME(#10894) should continue recursing
-    fn visit_ty(&mut self, _t: &ast::Ty, _:()) {}
+    fn visit_ty(&mut self, _t: &ast::Ty, _: ()) {}
 }
 
-pub fn resolve_type_vars_in_expr(fcx: @FnCtxt, e: @ast::Expr) -> bool {
+pub fn resolve_type_vars_in_expr(fcx: @FnCtxt, e: &ast::Expr) -> bool {
     let mut wbcx = WbCtxt { fcx: fcx, success: true };
     let wbcx = &mut wbcx;
     wbcx.visit_expr(e, ());
@@ -365,7 +365,7 @@ pub fn resolve_type_vars_in_expr(fcx: @FnCtxt, e: @ast::Expr) -> bool {
 
 pub fn resolve_type_vars_in_fn(fcx: @FnCtxt,
                                decl: &ast::fn_decl,
-                               blk: ast::P<ast::Block>,
+                               blk: &ast::Block,
                                self_info: Option<SelfInfo>) -> bool {
     let mut wbcx = WbCtxt { fcx: fcx, success: true };
     let wbcx = &mut wbcx;
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index d18c2419735..39c483241cb 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -158,23 +158,24 @@ pub struct CoherenceChecker {
 struct CoherenceCheckVisitor { cc: CoherenceChecker }
 
 impl visit::Visitor<()> for CoherenceCheckVisitor {
-    fn visit_item(&mut self, item:@item, _:()) {
+    fn visit_item(&mut self, item: &item, _: ()) {
 
-//                debug!("(checking coherence) item '{}'",
-//                       self.cc.crate_context.tcx.sess.str_of(item.ident));
+//      debug!("(checking coherence) item '{}'",
+//             self.cc.crate_context.tcx.sess.str_of(item.ident));
 
-                match item.node {
-                    item_impl(_, ref opt_trait, _, _) => {
-                        let opt_trait : ~[trait_ref] =
-                            opt_trait.iter()
-                                     .map(|x| (*x).clone())
-                                     .collect();
-                        self.cc.check_implementation(item, opt_trait);
+        match item.node {
+            item_impl(_, ref opt_trait, _, _) => {
+                match opt_trait.clone() {
+                    Some(opt_trait) => {
+                        self.cc.check_implementation(item, [opt_trait]);
                     }
-                    _ => {
-                        // Nothing to do.
-                    }
-                };
+                    None => self.cc.check_implementation(item, [])
+                }
+            }
+            _ => {
+                // Nothing to do.
+            }
+        };
 
         visit::walk_item(self, item, ());
     }
@@ -183,50 +184,50 @@ impl visit::Visitor<()> for CoherenceCheckVisitor {
 struct PrivilegedScopeVisitor { cc: CoherenceChecker }
 
 impl visit::Visitor<()> for PrivilegedScopeVisitor {
-    fn visit_item(&mut self, item:@item, _:()) {
+    fn visit_item(&mut self, item: &item, _: ()) {
 
-                match item.node {
-                    item_mod(ref module_) => {
-                        // Then visit the module items.
-                        visit::walk_mod(self, module_, ());
-                    }
-                    item_impl(_, None, ast_ty, _) => {
-                        if !self.cc.ast_type_is_defined_in_local_crate(ast_ty) {
-                            // This is an error.
-                            let session = self.cc.crate_context.tcx.sess;
-                            session.span_err(item.span,
-                                             "cannot associate methods with a type outside the \
-                                              crate the type is defined in; define and implement \
-                                              a trait or new type instead");
-                        }
-                    }
-                    item_impl(_, Some(ref trait_ref), _, _) => {
-                        // `for_ty` is `Type` in `impl Trait for Type`
-                        let for_ty =
-                            ty::node_id_to_type(self.cc.crate_context.tcx,
-                                                item.id);
-                        if !type_is_defined_in_local_crate(for_ty) {
-                            // This implementation is not in scope of its base
-                            // type. This still might be OK if the trait is
-                            // defined in the same crate.
+        match item.node {
+            item_mod(ref module_) => {
+                // Then visit the module items.
+                visit::walk_mod(self, module_, ());
+            }
+            item_impl(_, None, ast_ty, _) => {
+                if !self.cc.ast_type_is_defined_in_local_crate(ast_ty) {
+                    // This is an error.
+                    let session = self.cc.crate_context.tcx.sess;
+                    session.span_err(item.span,
+                                     "cannot associate methods with a type outside the \
+                                     crate the type is defined in; define and implement \
+                                     a trait or new type instead");
+                }
+            }
+            item_impl(_, Some(ref trait_ref), _, _) => {
+                // `for_ty` is `Type` in `impl Trait for Type`
+                let for_ty =
+                    ty::node_id_to_type(self.cc.crate_context.tcx,
+                                        item.id);
+                if !type_is_defined_in_local_crate(for_ty) {
+                    // This implementation is not in scope of its base
+                    // type. This still might be OK if the trait is
+                    // defined in the same crate.
 
-                            let trait_def_id =
-                                self.cc.trait_ref_to_trait_def_id(trait_ref);
+                    let trait_def_id =
+                        self.cc.trait_ref_to_trait_def_id(trait_ref);
 
-                            if trait_def_id.crate != LOCAL_CRATE {
-                                let session = self.cc.crate_context.tcx.sess;
-                                session.span_err(item.span,
-                                        "cannot provide an extension implementation \
-                                        where both trait and type are not defined in this crate");
-                            }
-                        }
-
-                        visit::walk_item(self, item, ());
-                    }
-                    _ => {
-                        visit::walk_item(self, item, ());
+                    if trait_def_id.crate != LOCAL_CRATE {
+                        let session = self.cc.crate_context.tcx.sess;
+                        session.span_err(item.span,
+                                "cannot provide an extension implementation \
+                                where both trait and type are not defined in this crate");
                     }
                 }
+
+                visit::walk_item(self, item, ());
+            }
+            _ => {
+                visit::walk_item(self, item, ());
+            }
+        }
     }
 }
 
@@ -257,7 +258,7 @@ impl CoherenceChecker {
     }
 
     pub fn check_implementation(&self,
-                                item: @item,
+                                item: &item,
                                 associated_traits: &[trait_ref]) {
         let tcx = self.crate_context.tcx;
         let self_type = ty::lookup_item_type(tcx, local_def(item.id));
@@ -592,7 +593,7 @@ impl CoherenceChecker {
     }
 
     // Converts an implementation in the AST to an Impl structure.
-    pub fn create_impl_from_item(&self, item: @item) -> @Impl {
+    pub fn create_impl_from_item(&self, item: &item) -> @Impl {
         let tcx = self.crate_context.tcx;
         match item.node {
             item_impl(_, ref trait_refs, _, ref ast_methods) => {
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 410c94a9a67..9a76a6b10c3 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -61,11 +61,11 @@ struct CollectItemTypesVisitor {
 }
 
 impl visit::Visitor<()> for CollectItemTypesVisitor {
-    fn visit_item(&mut self, i:@ast::item, _:()) {
+    fn visit_item(&mut self, i: &ast::item, _: ()) {
         convert(self.ccx, i);
         visit::walk_item(self, i, ());
     }
-    fn visit_foreign_item(&mut self, i:@ast::foreign_item, _:()) {
+    fn visit_foreign_item(&mut self, i: &ast::foreign_item, _: ()) {
         convert_foreign(self.ccx, i);
         visit::walk_foreign_item(self, i, ());
     }
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 9b71da4f767..a7bd65f862b 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -109,7 +109,8 @@ pub enum TypeOrigin {
     MethodCompatCheck(Span),
 
     // Checking that this expression can be assigned where it needs to be
-    ExprAssignable(@ast::Expr),
+    // FIXME(eddyb) #11161 is the original Expr required?
+    ExprAssignable(Span),
 
     // Relating trait refs when resolving vtables
     RelateTraitRefs(Span),
@@ -845,7 +846,7 @@ impl TypeOrigin {
     pub fn span(&self) -> Span {
         match *self {
             MethodCompatCheck(span) => span,
-            ExprAssignable(expr) => expr.span,
+            ExprAssignable(span) => span,
             Misc(span) => span,
             RelateTraitRefs(span) => span,
             RelateSelfType(span) => span,
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index 8d8524e0f51..6a338c73e9b 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -534,8 +534,7 @@ impl RegionVarBindings {
 
 impl RegionVarBindings {
     fn is_subregion_of(&self, sub: Region, sup: Region) -> bool {
-        let rm = self.tcx.region_maps;
-        rm.is_subregion_of(sub, sup)
+        self.tcx.region_maps.is_subregion_of(sub, sup)
     }
 
     fn lub_concrete_regions(&self, a: Region, b: Region) -> Region {
@@ -571,8 +570,7 @@ impl RegionVarBindings {
             // A "free" region can be interpreted as "some region
             // at least as big as the block fr.scope_id".  So, we can
             // reasonably compare free regions and scopes:
-            let rm = self.tcx.region_maps;
-            match rm.nearest_common_ancestor(fr.scope_id, s_id) {
+            match self.tcx.region_maps.nearest_common_ancestor(fr.scope_id, s_id) {
               // if the free region's scope `fr.scope_id` is bigger than
               // the scope region `s_id`, then the LUB is the free
               // region itself:
@@ -588,8 +586,7 @@ impl RegionVarBindings {
             // The region corresponding to an outer block is a
             // subtype of the region corresponding to an inner
             // block.
-            let rm = self.tcx.region_maps;
-            match rm.nearest_common_ancestor(a_id, b_id) {
+            match self.tcx.region_maps.nearest_common_ancestor(a_id, b_id) {
               Some(r_id) => ReScope(r_id),
               _ => ReStatic
             }
@@ -628,10 +625,9 @@ impl RegionVarBindings {
                   a: &FreeRegion,
                   b: &FreeRegion) -> ty::Region
         {
-            let rm = this.tcx.region_maps;
-            if rm.sub_free_region(*a, *b) {
+            if this.tcx.region_maps.sub_free_region(*a, *b) {
                 ty::ReFree(*b)
-            } else if rm.sub_free_region(*b, *a) {
+            } else if this.tcx.region_maps.sub_free_region(*b, *a) {
                 ty::ReFree(*a)
             } else {
                 ty::ReStatic
@@ -681,8 +677,7 @@ impl RegionVarBindings {
                 // than the scope `s_id`, then we can say that the GLB
                 // is the scope `s_id`.  Otherwise, as we do not know
                 // big the free region is precisely, the GLB is undefined.
-                let rm = self.tcx.region_maps;
-                match rm.nearest_common_ancestor(fr.scope_id, s_id) {
+                match self.tcx.region_maps.nearest_common_ancestor(fr.scope_id, s_id) {
                     Some(r_id) if r_id == fr.scope_id => Ok(s),
                     _ => Err(ty::terr_regions_no_overlap(b, a))
                 }
@@ -729,10 +724,9 @@ impl RegionVarBindings {
                   a: &FreeRegion,
                   b: &FreeRegion) -> cres<ty::Region>
         {
-            let rm = this.tcx.region_maps;
-            if rm.sub_free_region(*a, *b) {
+            if this.tcx.region_maps.sub_free_region(*a, *b) {
                 Ok(ty::ReFree(*a))
-            } else if rm.sub_free_region(*b, *a) {
+            } else if this.tcx.region_maps.sub_free_region(*b, *a) {
                 Ok(ty::ReFree(*b))
             } else {
                 this.intersect_scopes(ty::ReFree(*a), ty::ReFree(*b),
@@ -753,8 +747,7 @@ impl RegionVarBindings {
         // it.  Otherwise fail.
         debug!("intersect_scopes(scope_a={:?}, scope_b={:?}, region_a={:?}, region_b={:?})",
                scope_a, scope_b, region_a, region_b);
-        let rm = self.tcx.region_maps;
-        match rm.nearest_common_ancestor(scope_a, scope_b) {
+        match self.tcx.region_maps.nearest_common_ancestor(scope_a, scope_b) {
             Some(r_id) if scope_a == r_id => Ok(ReScope(scope_b)),
             Some(r_id) if scope_b == r_id => Ok(ReScope(scope_a)),
             _ => Err(ty::terr_regions_no_overlap(region_a, region_b))
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 0f42989855a..7f7bcf202ab 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -327,9 +327,7 @@ impl<'a> TermsContext<'a> {
 }
 
 impl<'a> Visitor<()> for TermsContext<'a> {
-    fn visit_item(&mut self,
-                  item: @ast::item,
-                  (): ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         debug!("add_inferreds for item {}", item.repr(self.tcx));
 
         let inferreds_on_entry = self.num_inferred();
@@ -434,9 +432,7 @@ fn add_constraints_from_crate<'a>(terms_cx: TermsContext<'a>,
 }
 
 impl<'a> Visitor<()> for ConstraintContext<'a> {
-    fn visit_item(&mut self,
-                  item: @ast::item,
-                  (): ()) {
+    fn visit_item(&mut self, item: &ast::item, _: ()) {
         let did = ast_util::local_def(item.id);
         let tcx = self.terms_cx.tcx;
 
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index f3933c5623b..e17a42d3494 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -74,7 +74,7 @@ struct LoopQueryVisitor<'a> {
 }
 
 impl<'a> Visitor<()> for LoopQueryVisitor<'a> {
-    fn visit_expr(&mut self, e: @ast::Expr, _: ()) {
+    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
@@ -87,7 +87,7 @@ impl<'a> Visitor<()> for LoopQueryVisitor<'a> {
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn loop_query(b: ast::P<ast::Block>, p: |&ast::Expr_| -> bool) -> bool {
+pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
     let mut v = LoopQueryVisitor {
         p: p,
         flag: false,
@@ -97,12 +97,12 @@ pub fn loop_query(b: ast::P<ast::Block>, p: |&ast::Expr_| -> bool) -> bool {
 }
 
 struct BlockQueryVisitor<'a> {
-    p: 'a |@ast::Expr| -> bool,
+    p: 'a |&ast::Expr| -> bool,
     flag: bool,
 }
 
 impl<'a> Visitor<()> for BlockQueryVisitor<'a> {
-    fn visit_expr(&mut self, e: @ast::Expr, _:()) {
+    fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
         self.flag |= (self.p)(e);
         visit::walk_expr(self, e, ())
     }
@@ -110,7 +110,7 @@ impl<'a> Visitor<()> for BlockQueryVisitor<'a> {
 
 // Takes a predicate p, returns true iff p is true for any subexpressions
 // of b -- skipping any inner loops (loop, while, loop_body)
-pub fn block_query(b: ast::P<ast::Block>, p: |@ast::Expr| -> bool) -> bool {
+pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
     let mut v = BlockQueryVisitor {
         p: p,
         flag: false,
@@ -119,7 +119,7 @@ pub fn block_query(b: ast::P<ast::Block>, p: |@ast::Expr| -> bool) -> bool {
     return v.flag;
 }
 
-pub fn local_rhs_span(l: @ast::Local, def: Span) -> Span {
+pub fn local_rhs_span(l: &ast::Local, def: Span) -> Span {
     match l.init {
       Some(i) => return i.span,
       _ => return def
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 42d888dbbe8..5762e8570df 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -72,11 +72,11 @@ fn get_ast_and_resolve(cpath: &Path,
         cfg.push(@dummy_spanned(ast::MetaWord(cfg_.to_managed())));
     }
 
-    let mut crate = phase_1_parse_input(sess, cfg.clone(), &input);
-    crate = phase_2_configure_and_expand(sess, cfg, crate);
+    let crate = phase_1_parse_input(sess, cfg.clone(), &input);
+    let (crate, ast_map) = phase_2_configure_and_expand(sess, cfg, crate);
     let driver::driver::CrateAnalysis {
         exported_items, ty_cx, ..
-    } = phase_3_run_analysis_passes(sess, &crate);
+    } = phase_3_run_analysis_passes(sess, &crate, ast_map);
 
     debug!("crate: {:?}", crate);
     return (DocContext { crate: crate, tycx: Some(ty_cx), sess: sess },
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 0fbe585b9bf..a1ef5a62994 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -57,8 +57,8 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
                                       span_diagnostic_handler);
 
     let cfg = driver::build_configuration(sess);
-    let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
-    crate = driver::phase_2_configure_and_expand(sess, cfg, crate);
+    let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
+    let (crate, _) = driver::phase_2_configure_and_expand(sess, cfg, crate);
 
     let ctx = @core::DocContext {
         crate: crate,
diff --git a/src/librustpkg/lib.rs b/src/librustpkg/lib.rs
index 7051c7de058..1f6de700940 100644
--- a/src/librustpkg/lib.rs
+++ b/src/librustpkg/lib.rs
@@ -86,8 +86,8 @@ struct PkgScript<'a> {
     sess: session::Session,
     /// The config for compiling the custom build script
     cfg: ast::CrateConfig,
-    /// The crate for the custom build script
-    crate: Option<ast::Crate>,
+    /// The crate and ast_map for the custom build script
+    crate_and_map: Option<(ast::Crate, syntax::ast_map::map)>,
     /// Directory in which to store build output
     build_dir: Path
 }
@@ -117,7 +117,7 @@ impl<'a> PkgScript<'a> {
                                             @diagnostic::Emitter);
         let cfg = driver::build_configuration(sess);
         let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
-        let crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
+        let crate_and_map = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
         let work_dir = build_pkg_id_in_workspace(id, workspace);
 
         debug!("Returning package script with id {}", id.to_str());
@@ -127,7 +127,7 @@ impl<'a> PkgScript<'a> {
             input: script,
             sess: sess,
             cfg: cfg,
-            crate: Some(crate),
+            crate_and_map: Some(crate_and_map),
             build_dir: work_dir
         }
     }
@@ -137,7 +137,8 @@ impl<'a> PkgScript<'a> {
 
         debug!("Working directory = {}", self.build_dir.display());
         // Collect together any user-defined commands in the package script
-        let crate = util::ready_crate(sess, self.crate.take_unwrap());
+        let (crate, ast_map) = self.crate_and_map.take_unwrap();
+        let crate = util::ready_crate(sess, crate);
         debug!("Building output filenames with script name {}",
                driver::source_name(&driver::file_input(self.input.clone())));
         let exe = self.build_dir.join("pkg" + util::exe_suffix());
@@ -147,6 +148,7 @@ impl<'a> PkgScript<'a> {
                                        &self.build_dir,
                                        sess,
                                        crate,
+                                       ast_map,
                                        Main);
         // Discover the output
         // FIXME (#9639): This needs to handle non-utf8 paths
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 7e43fde7b32..bda84cc8baa 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -18,7 +18,7 @@ use std::io::fs;
 use extra::workcache;
 use rustc::driver::{driver, session};
 use extra::getopts::groups::getopts;
-use syntax::ast_util::*;
+use syntax;
 use syntax::codemap::{DUMMY_SP, Spanned};
 use syntax::ext::base::ExtCtxt;
 use syntax::{ast, attr, codemap, diagnostic, fold, visit};
@@ -283,8 +283,8 @@ pub fn compile_input(context: &BuildContext,
     // Infer dependencies that rustpkg needs to build, by scanning for
     // `extern mod` directives.
     let cfg = driver::build_configuration(sess);
-    let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
-    crate = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
+    let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
+    let (mut crate, ast_map) = driver::phase_2_configure_and_expand(sess, cfg.clone(), crate);
 
     debug!("About to call find_and_install_dependencies...");
 
@@ -323,6 +323,7 @@ pub fn compile_input(context: &BuildContext,
                                           &out_dir,
                                           sess,
                                           crate,
+                                          ast_map,
                                           what);
     // Discover the output
     let discovered_output = if what == Lib  {
@@ -359,6 +360,7 @@ pub fn compile_crate_from_input(input: &Path,
 // Returns None if one of the flags that suppresses compilation output was
 // given
                                 crate: ast::Crate,
+                                ast_map: syntax::ast_map::map,
                                 what: OutputType) -> Option<Path> {
     debug!("Calling build_output_filenames with {}, building library? {:?}",
            out_dir.display(), sess.building_library);
@@ -394,7 +396,7 @@ pub fn compile_crate_from_input(input: &Path,
             debug!("an additional library: {}", lib.display());
         }
     }
-    let analysis = driver::phase_3_run_analysis_passes(sess, &crate);
+    let analysis = driver::phase_3_run_analysis_passes(sess, &crate, ast_map);
     if driver::stop_after_phase_3(sess) { return None; }
     let translation = driver::phase_4_translate_to_llvm(sess, crate,
                                                         &analysis,
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 8a5a1d2426c..a19b930be3e 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -11,21 +11,19 @@
 use abi::AbiSet;
 use ast::*;
 use ast;
-use ast_util::{inlined_item_utils, stmt_id};
 use ast_util;
 use codemap::Span;
-use codemap;
 use diagnostic::SpanHandler;
+use fold::ast_fold;
+use fold;
 use parse::token::get_ident_interner;
 use parse::token::ident_interner;
 use parse::token::special_idents;
 use print::pprust;
-use visit::{Visitor, fn_kind};
-use visit;
+use util::small_vector::SmallVector;
 
 use std::cell::RefCell;
 use std::hashmap::HashMap;
-use std::vec;
 
 #[deriving(Clone, Eq)]
 pub enum path_elt {
@@ -165,7 +163,10 @@ pub enum ast_node {
     node_expr(@Expr),
     node_stmt(@Stmt),
     node_arg(@Pat),
-    node_local(Ident),
+    // HACK(eddyb) should always be a pattern, but `self` is not, and thus it
+    // is identified only by an ident and no span is available. In all other
+    // cases, node_span will return the proper span (required by borrowck).
+    node_local(Ident, Option<@Pat>),
     node_block(P<Block>),
 
     /// node_struct_ctor represents a tuple struct.
@@ -195,164 +196,75 @@ impl ast_node {
 
 pub type map = @RefCell<HashMap<NodeId, ast_node>>;
 
-pub struct Ctx {
+pub trait FoldOps {
+    fn new_id(&self, id: ast::NodeId) -> ast::NodeId {
+        id
+    }
+    fn new_span(&self, span: Span) -> Span {
+        span
+    }
+}
+
+pub struct Ctx<F> {
     map: map,
-    path: RefCell<path>,
+    path: path,
     diag: @SpanHandler,
+    fold_ops: F
 }
 
-impl Ctx {
-    fn extend(&self, elt: path_elt) -> @path {
-        @vec::append(self.path.get(), [elt])
-    }
-
-    fn map_method(&mut self,
-                  impl_did: DefId,
-                  impl_path: @path,
-                  m: @method,
-                  is_provided: bool) {
-        let entry = if is_provided {
-            node_trait_method(@provided(m), impl_did, impl_path)
-        } else {
-            node_method(m, impl_did, impl_path)
-        };
-
+impl<F> Ctx<F> {
+    fn insert(&self, id: ast::NodeId, node: ast_node) {
         let mut map = self.map.borrow_mut();
-        map.get().insert(m.id, entry);
-        map.get().insert(m.self_id, node_local(special_idents::self_));
+        map.get().insert(id, node);
     }
 
-    fn map_struct_def(&mut self,
-                      struct_def: @ast::struct_def,
-                      parent_node: ast_node,
-                      ident: ast::Ident) {
-        let p = self.extend(path_name(ident));
-
-        // If this is a tuple-like struct, register the constructor.
-        match struct_def.ctor_id {
-            None => {}
-            Some(ctor_id) => {
-                match parent_node {
-                    node_item(item, _) => {
-                        let mut map = self.map.borrow_mut();
-                        map.get().insert(ctor_id,
-                                         node_struct_ctor(struct_def,
-                                                          item,
-                                                          p));
-                    }
-                    _ => fail!("struct def parent wasn't an item")
-                }
-            }
-        }
-    }
-
-    fn map_expr(&mut self, ex: @Expr) {
-        {
-            let mut map = self.map.borrow_mut();
-            map.get().insert(ex.id, node_expr(ex));
-        }
-
-        // Expressions which are or might be calls:
-        {
-            let r = ex.get_callee_id();
-            for callee_id in r.iter() {
-                let mut map = self.map.borrow_mut();
-                map.get().insert(*callee_id, node_callee_scope(ex));
-            }
-        }
-
-        visit::walk_expr(self, ex, ());
-    }
-
-    fn map_fn(&mut self,
-              fk: &visit::fn_kind,
-              decl: &fn_decl,
-              body: P<Block>,
-              sp: codemap::Span,
-              id: NodeId) {
-        for a in decl.inputs.iter() {
-            let mut map = self.map.borrow_mut();
-            map.get().insert(a.id, node_arg(a.pat));
-        }
-        match *fk {
-            visit::fk_method(name, _, _) => {
-                let mut path = self.path.borrow_mut();
-                path.get().push(path_name(name))
-            }
-            _ => {}
-        }
-        visit::walk_fn(self, fk, decl, body, sp, id, ());
-        match *fk {
-            visit::fk_method(..) => {
-                let mut path = self.path.borrow_mut();
-                path.get().pop();
-            }
-            _ => {}
-        }
-    }
-
-    fn map_stmt(&mut self, stmt: @Stmt) {
-        {
-            let mut map = self.map.borrow_mut();
-            map.get().insert(stmt_id(stmt), node_stmt(stmt));
-        }
-        visit::walk_stmt(self, stmt, ());
-    }
-
-    fn map_block(&mut self, b: P<Block>) {
-        {
-            let mut map = self.map.borrow_mut();
-            map.get().insert(b.id, node_block(b));
-        }
-
-        visit::walk_block(self, b, ());
-    }
-
-    fn map_pat(&mut self, pat: &Pat) {
-        match pat.node {
-            PatIdent(_, ref path, _) => {
-                // Note: this is at least *potentially* a pattern...
-                let mut map = self.map.borrow_mut();
-                map.get().insert(pat.id,
-                                 node_local(ast_util::path_to_ident(path)));
-            }
-            _ => ()
-        }
-
-        visit::walk_pat(self, pat, ());
+    fn map_self(&self, m: @method) {
+        self.insert(m.self_id, node_local(special_idents::self_, None));
     }
 }
 
-impl Visitor<()> for Ctx {
-    fn visit_item(&mut self, i: @item, _: ()) {
+impl<F: FoldOps> ast_fold for Ctx<F> {
+    fn new_id(&mut self, id: ast::NodeId) -> ast::NodeId {
+        self.fold_ops.new_id(id)
+    }
+
+    fn new_span(&mut self, span: Span) -> Span {
+        self.fold_ops.new_span(span)
+    }
+
+    fn fold_item(&mut self, i: @item) -> SmallVector<@item> {
         // clone is FIXME #2543
-        let item_path = @self.path.get();
-        {
-            let mut map = self.map.borrow_mut();
-            map.get().insert(i.id, node_item(i, item_path));
-        }
-        match i.node {
-            item_impl(_, ref maybe_trait, ty, ref ms) => {
+        let item_path = @self.path.clone();
+        self.path.push(match i.node {
+            item_impl(_, ref maybe_trait, ty, _) => {
                 // Right now the ident on impls is __extensions__ which isn't
                 // very pretty when debugging, so attempt to select a better
                 // name to use.
-                let elt = impl_pretty_name(maybe_trait, ty);
+                impl_pretty_name(maybe_trait, ty)
+            }
+            item_mod(_) | item_foreign_mod(_) => path_mod(i.ident),
+            _ => path_name(i.ident)
+        });
 
+        let i = fold::noop_fold_item(i, self).expect_one("expected one item");
+        self.insert(i.id, node_item(i, item_path));
+
+        match i.node {
+            item_impl(_, _, _, ref ms) => {
+                // clone is FIXME #2543
+                let p = @self.path.clone();
                 let impl_did = ast_util::local_def(i.id);
-                for m in ms.iter() {
-                    let extended = { self.extend(elt) };
-                    self.map_method(impl_did, extended, *m, false)
+                for &m in ms.iter() {
+                    self.insert(m.id, node_method(m, impl_did, p));
+                    self.map_self(m);
                 }
 
-                let mut path = self.path.borrow_mut();
-                path.get().push(elt);
             }
             item_enum(ref enum_definition, _) => {
+                // clone is FIXME #2543
+                let p = @self.path.clone();
                 for &v in enum_definition.variants.iter() {
-                    let elt = path_name(i.ident);
-                    let mut map = self.map.borrow_mut();
-                    map.get().insert(v.node.id,
-                                     node_variant(v, i, self.extend(elt)));
+                    self.insert(v.node.id, node_variant(v, i, p));
                 }
             }
             item_foreign_mod(ref nm) => {
@@ -364,41 +276,38 @@ impl Visitor<()> for Ctx {
                         inherited => i.vis
                     };
 
-                    let mut map = self.map.borrow_mut();
-                    map.get().insert(nitem.id,
-                                     node_foreign_item(*nitem,
-                                                       nm.abis,
-                                                       visibility,
-                                                       // FIXME (#2543)
-                                                        // Anonymous extern
-                                                        // mods go in the
-                                                        // parent scope.
-                                                        @self.path.get()
-                                                       ));
+                    self.insert(nitem.id,
+                                // Anonymous extern mods go in the parent scope.
+                                node_foreign_item(*nitem, nm.abis, visibility, item_path));
                 }
             }
             item_struct(struct_def, _) => {
-                self.map_struct_def(struct_def,
-                                    node_item(i, item_path),
-                                    i.ident)
+                // If this is a tuple-like struct, register the constructor.
+                match struct_def.ctor_id {
+                    None => {}
+                    Some(ctor_id) => {
+                        // clone is FIXME #2543
+                        let p = @self.path.clone();
+                        self.insert(ctor_id, node_struct_ctor(struct_def, i, p));
+                    }
+                }
             }
             item_trait(_, ref traits, ref methods) => {
-                for p in traits.iter() {
-                    let mut map = self.map.borrow_mut();
-                    map.get().insert(p.ref_id, node_item(i, item_path));
+                for t in traits.iter() {
+                    self.insert(t.ref_id, node_item(i, item_path));
                 }
+
+                // clone is FIXME #2543
+                let p = @self.path.clone();
                 for tm in methods.iter() {
-                    let ext = { self.extend(path_name(i.ident)) };
                     let d_id = ast_util::local_def(i.id);
                     match *tm {
                         required(ref m) => {
-                            let entry =
-                                node_trait_method(@(*tm).clone(), d_id, ext);
-                            let mut map = self.map.borrow_mut();
-                            map.get().insert(m.id, entry);
+                            self.insert(m.id, node_trait_method(@(*tm).clone(), d_id, p));
                         }
                         provided(m) => {
-                            self.map_method(d_id, ext, m, true);
+                            self.insert(m.id, node_trait_method(@provided(m), d_id, p));
+                            self.map_self(m);
                         }
                     }
                 }
@@ -406,100 +315,123 @@ impl Visitor<()> for Ctx {
             _ => {}
         }
 
-        match i.node {
-            item_mod(_) | item_foreign_mod(_) => {
-                let mut path = self.path.borrow_mut();
-                path.get().push(path_mod(i.ident));
+        self.path.pop();
+
+        SmallVector::one(i)
+    }
+
+    fn fold_pat(&mut self, pat: @Pat) -> @Pat {
+        let pat = fold::noop_fold_pat(pat, self);
+        match pat.node {
+            PatIdent(_, ref path, _) => {
+                // Note: this is at least *potentially* a pattern...
+                self.insert(pat.id, node_local(ast_util::path_to_ident(path), Some(pat)));
             }
-            item_impl(..) => {} // this was guessed above.
-            _ => {
-                let mut path = self.path.borrow_mut();
-                path.get().push(path_name(i.ident))
+            _ => {}
+        }
+
+        pat
+    }
+
+    fn fold_expr(&mut self, expr: @Expr) -> @Expr {
+        let expr = fold::noop_fold_expr(expr, self);
+
+        self.insert(expr.id, node_expr(expr));
+
+        // Expressions which are or might be calls:
+        {
+            let r = expr.get_callee_id();
+            for callee_id in r.iter() {
+                self.insert(*callee_id, node_callee_scope(expr));
             }
         }
-        visit::walk_item(self, i, ());
 
-        let mut path = self.path.borrow_mut();
-        path.get().pop();
+        expr
     }
 
-    fn visit_pat(&mut self, pat: &Pat, _: ()) {
-        self.map_pat(pat);
-        visit::walk_pat(self, pat, ())
+    fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<@Stmt> {
+        let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
+        self.insert(ast_util::stmt_id(stmt), node_stmt(stmt));
+        SmallVector::one(stmt)
     }
 
-    fn visit_expr(&mut self, expr: @Expr, _: ()) {
-        self.map_expr(expr)
+    fn fold_method(&mut self, m: @method) -> @method {
+        self.path.push(path_name(m.ident));
+        let m = fold::noop_fold_method(m, self);
+        self.path.pop();
+        m
     }
 
-    fn visit_stmt(&mut self, stmt: @Stmt, _: ()) {
-        self.map_stmt(stmt)
+    fn fold_fn_decl(&mut self, decl: &fn_decl) -> P<fn_decl> {
+        let decl = fold::noop_fold_fn_decl(decl, self);
+        for a in decl.inputs.iter() {
+            self.insert(a.id, node_arg(a.pat));
+        }
+        decl
     }
 
-    fn visit_fn(&mut self,
-                function_kind: &fn_kind,
-                function_declaration: &fn_decl,
-                block: P<Block>,
-                span: Span,
-                node_id: NodeId,
-                _: ()) {
-        self.map_fn(function_kind, function_declaration, block, span, node_id)
-    }
-
-    fn visit_block(&mut self, block: P<Block>, _: ()) {
-        self.map_block(block)
-    }
-
-    fn visit_ty(&mut self, typ: &Ty, _: ()) {
-        visit::walk_ty(self, typ, ())
+    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
+        let block = fold::noop_fold_block(block, self);
+        self.insert(block.id, node_block(block));
+        block
     }
 }
 
-pub fn map_crate(diag: @SpanHandler, c: &Crate) -> map {
+pub fn map_crate<F: 'static + FoldOps>(diag: @SpanHandler, c: Crate,
+                                       fold_ops: F) -> (Crate, map) {
     let mut cx = Ctx {
         map: @RefCell::new(HashMap::new()),
-        path: RefCell::new(~[]),
+        path: ~[],
         diag: diag,
+        fold_ops: fold_ops
     };
-    visit::walk_crate(&mut cx, c, ());
-    cx.map
+    (cx.fold_crate(c), cx.map)
 }
 
 // Used for items loaded from external crate that are being inlined into this
 // crate.  The `path` should be the path to the item but should not include
 // the item itself.
-pub fn map_decoded_item(diag: @SpanHandler,
-                        map: map,
-                        path: path,
-                        ii: &inlined_item) {
+pub fn map_decoded_item<F: 'static + FoldOps>(diag: @SpanHandler,
+                                              map: map,
+                                              path: path,
+                                              fold_ops: F,
+                                              fold_ii: |&mut Ctx<F>| -> inlined_item)
+                                              -> inlined_item {
     // I believe it is ok for the local IDs of inlined items from other crates
     // to overlap with the local ids from this crate, so just generate the ids
     // starting from 0.
     let mut cx = Ctx {
         map: map,
-        path: RefCell::new(path.clone()),
+        path: path.clone(),
         diag: diag,
+        fold_ops: fold_ops
     };
 
+    let ii = fold_ii(&mut cx);
+
     // Methods get added to the AST map when their impl is visited.  Since we
     // don't decode and instantiate the impl, but just the method, we have to
     // add it to the table now. Likewise with foreign items.
-    match *ii {
+    match ii {
         ii_item(..) => {} // fallthrough
         ii_foreign(i) => {
-            let mut map = cx.map.borrow_mut();
-            map.get().insert(i.id, node_foreign_item(i,
-                                                     AbiSet::Intrinsic(),
-                                                     i.vis,    // Wrong but OK
-                                                     @path));
+            cx.insert(i.id, node_foreign_item(i,
+                                              AbiSet::Intrinsic(),
+                                              i.vis,    // Wrong but OK
+                                              @path));
         }
         ii_method(impl_did, is_provided, m) => {
-            cx.map_method(impl_did, @path, m, is_provided);
+            let entry = if is_provided {
+                node_trait_method(@provided(m), impl_did, @path)
+            } else {
+                node_method(m, impl_did, @path)
+            };
+            cx.insert(m.id, entry);
+            cx.map_self(m);
         }
     }
 
-    // visit the item / method contents and add those to the map:
-    ii.accept((), &mut cx);
+    ii
 }
 
 pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
@@ -554,7 +486,7 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
       Some(&node_arg(pat)) => {
         format!("arg {} (id={})", pprust::pat_to_str(pat, itr), id)
       }
-      Some(&node_local(ident)) => {
+      Some(&node_local(ident, _)) => {
         format!("local (id={}, name={})", id, itr.get(ident.name))
       }
       Some(&node_block(block)) => {
@@ -589,7 +521,10 @@ pub fn node_span(items: map,
         Some(&node_expr(expr)) => expr.span,
         Some(&node_stmt(stmt)) => stmt.span,
         Some(&node_arg(pat)) => pat.span,
-        Some(&node_local(_)) => fail!("node_span: cannot get span from node_local"),
+        Some(&node_local(_, pat)) => match pat {
+            Some(pat) => pat.span,
+            None => fail!("node_span: cannot get span from node_local (likely `self`)")
+        },
         Some(&node_block(block)) => block.span,
         Some(&node_struct_ctor(_, item, _)) => item.span,
         Some(&node_callee_scope(expr)) => expr.span,
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index f99fed517b1..973d7f5aa9e 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -292,38 +292,6 @@ 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, V:Visitor<E>>(&self, e: E, v: &mut V);
-}
-
-impl inlined_item_utils for inlined_item {
-    fn ident(&self) -> Ident {
-        match *self {
-            ii_item(i) => i.ident,
-            ii_foreign(i) => i.ident,
-            ii_method(_, _, m) => m.ident,
-        }
-    }
-
-    fn id(&self) -> ast::NodeId {
-        match *self {
-            ii_item(i) => i.id,
-            ii_foreign(i) => i.id,
-            ii_method(_, _, m) => m.id,
-        }
-    }
-
-    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::walk_method_helper(v, m, e),
-        }
-    }
-}
-
 /* True if d is either a def_self, or a chain of def_upvars
  referring to a def_self */
 pub fn is_self(d: ast::Def) -> bool {
@@ -443,12 +411,12 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
         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.operation.visit_id(foreign_item.id);
         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
@@ -472,17 +440,17 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
         self.visited_outermost = false
     }
 
-    fn visit_local(&mut self, local: @Local, env: ()) {
+    fn visit_local(&mut self, local: &Local, env: ()) {
         self.operation.visit_id(local.id);
         visit::walk_local(self, local, env)
     }
 
-    fn visit_block(&mut self, block: P<Block>, env: ()) {
+    fn visit_block(&mut self, block: &Block, env: ()) {
         self.operation.visit_id(block.id);
         visit::walk_block(self, block, env)
     }
 
-    fn visit_stmt(&mut self, statement: @Stmt, env: ()) {
+    fn visit_stmt(&mut self, statement: &Stmt, env: ()) {
         self.operation.visit_id(ast_util::stmt_id(statement));
         visit::walk_stmt(self, statement, env)
     }
@@ -493,7 +461,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
     }
 
 
-    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() {
@@ -521,7 +489,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
     fn visit_fn(&mut self,
                 function_kind: &visit::fn_kind,
                 function_declaration: &fn_decl,
-                block: P<Block>,
+                block: &Block,
                 span: Span,
                 node_id: NodeId,
                 env: ()) {
@@ -572,7 +540,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
     }
 
     fn visit_struct_def(&mut self,
-                        struct_def: @struct_def,
+                        struct_def: &struct_def,
                         ident: ast::Ident,
                         generics: &ast::Generics,
                         id: NodeId,
@@ -598,7 +566,12 @@ pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &inlined_item,
         pass_through_items: true,
         visited_outermost: false,
     };
-    item.accept((), &mut id_visitor);
+
+    match *item {
+        ii_item(i) => id_visitor.visit_item(i, ()),
+        ii_foreign(i) => id_visitor.visit_foreign_item(i, ()),
+        ii_method(_, _, m) => visit::walk_method_helper(&mut id_visitor, m, ()),
+    }
 }
 
 struct IdRangeComputingVisitor {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index aa7c26805c3..29dd20d2bcc 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1128,7 +1128,7 @@ mod test {
 
     impl Visitor<()> for NewPathExprFinderContext {
 
-        fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
+        fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
             match *expr {
                 ast::Expr{id:_,span:_,node:ast::ExprPath(ref p)} => {
                     self.path_accumulator.push(p.clone());
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 47130a8e355..8fab2df7a5d 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -84,32 +84,7 @@ pub trait ast_fold {
     }
 
     fn fold_foreign_item(&mut self, ni: @foreign_item) -> @foreign_item {
-        let fold_attribute = |x| fold_attribute_(x, self);
-
-        @ast::foreign_item {
-            ident: self.fold_ident(ni.ident),
-            attrs: ni.attrs.map(|x| fold_attribute(*x)),
-            node:
-                match ni.node {
-                    foreign_item_fn(ref fdec, ref generics) => {
-                        foreign_item_fn(
-                            P(fn_decl {
-                                inputs: fdec.inputs.map(|a| fold_arg_(a,
-                                                                      self)),
-                                output: self.fold_ty(fdec.output),
-                                cf: fdec.cf,
-                                variadic: fdec.variadic
-                            }),
-                            fold_generics(generics, self))
-                    }
-                    foreign_item_static(t, m) => {
-                        foreign_item_static(self.fold_ty(t), m)
-                    }
-                },
-            id: self.new_id(ni.id),
-            span: self.new_span(ni.span),
-            vis: ni.vis,
-        }
+        noop_fold_foreign_item(ni, self)
     }
 
     fn fold_item(&mut self, i: @item) -> SmallVector<@item> {
@@ -134,24 +109,16 @@ pub trait ast_fold {
         noop_fold_item_underscore(i, self)
     }
 
+    fn fold_fn_decl(&mut self, d: &fn_decl) -> P<fn_decl> {
+        noop_fold_fn_decl(d, self)
+    }
+
     fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
         noop_fold_type_method(m, self)
     }
 
     fn fold_method(&mut self, m: @method) -> @method {
-        @ast::method {
-            ident: self.fold_ident(m.ident),
-            attrs: m.attrs.map(|a| fold_attribute_(*a, self)),
-            generics: fold_generics(&m.generics, self),
-            explicit_self: self.fold_explicit_self(&m.explicit_self),
-            purity: m.purity,
-            decl: fold_fn_decl(m.decl, self),
-            body: self.fold_block(m.body),
-            id: self.new_id(m.id),
-            span: self.new_span(m.span),
-            self_id: self.new_id(m.self_id),
-            vis: m.vis,
-        }
+        noop_fold_method(m, self)
     }
 
     fn fold_block(&mut self, b: P<Block>) -> P<Block> {
@@ -171,48 +138,7 @@ pub trait ast_fold {
     }
 
     fn fold_pat(&mut self, p: @Pat) -> @Pat {
-        let node = match p.node {
-            PatWild => PatWild,
-            PatWildMulti => PatWildMulti,
-            PatIdent(binding_mode, ref pth, ref sub) => {
-                PatIdent(binding_mode,
-                         self.fold_path(pth),
-                         sub.map(|x| self.fold_pat(x)))
-            }
-            PatLit(e) => PatLit(self.fold_expr(e)),
-            PatEnum(ref pth, ref pats) => {
-                PatEnum(self.fold_path(pth),
-                        pats.as_ref().map(|pats| pats.map(|x| self.fold_pat(*x))))
-            }
-            PatStruct(ref pth, ref fields, etc) => {
-                let pth_ = self.fold_path(pth);
-                let fs = fields.map(|f| {
-                    ast::FieldPat {
-                        ident: f.ident,
-                        pat: self.fold_pat(f.pat)
-                    }
-                });
-                PatStruct(pth_, fs, etc)
-            }
-            PatTup(ref elts) => PatTup(elts.map(|x| self.fold_pat(*x))),
-            PatBox(inner) => PatBox(self.fold_pat(inner)),
-            PatUniq(inner) => PatUniq(self.fold_pat(inner)),
-            PatRegion(inner) => PatRegion(self.fold_pat(inner)),
-            PatRange(e1, e2) => {
-                PatRange(self.fold_expr(e1), self.fold_expr(e2))
-            },
-            PatVec(ref before, ref slice, ref after) => {
-                PatVec(before.map(|x| self.fold_pat(*x)),
-                       slice.map(|x| self.fold_pat(x)),
-                       after.map(|x| self.fold_pat(*x)))
-            }
-        };
-
-        @Pat {
-            id: self.new_id(p.id),
-            span: self.new_span(p.span),
-            node: node,
-        }
+        noop_fold_pat(p, self)
     }
 
     fn fold_decl(&mut self, d: @Decl) -> SmallVector<@Decl> {
@@ -252,7 +178,7 @@ pub trait ast_fold {
                     region: fold_opt_lifetime(&f.region, self),
                     onceness: f.onceness,
                     bounds: fold_opt_bounds(&f.bounds, self),
-                    decl: fold_fn_decl(f.decl, self),
+                    decl: self.fold_fn_decl(f.decl),
                     lifetimes: f.lifetimes.map(|l| fold_lifetime(l, self)),
                 })
             }
@@ -261,7 +187,7 @@ pub trait ast_fold {
                     lifetimes: f.lifetimes.map(|l| fold_lifetime(l, self)),
                     purity: f.purity,
                     abis: f.abis,
-                    decl: fold_fn_decl(f.decl, self)
+                    decl: self.fold_fn_decl(f.decl)
                 })
             }
             ty_tup(ref tys) => ty_tup(tys.map(|&ty| self.fold_ty(ty))),
@@ -410,7 +336,7 @@ pub trait ast_fold {
 /* some little folds that probably aren't useful to have in ast_fold itself*/
 
 //used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
-fn fold_meta_item_<T:ast_fold>(mi: @MetaItem, fld: &mut T) -> @MetaItem {
+fn fold_meta_item_<T: ast_fold>(mi: @MetaItem, fld: &mut T) -> @MetaItem {
     @Spanned {
         node:
             match mi.node {
@@ -428,7 +354,7 @@ fn fold_meta_item_<T:ast_fold>(mi: @MetaItem, fld: &mut T) -> @MetaItem {
 }
 
 //used in noop_fold_item and noop_fold_crate
-fn fold_attribute_<T:ast_fold>(at: Attribute, fld: &mut T) -> Attribute {
+fn fold_attribute_<T: ast_fold>(at: Attribute, fld: &mut T) -> Attribute {
     Spanned {
         span: fld.new_span(at.span),
         node: ast::Attribute_ {
@@ -440,7 +366,7 @@ fn fold_attribute_<T:ast_fold>(at: Attribute, fld: &mut T) -> Attribute {
 }
 
 //used in noop_fold_foreign_item and noop_fold_fn_decl
-fn fold_arg_<T:ast_fold>(a: &arg, fld: &mut T) -> arg {
+fn fold_arg_<T: ast_fold>(a: &arg, fld: &mut T) -> arg {
     ast::arg {
         ty: fld.fold_ty(a.ty),
         pat: fld.fold_pat(a.pat),
@@ -450,7 +376,7 @@ fn fold_arg_<T:ast_fold>(a: &arg, fld: &mut T) -> arg {
 
 // build a new vector of tts by appling the ast_fold's fold_ident to
 // all of the identifiers in the token trees.
-pub fn fold_tts<T:ast_fold>(tts: &[token_tree], fld: &mut T) -> ~[token_tree] {
+pub fn fold_tts<T: ast_fold>(tts: &[token_tree], fld: &mut T) -> ~[token_tree] {
     tts.map(|tt| {
         match *tt {
             tt_tok(span, ref tok) =>
@@ -468,7 +394,7 @@ pub fn fold_tts<T:ast_fold>(tts: &[token_tree], fld: &mut T) -> ~[token_tree] {
 }
 
 // apply ident folder if it's an ident, otherwise leave it alone
-fn maybe_fold_ident<T:ast_fold>(t: &token::Token, fld: &mut T) -> token::Token {
+fn maybe_fold_ident<T: ast_fold>(t: &token::Token, fld: &mut T) -> token::Token {
     match *t {
         token::IDENT(id, followed_by_colons) => {
             token::IDENT(fld.fold_ident(id), followed_by_colons)
@@ -477,8 +403,8 @@ fn maybe_fold_ident<T:ast_fold>(t: &token::Token, fld: &mut T) -> token::Token {
     }
 }
 
-pub fn fold_fn_decl<T:ast_fold>(decl: &ast::fn_decl, fld: &mut T)
-                                -> P<fn_decl> {
+pub fn noop_fold_fn_decl<T: ast_fold>(decl: &fn_decl, fld: &mut T)
+                                      -> P<fn_decl> {
     P(fn_decl {
         inputs: decl.inputs.map(|x| fold_arg_(x, fld)), // bad copy
         output: fld.fold_ty(decl.output),
@@ -487,15 +413,15 @@ pub fn fold_fn_decl<T:ast_fold>(decl: &ast::fn_decl, fld: &mut T)
     })
 }
 
-fn fold_ty_param_bound<T:ast_fold>(tpb: &TyParamBound, fld: &mut T)
-                                   -> TyParamBound {
+fn fold_ty_param_bound<T: ast_fold>(tpb: &TyParamBound, fld: &mut T)
+                                    -> TyParamBound {
     match *tpb {
         TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)),
         RegionTyParamBound => RegionTyParamBound
     }
 }
 
-pub fn fold_ty_param<T:ast_fold>(tp: &TyParam, fld: &mut T) -> TyParam {
+pub fn fold_ty_param<T: ast_fold>(tp: &TyParam, fld: &mut T) -> TyParam {
     TyParam {
         ident: tp.ident,
         id: fld.new_id(tp.id),
@@ -503,12 +429,12 @@ pub fn fold_ty_param<T:ast_fold>(tp: &TyParam, fld: &mut T) -> TyParam {
     }
 }
 
-pub fn fold_ty_params<T:ast_fold>(tps: &OptVec<TyParam>, fld: &mut T)
-                                  -> OptVec<TyParam> {
+pub fn fold_ty_params<T: ast_fold>(tps: &OptVec<TyParam>, fld: &mut T)
+                                   -> OptVec<TyParam> {
     tps.map(|tp| fold_ty_param(tp, fld))
 }
 
-pub fn fold_lifetime<T:ast_fold>(l: &Lifetime, fld: &mut T) -> Lifetime {
+pub fn fold_lifetime<T: ast_fold>(l: &Lifetime, fld: &mut T) -> Lifetime {
     Lifetime {
         id: fld.new_id(l.id),
         span: fld.new_span(l.span),
@@ -516,37 +442,36 @@ pub fn fold_lifetime<T:ast_fold>(l: &Lifetime, fld: &mut T) -> Lifetime {
     }
 }
 
-pub fn fold_lifetimes<T:ast_fold>(lts: &OptVec<Lifetime>, fld: &mut T)
-                                  -> OptVec<Lifetime> {
+pub fn fold_lifetimes<T: ast_fold>(lts: &OptVec<Lifetime>, fld: &mut T)
+                                   -> OptVec<Lifetime> {
     lts.map(|l| fold_lifetime(l, fld))
 }
 
-pub fn fold_opt_lifetime<T:ast_fold>(o_lt: &Option<Lifetime>, fld: &mut T)
-                                     -> Option<Lifetime> {
+pub fn fold_opt_lifetime<T: ast_fold>(o_lt: &Option<Lifetime>, fld: &mut T)
+                                      -> Option<Lifetime> {
     o_lt.as_ref().map(|lt| fold_lifetime(lt, fld))
 }
 
-pub fn fold_generics<T:ast_fold>(generics: &Generics, fld: &mut T) -> Generics {
+pub fn fold_generics<T: ast_fold>(generics: &Generics, fld: &mut T) -> Generics {
     Generics {ty_params: fold_ty_params(&generics.ty_params, fld),
               lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
 }
 
-fn fold_struct_def<T:ast_fold>(struct_def: @ast::struct_def, fld: &mut T)
-                               -> @ast::struct_def {
+fn fold_struct_def<T: ast_fold>(struct_def: @struct_def, fld: &mut T) -> @struct_def {
     @ast::struct_def {
         fields: struct_def.fields.map(|f| fold_struct_field(f, fld)),
         ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)),
     }
 }
 
-fn fold_trait_ref<T:ast_fold>(p: &trait_ref, fld: &mut T) -> trait_ref {
+fn fold_trait_ref<T: ast_fold>(p: &trait_ref, fld: &mut T) -> trait_ref {
     ast::trait_ref {
         path: fld.fold_path(&p.path),
         ref_id: fld.new_id(p.ref_id),
     }
 }
 
-fn fold_struct_field<T:ast_fold>(f: &struct_field, fld: &mut T) -> struct_field {
+fn fold_struct_field<T: ast_fold>(f: &struct_field, fld: &mut T) -> struct_field {
     Spanned {
         node: ast::struct_field_ {
             kind: f.node.kind,
@@ -558,7 +483,7 @@ fn fold_struct_field<T:ast_fold>(f: &struct_field, fld: &mut T) -> struct_field
     }
 }
 
-fn fold_field_<T:ast_fold>(field: Field, folder: &mut T) -> Field {
+fn fold_field_<T: ast_fold>(field: Field, folder: &mut T) -> Field {
     ast::Field {
         ident: respan(field.ident.span, folder.fold_ident(field.ident.node)),
         expr: folder.fold_expr(field.expr),
@@ -566,15 +491,15 @@ fn fold_field_<T:ast_fold>(field: Field, folder: &mut T) -> Field {
     }
 }
 
-fn fold_mt<T:ast_fold>(mt: &mt, folder: &mut T) -> mt {
+fn fold_mt<T: ast_fold>(mt: &mt, folder: &mut T) -> mt {
     mt {
         ty: folder.fold_ty(mt.ty),
         mutbl: mt.mutbl,
     }
 }
 
-fn fold_opt_bounds<T:ast_fold>(b: &Option<OptVec<TyParamBound>>, folder: &mut T)
-                               -> Option<OptVec<TyParamBound>> {
+fn fold_opt_bounds<T: ast_fold>(b: &Option<OptVec<TyParamBound>>, folder: &mut T)
+                                -> Option<OptVec<TyParamBound>> {
     b.as_ref().map(|bounds| {
         bounds.map(|bound| {
             fold_ty_param_bound(bound, folder)
@@ -582,15 +507,14 @@ fn fold_opt_bounds<T:ast_fold>(b: &Option<OptVec<TyParamBound>>, folder: &mut T)
     })
 }
 
-fn fold_variant_arg_<T:ast_fold>(va: &variant_arg, folder: &mut T)
-                                 -> variant_arg {
+fn fold_variant_arg_<T: ast_fold>(va: &variant_arg, folder: &mut T) -> variant_arg {
     ast::variant_arg {
         ty: folder.fold_ty(va.ty),
         id: folder.new_id(va.id)
     }
 }
 
-pub fn noop_fold_block<T:ast_fold>(b: P<Block>, folder: &mut T) -> P<Block> {
+pub fn noop_fold_block<T: ast_fold>(b: P<Block>, folder: &mut T) -> P<Block> {
     let view_items = b.view_items.map(|x| folder.fold_view_item(x));
     let stmts = b.stmts.iter().flat_map(|s| folder.fold_stmt(*s).move_iter()).collect();
     P(Block {
@@ -603,14 +527,14 @@ pub fn noop_fold_block<T:ast_fold>(b: P<Block>, folder: &mut T) -> P<Block> {
     })
 }
 
-pub fn noop_fold_item_underscore<T:ast_fold>(i: &item_, folder: &mut T) -> item_ {
+pub fn noop_fold_item_underscore<T: ast_fold>(i: &item_, folder: &mut T) -> item_ {
     match *i {
         item_static(t, m, e) => {
             item_static(folder.fold_ty(t), m, folder.fold_expr(e))
         }
         item_fn(decl, purity, abi, ref generics, body) => {
             item_fn(
-                fold_fn_decl(decl, folder),
+                folder.fold_fn_decl(decl),
                 purity,
                 abi,
                 fold_generics(generics, folder),
@@ -660,13 +584,12 @@ pub fn noop_fold_item_underscore<T:ast_fold>(i: &item_, folder: &mut T) -> item_
     }
 }
 
-pub fn noop_fold_type_method<T:ast_fold>(m: &TypeMethod, fld: &mut T)
-                                         -> TypeMethod {
+pub fn noop_fold_type_method<T: ast_fold>(m: &TypeMethod, fld: &mut T) -> TypeMethod {
     TypeMethod {
         ident: fld.fold_ident(m.ident),
         attrs: m.attrs.map(|a| fold_attribute_(*a, fld)),
         purity: m.purity,
-        decl: fold_fn_decl(m.decl, fld),
+        decl: fld.fold_fn_decl(m.decl),
         generics: fold_generics(&m.generics, fld),
         explicit_self: fld.fold_explicit_self(&m.explicit_self),
         id: fld.new_id(m.id),
@@ -674,7 +597,7 @@ pub fn noop_fold_type_method<T:ast_fold>(m: &TypeMethod, fld: &mut T)
     }
 }
 
-pub fn noop_fold_mod<T:ast_fold>(m: &_mod, folder: &mut T) -> _mod {
+pub fn noop_fold_mod<T: ast_fold>(m: &_mod, folder: &mut T) -> _mod {
     ast::_mod {
         view_items: m.view_items
                      .iter()
@@ -683,7 +606,7 @@ pub fn noop_fold_mod<T:ast_fold>(m: &_mod, folder: &mut T) -> _mod {
     }
 }
 
-pub fn noop_fold_crate<T:ast_fold>(c: Crate, folder: &mut T) -> Crate {
+pub fn noop_fold_crate<T: ast_fold>(c: Crate, folder: &mut T) -> Crate {
     let fold_meta_item = |x| fold_meta_item_(x, folder);
     let fold_attribute = |x| fold_attribute_(x, folder);
 
@@ -695,11 +618,11 @@ pub fn noop_fold_crate<T:ast_fold>(c: Crate, folder: &mut T) -> Crate {
     }
 }
 
-pub fn noop_fold_item<T:ast_fold>(i: @ast::item, folder: &mut T)
-                                  -> SmallVector<@ast::item> {
+pub fn noop_fold_item<T: ast_fold>(i: &item, folder: &mut T)
+                                   -> SmallVector<@item> {
     let fold_attribute = |x| fold_attribute_(x, folder);
 
-    SmallVector::one(@ast::item {
+    SmallVector::one(@item {
         ident: folder.fold_ident(i.ident),
         attrs: i.attrs.map(|e| fold_attribute(*e)),
         id: folder.new_id(i.id),
@@ -709,7 +632,92 @@ pub fn noop_fold_item<T:ast_fold>(i: @ast::item, folder: &mut T)
     })
 }
 
-pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &mut T) -> @ast::Expr {
+pub fn noop_fold_foreign_item<T: ast_fold>(ni: &foreign_item, folder: &mut T)
+                                           -> @foreign_item {
+    @foreign_item {
+        ident: folder.fold_ident(ni.ident),
+        attrs: ni.attrs.map(|x| fold_attribute_(*x, folder)),
+        node: match ni.node {
+            foreign_item_fn(ref fdec, ref generics) => {
+                foreign_item_fn(P(fn_decl {
+                    inputs: fdec.inputs.map(|a| fold_arg_(a, folder)),
+                    output: folder.fold_ty(fdec.output),
+                    cf: fdec.cf,
+                    variadic: fdec.variadic
+                }), fold_generics(generics, folder))
+            }
+            foreign_item_static(t, m) => {
+                foreign_item_static(folder.fold_ty(t), m)
+            }
+        },
+        id: folder.new_id(ni.id),
+        span: folder.new_span(ni.span),
+        vis: ni.vis,
+    }
+}
+
+pub fn noop_fold_method<T: ast_fold>(m: &method, folder: &mut T) -> @method {
+    @method {
+        ident: folder.fold_ident(m.ident),
+        attrs: m.attrs.map(|a| fold_attribute_(*a, folder)),
+        generics: fold_generics(&m.generics, folder),
+        explicit_self: folder.fold_explicit_self(&m.explicit_self),
+        purity: m.purity,
+        decl: folder.fold_fn_decl(m.decl),
+        body: folder.fold_block(m.body),
+        id: folder.new_id(m.id),
+        span: folder.new_span(m.span),
+        self_id: folder.new_id(m.self_id),
+        vis: m.vis
+    }
+}
+
+pub fn noop_fold_pat<T: ast_fold>(p: @Pat, folder: &mut T) -> @Pat {
+    let node = match p.node {
+        PatWild => PatWild,
+        PatWildMulti => PatWildMulti,
+        PatIdent(binding_mode, ref pth, ref sub) => {
+            PatIdent(binding_mode,
+                     folder.fold_path(pth),
+                     sub.map(|x| folder.fold_pat(x)))
+        }
+        PatLit(e) => PatLit(folder.fold_expr(e)),
+        PatEnum(ref pth, ref pats) => {
+            PatEnum(folder.fold_path(pth),
+                    pats.as_ref().map(|pats| pats.map(|x| folder.fold_pat(*x))))
+        }
+        PatStruct(ref pth, ref fields, etc) => {
+            let pth_ = folder.fold_path(pth);
+            let fs = fields.map(|f| {
+                ast::FieldPat {
+                    ident: f.ident,
+                    pat: folder.fold_pat(f.pat)
+                }
+            });
+            PatStruct(pth_, fs, etc)
+        }
+        PatTup(ref elts) => PatTup(elts.map(|x| folder.fold_pat(*x))),
+        PatBox(inner) => PatBox(folder.fold_pat(inner)),
+        PatUniq(inner) => PatUniq(folder.fold_pat(inner)),
+        PatRegion(inner) => PatRegion(folder.fold_pat(inner)),
+        PatRange(e1, e2) => {
+            PatRange(folder.fold_expr(e1), folder.fold_expr(e2))
+        },
+        PatVec(ref before, ref slice, ref after) => {
+            PatVec(before.map(|x| folder.fold_pat(*x)),
+                    slice.map(|x| folder.fold_pat(x)),
+                    after.map(|x| folder.fold_pat(*x)))
+        }
+    };
+
+    @Pat {
+        id: folder.new_id(p.id),
+        span: folder.new_span(p.span),
+        node: node,
+    }
+}
+
+pub fn noop_fold_expr<T: ast_fold>(e: @Expr, folder: &mut T) -> @Expr {
     let fold_field = |x| fold_field_(x, folder);
 
     let node = match e.node {
@@ -776,13 +784,10 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &mut T) -> @ast::Expr {
                       arms.map(|x| folder.fold_arm(x)))
         }
         ExprFnBlock(decl, body) => {
-            ExprFnBlock(
-                fold_fn_decl(decl, folder),
-                folder.fold_block(body)
-            )
+            ExprFnBlock(folder.fold_fn_decl(decl), folder.fold_block(body))
         }
         ExprProc(decl, body) => {
-            ExprProc(fold_fn_decl(decl, folder), folder.fold_block(body))
+            ExprProc(folder.fold_fn_decl(decl), folder.fold_block(body))
         }
         ExprBlock(blk) => ExprBlock(folder.fold_block(blk)),
         ExprAssign(el, er) => {
@@ -835,7 +840,7 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &mut T) -> @ast::Expr {
     }
 }
 
-pub fn noop_fold_stmt<T:ast_fold>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt> {
+pub fn noop_fold_stmt<T: ast_fold>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt> {
     let nodes = match s.node {
         StmtDecl(d, nid) => {
             folder.fold_decl(d).move_iter()
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 29567ab9442..6484855d9d9 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -64,34 +64,34 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics {
     }
 }
 
-pub trait Visitor<E:Clone> {
+pub trait Visitor<E: Clone> {
     fn visit_ident(&mut self, _sp: Span, _ident: Ident, _e: E) {
         /*! 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:&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:P<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:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, e:E) {
+    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) { 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: &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) {
+    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) }
-    fn visit_variant(&mut self, v:&variant, g:&Generics, e:E) { walk_variant(self, v, g, e) }
+    fn visit_struct_field(&mut self, s: &struct_field, 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_opt_lifetime_ref(&mut self,
                               _span: Span,
                               opt_lifetime: &Option<Lifetime>,
@@ -115,7 +115,7 @@ pub trait Visitor<E:Clone> {
     fn visit_explicit_self(&mut self, es: &explicit_self, e: E) {
         walk_explicit_self(self, es, e)
     }
-    fn visit_mac(&mut self, macro:&mac, e:E) {
+    fn visit_mac(&mut self, macro: &mac, e: E) {
         walk_mac(self, macro, e)
     }
     fn visit_path(&mut self, path: &Path, _id: ast::NodeId, e: E) {
@@ -123,11 +123,11 @@ pub trait Visitor<E:Clone> {
     }
 }
 
-pub fn walk_crate<E:Clone, V:Visitor<E>>(visitor: &mut V, crate: &Crate, env: 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 walk_mod<E:Clone, V:Visitor<E>>(visitor: &mut V, 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())
     }
@@ -137,7 +137,7 @@ pub fn walk_mod<E:Clone, V:Visitor<E>>(visitor: &mut V, module: &_mod, env: E) {
     }
 }
 
-pub fn walk_view_item<E:Clone, V:Visitor<E>>(visitor: &mut V, vi: &view_item, env: E) {
+pub fn walk_view_item<E: Clone, V: Visitor<E>>(visitor: &mut V, vi: &view_item, env: E) {
     match vi.node {
         view_item_extern_mod(name, _, _) => {
             visitor.visit_ident(vi.span, name, env)
@@ -164,7 +164,7 @@ pub fn walk_view_item<E:Clone, V:Visitor<E>>(visitor: &mut V, vi: &view_item, en
     }
 }
 
-pub fn walk_local<E:Clone, V:Visitor<E>>(visitor: &mut V, 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 {
@@ -173,9 +173,9 @@ pub fn walk_local<E:Clone, V:Visitor<E>>(visitor: &mut V, local: &Local, env: E)
     }
 }
 
-fn walk_explicit_self<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                             explicit_self: &explicit_self,
-                                             env: E) {
+fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                               explicit_self: &explicit_self,
+                                               env: E) {
     match explicit_self.node {
         sty_static | sty_value(_) | sty_box(_) | sty_uniq(_) => {
         }
@@ -185,13 +185,13 @@ fn walk_explicit_self<E:Clone, V:Visitor<E>>(visitor: &mut V,
     }
 }
 
-fn walk_trait_ref<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                            trait_ref: &ast::trait_ref,
-                            env: E) {
+fn walk_trait_ref<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                           trait_ref: &trait_ref,
+                                           env: E) {
     visitor.visit_path(&trait_ref.path, trait_ref.ref_id, env)
 }
 
-pub fn walk_item<E:Clone, V:Visitor<E>>(visitor: &mut V, item: &item, env: E) {
+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());
     match item.node {
         item_static(typ, _, expr) => {
@@ -261,19 +261,19 @@ pub fn walk_item<E:Clone, V:Visitor<E>>(visitor: &mut V, item: &item, env: E) {
     }
 }
 
-pub fn walk_enum_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                               enum_definition: &ast::enum_def,
-                               generics: &Generics,
-                               env: E) {
+pub fn walk_enum_def<E: Clone, V:Visitor<E>>(visitor: &mut V,
+                                             enum_definition: &enum_def,
+                                             generics: &Generics,
+                                             env: E) {
     for &variant in enum_definition.variants.iter() {
         visitor.visit_variant(variant, generics, env.clone());
     }
 }
 
-pub fn walk_variant<E:Clone, V:Visitor<E>>(visitor:&mut V,
-                                           variant: &variant,
-                                           generics: &Generics,
-                                           env: E) {
+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());
 
     match variant.node.kind {
@@ -296,11 +296,11 @@ pub fn walk_variant<E:Clone, V:Visitor<E>>(visitor:&mut V,
     }
 }
 
-pub fn skip_ty<E, V:Visitor<E>>(_: &mut V, _: &Ty, _: E) {
+pub fn skip_ty<E, V: Visitor<E>>(_: &mut V, _: &Ty, _: E) {
     // Empty!
 }
 
-pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
+pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
     match typ.node {
         ty_uniq(ty) | ty_vec(ty) | ty_box(ty) => {
             visitor.visit_ty(ty, env)
@@ -357,15 +357,15 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
     }
 }
 
-fn walk_lifetime_decls<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                              lifetimes: &OptVec<Lifetime>,
-                                              env: E) {
+fn walk_lifetime_decls<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                lifetimes: &OptVec<Lifetime>,
+                                                env: E) {
     for l in lifetimes.iter() {
         visitor.visit_lifetime_decl(l, env.clone());
     }
 }
 
-pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
+pub fn walk_path<E: Clone, V: Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
     for segment in path.segments.iter() {
         visitor.visit_ident(path.span, segment.identifier, env.clone());
 
@@ -378,7 +378,7 @@ pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
     }
 }
 
-pub fn walk_pat<E:Clone, V:Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E) {
+pub fn walk_pat<E: Clone, V: Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E) {
     match pattern.node {
         PatEnum(ref path, ref children) => {
             visitor.visit_path(path, pattern.id, env.clone());
@@ -431,9 +431,9 @@ pub fn walk_pat<E:Clone, V:Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E) {
     }
 }
 
-pub fn walk_foreign_item<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                   foreign_item: &foreign_item,
-                                   env: E) {
+pub fn walk_foreign_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                  foreign_item: &foreign_item,
+                                                  env: E) {
     visitor.visit_ident(foreign_item.span, foreign_item.ident, env.clone());
 
     match foreign_item.node {
@@ -445,9 +445,9 @@ pub fn walk_foreign_item<E:Clone, V:Visitor<E>>(visitor: &mut V,
     }
 }
 
-pub fn walk_ty_param_bounds<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                      bounds: &OptVec<TyParamBound>,
-                                      env: 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) => {
@@ -458,18 +458,18 @@ pub fn walk_ty_param_bounds<E:Clone, V:Visitor<E>>(visitor: &mut V,
     }
 }
 
-pub fn walk_generics<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                               generics: &Generics,
-                               env: 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() {
         walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
     }
     walk_lifetime_decls(visitor, &generics.lifetimes, env);
 }
 
-pub fn walk_fn_decl<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                              function_declaration: &fn_decl,
-                              env: 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() {
         visitor.visit_pat(argument.pat, env.clone());
         visitor.visit_ty(argument.ty, env.clone())
@@ -481,9 +481,9 @@ pub fn walk_fn_decl<E:Clone, V:Visitor<E>>(visitor: &mut V,
 // 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 walk_method_helper<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                    method: &method,
-                                    env: E) {
+pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                   method: &method,
+                                                   env: E) {
     visitor.visit_ident(method.span, method.ident, env.clone());
     visitor.visit_fn(&fk_method(method.ident, &method.generics, method),
                      method.decl,
@@ -493,13 +493,13 @@ pub fn walk_method_helper<E:Clone, V:Visitor<E>>(visitor: &mut V,
                      env)
 }
 
-pub fn walk_fn<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                         function_kind: &fn_kind,
-                         function_declaration: &fn_decl,
-                         function_body: P<Block>,
-                         _span: Span,
-                         _: NodeId,
-                         env: 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: Span,
+                                        _: NodeId,
+                                        env: E) {
     walk_fn_decl(visitor, function_declaration, env.clone());
 
     match *function_kind {
@@ -518,9 +518,9 @@ pub fn walk_fn<E:Clone, V:Visitor<E>>(visitor: &mut V,
     visitor.visit_block(function_body, env)
 }
 
-pub fn walk_ty_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                             method_type: &TypeMethod,
-                                             env: E) {
+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());
     for argument_type in method_type.decl.inputs.iter() {
@@ -530,9 +530,9 @@ pub fn walk_ty_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
     visitor.visit_ty(method_type.decl.output, env);
 }
 
-pub fn walk_trait_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                   trait_method: &trait_method,
-                                   env: 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)
@@ -541,20 +541,20 @@ pub fn walk_trait_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
     }
 }
 
-pub fn walk_struct_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                 struct_definition: @struct_def,
-                                 _: ast::Ident,
-                                 _: &Generics,
-                                 _: NodeId,
-                                 env: E) {
+pub fn walk_struct_def<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                struct_definition: &struct_def,
+                                                _: Ident,
+                                                _: &Generics,
+                                                _: NodeId,
+                                                env: E) {
     for field in struct_definition.fields.iter() {
         visitor.visit_struct_field(field, env.clone())
     }
 }
 
-pub fn walk_struct_field<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                   struct_field: &struct_field,
-                                   env: E) {
+pub fn walk_struct_field<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                  struct_field: &struct_field,
+                                                  env: E) {
     match struct_field.node.kind {
         named_field(name, _) => {
             visitor.visit_ident(struct_field.span, name, env.clone())
@@ -565,7 +565,7 @@ pub fn walk_struct_field<E:Clone, V:Visitor<E>>(visitor: &mut V,
     visitor.visit_ty(struct_field.node.ty, env)
 }
 
-pub fn walk_block<E:Clone, V:Visitor<E>>(visitor: &mut V, block: P<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())
     }
@@ -575,7 +575,7 @@ pub fn walk_block<E:Clone, V:Visitor<E>>(visitor: &mut V, block: P<Block>, env:
     walk_expr_opt(visitor, block.expr, env)
 }
 
-pub fn walk_stmt<E:Clone, V:Visitor<E>>(visitor: &mut V, statement: &Stmt, env: E) {
+pub fn walk_stmt<E: Clone, V: Visitor<E>>(visitor: &mut V, statement: &Stmt, env: E) {
     match statement.node {
         StmtDecl(declaration, _) => visitor.visit_decl(declaration, env),
         StmtExpr(expression, _) | StmtSemi(expression, _) => {
@@ -585,35 +585,35 @@ pub fn walk_stmt<E:Clone, V:Visitor<E>>(visitor: &mut V, statement: &Stmt, env:
     }
 }
 
-pub fn walk_decl<E:Clone, V:Visitor<E>>(visitor: &mut V, declaration: &Decl, env: E) {
+pub fn walk_decl<E: Clone, V: Visitor<E>>(visitor: &mut V, declaration: &Decl, env: E) {
     match declaration.node {
         DeclLocal(ref local) => visitor.visit_local(*local, env),
         DeclItem(item) => visitor.visit_item(item, env),
     }
 }
 
-pub fn walk_expr_opt<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                         optional_expression: Option<@Expr>,
-                         env: E) {
+pub fn walk_expr_opt<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                              optional_expression: Option<@Expr>,
+                                              env: E) {
     match optional_expression {
         None => {}
         Some(expression) => visitor.visit_expr(expression, env),
     }
 }
 
-pub fn walk_exprs<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                            expressions: &[@Expr],
-                            env: E) {
+pub fn walk_exprs<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                           expressions: &[@Expr],
+                                           env: E) {
     for expression in expressions.iter() {
         visitor.visit_expr(*expression, env.clone())
     }
 }
 
-pub fn walk_mac<E, V:Visitor<E>>(_: &mut V, _: &mac, _: E) {
+pub fn walk_mac<E, V: Visitor<E>>(_: &mut V, _: &mac, _: E) {
     // Empty!
 }
 
-pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env: E) {
+pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, env: E) {
     match expression.node {
         ExprVstore(subexpression, _) => {
             visitor.visit_expr(subexpression, env.clone())
@@ -745,7 +745,7 @@ pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env:
     visitor.visit_expr_post(expression, env.clone())
 }
 
-pub fn walk_arm<E:Clone, V:Visitor<E>>(visitor: &mut V, 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())
     }