about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2013-12-01 00:00:39 +0200
committerEduard Burtescu <edy.burt@gmail.com>2013-12-01 00:00:39 +0200
commita9c4b18b18bd3f5fd4a4c20489f37c52d106fc81 (patch)
treecbc704d0832866ca7c3856d0720f051eb526c7fa
parent80991bb578329ca921fdc910d9b6b064e8f521d2 (diff)
Box Block, fn_decl, variant and Ty in the AST, as they were inflating critical enum sizes.
-rw-r--r--src/librustc/front/config.rs12
-rw-r--r--src/librustc/metadata/encoder.rs4
-rw-r--r--src/librustc/middle/astencode.rs8
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs10
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs16
-rw-r--r--src/librustc/middle/borrowck/mod.rs6
-rw-r--r--src/librustc/middle/cfg/construct.rs12
-rw-r--r--src/librustc/middle/check_loop.rs6
-rw-r--r--src/librustc/middle/check_match.rs4
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/dataflow.rs14
-rw-r--r--src/librustc/middle/effect.rs4
-rw-r--r--src/librustc/middle/freevars.rs4
-rw-r--r--src/librustc/middle/kind.rs6
-rw-r--r--src/librustc/middle/lint.rs10
-rw-r--r--src/librustc/middle/liveness.rs18
-rw-r--r--src/librustc/middle/moves.rs18
-rw-r--r--src/librustc/middle/privacy.rs4
-rw-r--r--src/librustc/middle/reachable.rs6
-rw-r--r--src/librustc/middle/region.rs10
-rw-r--r--src/librustc/middle/resolve.rs57
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/middle/trans/_match.rs2
-rw-r--r--src/librustc/middle/trans/base.rs12
-rw-r--r--src/librustc/middle/trans/callee.rs6
-rw-r--r--src/librustc/middle/trans/controlflow.rs6
-rw-r--r--src/librustc/middle/trans/debuginfo.rs30
-rw-r--r--src/librustc/middle/trans/expr.rs12
-rw-r--r--src/librustc/middle/trans/inline.rs4
-rw-r--r--src/librustc/middle/trans/meth.rs4
-rw-r--r--src/librustc/middle/trans/monomorphize.rs4
-rw-r--r--src/librustc/middle/ty.rs2
-rw-r--r--src/librustc/middle/typeck/astconv.rs14
-rw-r--r--src/librustc/middle/typeck/check/_match.rs2
-rw-r--r--src/librustc/middle/typeck/check/mod.rs54
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs10
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs2
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs6
-rw-r--r--src/librustc/middle/typeck/coherence.rs2
-rw-r--r--src/librustc/middle/typeck/collect.rs26
-rw-r--r--src/librustc/middle/typeck/variance.rs2
-rw-r--r--src/librustc/util/common.rs4
-rw-r--r--src/librustdoc/doctree.rs6
-rw-r--r--src/librustdoc/visit_ast.rs14
-rw-r--r--src/libsyntax/ast.rs69
-rw-r--r--src/libsyntax/ast_map.rs26
-rw-r--r--src/libsyntax/ast_util.rs33
-rw-r--r--src/libsyntax/ext/build.rs164
-rw-r--r--src/libsyntax/ext/deriving/generic.rs28
-rw-r--r--src/libsyntax/ext/deriving/ty.rs6
-rw-r--r--src/libsyntax/ext/expand.rs35
-rw-r--r--src/libsyntax/ext/format.rs7
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs4
-rw-r--r--src/libsyntax/fold.rs94
-rw-r--r--src/libsyntax/parse/classify.rs4
-rw-r--r--src/libsyntax/parse/mod.rs20
-rw-r--r--src/libsyntax/parse/parser.rs140
-rw-r--r--src/libsyntax/parse/token.rs6
-rw-r--r--src/libsyntax/print/pprust.rs94
-rw-r--r--src/libsyntax/visit.rs74
60 files changed, 623 insertions, 640 deletions
diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs
index ee1935207b1..e9dfed46f73 100644
--- a/src/librustc/front/config.rs
+++ b/src/librustc/front/config.rs
@@ -27,7 +27,7 @@ impl<'self> fold::ast_fold for Context<'self> {
     fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {
         fold_mod(self, module)
     }
-    fn fold_block(&self, block: &ast::Block) -> ast::Block {
+    fn fold_block(&self, block: ast::P<ast::Block>) -> ast::P<ast::Block> {
         fold_block(self, block)
     }
     fn fold_foreign_mod(&self, foreign_module: &ast::foreign_mod)
@@ -97,10 +97,10 @@ fn fold_foreign_mod(cx: &Context, nm: &ast::foreign_mod) -> ast::foreign_mod {
 
 fn fold_item_underscore(cx: &Context, item: &ast::item_) -> ast::item_ {
     let item = match *item {
-        ast::item_impl(ref a, ref b, ref c, ref methods) => {
+        ast::item_impl(ref a, ref b, c, ref methods) => {
             let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
                 .map(|x| *x).collect();
-            ast::item_impl((*a).clone(), (*b).clone(), (*c).clone(), methods)
+            ast::item_impl((*a).clone(), (*b).clone(), c, methods)
         }
         ast::item_trait(ref a, ref b, ref methods) => {
             let methods = methods.iter()
@@ -129,7 +129,7 @@ fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
     }
 }
 
-fn fold_block(cx: &Context, b: &ast::Block) -> ast::Block {
+fn fold_block(cx: &Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
     let resulting_stmts = b.stmts.iter()
             .filter(|&a| retain_stmt(cx, *a))
             .flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
@@ -137,14 +137,14 @@ fn fold_block(cx: &Context, b: &ast::Block) -> ast::Block {
     let filtered_view_items = b.view_items.iter().filter_map(|a| {
         filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
     }).collect();
-    ast::Block {
+    ast::P(ast::Block {
         view_items: filtered_view_items,
         stmts: resulting_stmts,
         expr: b.expr.map(|x| cx.fold_expr(x)),
         id: b.id,
         rules: b.rules,
         span: b.span,
-    }
+    })
 }
 
 fn item_in_cfg(cx: &Context, item: @ast::item) -> bool {
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 6da75397002..79e38da7032 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -351,7 +351,7 @@ fn encode_struct_fields(ecx: &EncodeContext,
 fn encode_enum_variant_info(ecx: &EncodeContext,
                             ebml_w: &mut writer::Encoder,
                             id: NodeId,
-                            variants: &[variant],
+                            variants: &[P<variant>],
                             path: &[ast_map::path_elt],
                             index: @mut ~[entry<i64>],
                             generics: &ast::Generics) {
@@ -1080,7 +1080,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                                         def_id.node);
         }
       }
-      item_impl(_, ref opt_trait, ref ty, ref ast_methods) => {
+      item_impl(_, ref opt_trait, ty, ref ast_methods) => {
         // We need to encode information about the default methods we
         // have inherited, so we drive this based on the impl structure.
         let imp = tcx.impls.get(&def_id);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 2eb6dcaf49b..e8a7e73b58c 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -301,7 +301,7 @@ struct NestedItemsDropper {
 }
 
 impl fold::ast_fold for NestedItemsDropper {
-    fn fold_block(&self, blk: &ast::Block) -> ast::Block {
+    fn fold_block(&self, blk: ast::P<ast::Block>) -> ast::P<ast::Block> {
         let stmts_sans_items = blk.stmts.iter().filter_map(|stmt| {
             match stmt.node {
                 ast::StmtExpr(_, _) | ast::StmtSemi(_, _) |
@@ -316,7 +316,7 @@ impl fold::ast_fold for NestedItemsDropper {
                 ast::StmtMac(..) => fail!("unexpanded macro in astencode")
             }
         }).collect();
-        let blk_sans_items = ast::Block {
+        let blk_sans_items = ast::P(ast::Block {
             view_items: ~[], // I don't know if we need the view_items here,
                              // but it doesn't break tests!
             stmts: stmts_sans_items,
@@ -324,8 +324,8 @@ impl fold::ast_fold for NestedItemsDropper {
             id: blk.id,
             rules: blk.rules,
             span: blk.span,
-        };
-        fold::noop_fold_block(&blk_sans_items, self)
+        });
+        fold::noop_fold_block(blk_sans_items, self)
     }
 }
 
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index 6545919e844..4e1fca1e125 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -48,14 +48,14 @@ impl<'self> Visitor<()> for CheckLoanCtxt<'self> {
     fn visit_local(&mut self, l:@ast::Local, _:()) {
         check_loans_in_local(self, l);
     }
-    fn visit_block(&mut self, b:&ast::Block, _:()) {
+    fn visit_block(&mut self, b:ast::P<ast::Block>, _:()) {
         check_loans_in_block(self, b);
     }
     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::Block, s:Span, n:ast::NodeId, _:()) {
+                b:ast::P<ast::Block>, s:Span, n:ast::NodeId, _:()) {
         check_loans_in_fn(self, fk, fd, b, s, n);
     }
 }
@@ -64,7 +64,7 @@ pub fn check_loans(bccx: &BorrowckCtxt,
                    dfcx_loans: &LoanDataFlow,
                    move_data: move_data::FlowedMoveData,
                    all_loans: &[Loan],
-                   body: &ast::Block) {
+                   body: ast::P<ast::Block>) {
     debug!("check_loans(body id={:?})", body.id);
 
     let mut clcx = CheckLoanCtxt {
@@ -724,7 +724,7 @@ impl<'self> CheckLoanCtxt<'self> {
 fn check_loans_in_fn<'a>(this: &mut CheckLoanCtxt<'a>,
                          fk: &visit::fn_kind,
                          decl: &ast::fn_decl,
-                         body: &ast::Block,
+                         body: ast::P<ast::Block>,
                          sp: Span,
                          id: ast::NodeId) {
     match *fk {
@@ -855,7 +855,7 @@ fn check_loans_in_pat<'a>(this: &mut CheckLoanCtxt<'a>,
 }
 
 fn check_loans_in_block<'a>(this: &mut CheckLoanCtxt<'a>,
-                            blk: &ast::Block)
+                            blk: ast::P<ast::Block>)
 {
     visit::walk_block(this, blk, ());
     this.check_for_conflicting_loans(blk.id);
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index 7688d4dff73..787cba86bb4 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -32,7 +32,7 @@ use syntax::codemap::Span;
 use syntax::print::pprust;
 use syntax::visit;
 use syntax::visit::{Visitor, fn_kind};
-use syntax::ast::{Expr, fn_decl, Block, NodeId, Stmt, Pat, Local};
+use syntax::ast::{P, Expr, fn_decl, Block, NodeId, Stmt, Pat, Local};
 
 mod lifetime;
 mod restrictions;
@@ -77,10 +77,10 @@ impl<'self> visit::Visitor<()> for GatherLoanCtxt<'self> {
     fn visit_expr(&mut self, ex:@Expr, _:()) {
         gather_loans_in_expr(self, ex);
     }
-    fn visit_block(&mut self, b:&Block, _:()) {
+    fn visit_block(&mut self, b:P<Block>, _:()) {
         gather_loans_in_block(self, b);
     }
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block,
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>,
                 s:Span, n:NodeId, _:()) {
         gather_loans_in_fn(self, fk, fd, b, s, n);
     }
@@ -102,7 +102,7 @@ impl<'self> visit::Visitor<()> for GatherLoanCtxt<'self> {
 
 pub fn gather_loans(bccx: &BorrowckCtxt,
                     decl: &ast::fn_decl,
-                    body: &ast::Block)
+                    body: ast::P<ast::Block>)
                     -> (id_range, @mut ~[Loan], @mut move_data::MoveData) {
     let mut glcx = GatherLoanCtxt {
         bccx: bccx,
@@ -131,7 +131,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::Block,
+                      body: ast::P<ast::Block>,
                       sp: Span,
                       id: ast::NodeId) {
     match fk {
@@ -150,7 +150,7 @@ fn gather_loans_in_fn(this: &mut GatherLoanCtxt,
 }
 
 fn gather_loans_in_block(this: &mut GatherLoanCtxt,
-                         blk: &ast::Block) {
+                         blk: ast::P<ast::Block>) {
     this.id_range.add(blk.id);
     visit::walk_block(this, blk, ());
 }
@@ -286,7 +286,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
       }
 
       // see explanation attached to the `root_ub` field:
-      ast::ExprWhile(cond, ref body) => {
+      ast::ExprWhile(cond, body) => {
           // during the condition, can only root for the condition
           this.push_repeating_id(cond.id);
           this.visit_expr(cond, ());
@@ -299,7 +299,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
       }
 
       // see explanation attached to the `root_ub` field:
-      ast::ExprLoop(ref body, _) => {
+      ast::ExprLoop(body, _) => {
           this.push_repeating_id(body.id);
           visit::walk_expr(this, ex, ());
           this.pop_repeating_id(body.id);
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index c12194ac8bb..b8e7a13f208 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::{fn_decl,Block,NodeId};
+use syntax::ast::{P,fn_decl,Block,NodeId};
 
 macro_rules! if_ok(
     ($inp: expr) => (
@@ -62,7 +62,7 @@ pub type LoanDataFlow = DataFlowContext<LoanDataFlowOperator>;
 
 impl Visitor<()> for BorrowckCtxt {
     fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl,
-                b:&Block, s:Span, n:NodeId, _:()) {
+                b:P<Block>, s:Span, n:NodeId, _:()) {
         borrowck_fn(self, fk, fd, b, s, n);
     }
 }
@@ -123,7 +123,7 @@ pub fn check_crate(
 fn borrowck_fn(this: &mut BorrowckCtxt,
                fk: &visit::fn_kind,
                decl: &ast::fn_decl,
-               body: &ast::Block,
+               body: ast::P<ast::Block>,
                sp: Span,
                id: ast::NodeId) {
     match fk {
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index 028fdd52a26..4a12ac4ccff 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -161,12 +161,12 @@ impl CFGBuilder {
 
     fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex {
         match expr.node {
-            ast::ExprBlock(ref blk) => {
+            ast::ExprBlock(blk) => {
                 let blk_exit = self.block(blk, pred);
                 self.add_node(expr.id, [blk_exit])
             }
 
-            ast::ExprIf(cond, ref then, None) => {
+            ast::ExprIf(cond, then, None) => {
                 //
                 //     [pred]
                 //       |
@@ -186,7 +186,7 @@ impl CFGBuilder {
                 self.add_node(expr.id, [cond_exit, then_exit])        // 3,4
             }
 
-            ast::ExprIf(cond, ref then, Some(otherwise)) => {
+            ast::ExprIf(cond, then, Some(otherwise)) => {
                 //
                 //     [pred]
                 //       |
@@ -207,7 +207,7 @@ impl CFGBuilder {
                 self.add_node(expr.id, [then_exit, else_exit])        // 4, 5
             }
 
-            ast::ExprWhile(cond, ref body) => {
+            ast::ExprWhile(cond, body) => {
                 //
                 //         [pred]
                 //           |
@@ -241,7 +241,7 @@ impl CFGBuilder {
 
             ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
 
-            ast::ExprLoop(ref body, _) => {
+            ast::ExprLoop(body, _) => {
                 //
                 //     [pred]
                 //       |
@@ -300,7 +300,7 @@ impl CFGBuilder {
                 for arm in arms.iter() {
                     guard_exit = self.opt_expr(arm.guard, guard_exit); // 2
                     let pats_exit = self.pats_any(arm.pats, guard_exit); // 3
-                    let body_exit = self.block(&arm.body, pats_exit);    // 4
+                    let body_exit = self.block(arm.body, pats_exit);    // 4
                     self.add_contained_edge(body_exit, expr_exit);       // 5
                 }
                 expr_exit
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index 8a320f88649..a08884857a6 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -35,14 +35,14 @@ impl Visitor<Context> for CheckLoopVisitor {
 
     fn visit_expr(&mut self, e: @ast::Expr, cx:Context) {
         match e.node {
-            ast::ExprWhile(e, ref b) => {
+            ast::ExprWhile(e, b) => {
                 self.visit_expr(e, cx);
                 self.visit_block(b, Loop);
             }
-            ast::ExprLoop(ref b, _) => {
+            ast::ExprLoop(b, _) => {
                 self.visit_block(b, Loop);
             }
-            ast::ExprFnBlock(_, ref b) | ast::ExprProc(_, ref b) => {
+            ast::ExprFnBlock(_, b) | ast::ExprProc(_, b) => {
                 self.visit_block(b, Closure);
             }
             ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index c46f5fa892e..7e236a87514 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -45,7 +45,7 @@ impl Visitor<()> for CheckMatchVisitor {
     fn visit_local(&mut self, l:@Local, e:()) {
         check_local(self, self.cx, l, e);
     }
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, e:()) {
+    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);
     }
 }
@@ -827,7 +827,7 @@ fn check_fn(v: &mut CheckMatchVisitor,
                 cx: &MatchCheckCtxt,
                 kind: &visit::fn_kind,
                 decl: &fn_decl,
-                body: &Block,
+                body: P<Block>,
                 sp: Span,
                 id: NodeId,
                 s: ()) {
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 641a685a38f..248ff1fdd16 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -90,7 +90,7 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt,
                             enum_def: ast::DefId,
                             variant_def: ast::DefId)
                        -> Option<@Expr> {
-    fn variant_expr(variants: &[ast::variant], id: ast::NodeId) -> Option<@Expr> {
+    fn variant_expr(variants: &[ast::P<ast::variant>], id: ast::NodeId) -> Option<@Expr> {
         for variant in variants.iter() {
             if variant.node.id == id {
                 return variant.node.disr_expr;
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index 6927793ec1f..6ef3b70dba8 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -429,8 +429,8 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
         self.merge_with_entry_set(expr.id, in_out);
 
         match expr.node {
-            ast::ExprFnBlock(ref decl, ref body) |
-            ast::ExprProc(ref decl, ref body) => {
+            ast::ExprFnBlock(ref decl, body) |
+            ast::ExprProc(ref decl, body) => {
                 if self.dfcx.oper.walk_closures() {
                     // In the absence of once fns, we must assume that
                     // every function body will execute more than
@@ -519,7 +519,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
                 }
             }
 
-            ast::ExprIf(cond, ref then, els) => {
+            ast::ExprIf(cond, then, els) => {
                 //
                 //     (cond)
                 //       |
@@ -542,7 +542,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
                 join_bits(&self.dfcx.oper, then_bits, in_out);
             }
 
-            ast::ExprWhile(cond, ref blk) => {
+            ast::ExprWhile(cond, blk) => {
                 //
                 //     (expr) <--+
                 //       |       |
@@ -570,7 +570,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
 
             ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
 
-            ast::ExprLoop(ref blk, _) => {
+            ast::ExprLoop(blk, _) => {
                 //
                 //     (expr) <--+
                 //       |       |
@@ -623,7 +623,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
                     // them into `in_out`, which reflects all bodies to date
                     let mut body = reslice(guards).to_owned();
                     self.walk_pat_alternatives(arm.pats, body, loop_scopes);
-                    self.walk_block(&arm.body, body, loop_scopes);
+                    self.walk_block(arm.body, body, loop_scopes);
                     join_bits(&self.dfcx.oper, body, in_out);
                 }
             }
@@ -730,7 +730,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> {
                 }
             }
 
-            ast::ExprBlock(ref blk) => {
+            ast::ExprBlock(blk) => {
                 self.walk_block(blk, in_out, loop_scopes);
             }
 
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 4c7ffcf1e21..aff37264f24 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -81,7 +81,7 @@ impl EffectCheckVisitor {
 
 impl Visitor<()> for EffectCheckVisitor {
     fn visit_fn(&mut self, fn_kind: &visit::fn_kind, fn_decl: &ast::fn_decl,
-                block: &ast::Block, span: Span, node_id: ast::NodeId, _:()) {
+                block: ast::P<ast::Block>, span: Span, node_id: ast::NodeId, _:()) {
 
         let (is_item_fn, is_unsafe_fn) = match *fn_kind {
             visit::fk_item_fn(_, _, purity, _) =>
@@ -103,7 +103,7 @@ impl Visitor<()> for EffectCheckVisitor {
         self.unsafe_context = old_unsafe_context
     }
 
-    fn visit_block(&mut self, block: &ast::Block, _:()) {
+    fn visit_block(&mut self, block: ast::P<ast::Block>, _:()) {
         let old_unsafe_context = self.unsafe_context;
         let is_unsafe = match block.rules {
             ast::UnsafeBlock(..) => true, ast::DefaultBlock => false
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
index 1219fd9260e..10b72b06048 100644
--- a/src/librustc/middle/freevars.rs
+++ b/src/librustc/middle/freevars.rs
@@ -88,7 +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::Block)
+fn collect_freevars(def_map: resolve::DefMap, blk: ast::P<ast::Block>)
     -> freevar_info {
     let seen = @mut HashMap::new();
     let refs = @mut ~[];
@@ -110,7 +110,7 @@ struct AnnotateFreevarsVisitor {
 
 impl Visitor<()> for AnnotateFreevarsVisitor {
     fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
-                blk:&ast::Block, s:Span, nid:ast::NodeId, _:()) {
+                blk:ast::P<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 bd6e7d528a7..c1b2b304c51 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -62,7 +62,7 @@ impl Visitor<()> for Context {
         check_expr(self, ex);
     }
 
-    fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, _:()) {
         check_fn(self, fk, fd, b, s, n);
     }
 
@@ -154,7 +154,7 @@ fn check_impl_of_trait(cx: &mut Context, it: @item, trait_ref: &trait_ref, self_
 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), ref self_type, _) => {
+            item_impl(_, Some(ref trait_ref), self_type, _) => {
                 check_impl_of_trait(cx, item, trait_ref, self_type);
             }
             _ => {}
@@ -240,7 +240,7 @@ fn check_fn(
     cx: &mut Context,
     fk: &visit::fn_kind,
     decl: &fn_decl,
-    body: &Block,
+    body: P<Block>,
     sp: Span,
     fn_id: NodeId) {
 
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 4c6ca53694a..f56fcee0f6f 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -733,19 +733,19 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) {
 
     fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) {
         for input in decl.inputs.iter() {
-            check_ty(cx, &input.ty);
+            check_ty(cx, input.ty);
         }
-        check_ty(cx, &decl.output)
+        check_ty(cx, decl.output)
     }
 
     match it.node {
       ast::item_foreign_mod(ref nmod) if !nmod.abis.is_intrinsic() => {
         for ni in nmod.items.iter() {
             match ni.node {
-                ast::foreign_item_fn(ref decl, _) => {
+                ast::foreign_item_fn(decl, _) => {
                     check_foreign_fn(cx, decl);
                 }
-                ast::foreign_item_static(ref t, _) => { check_ty(cx, t); }
+                ast::foreign_item_static(t, _) => { check_ty(cx, t); }
             }
         }
       }
@@ -1267,7 +1267,7 @@ impl<'self> Visitor<()> for Context<'self> {
     }
 
     fn visit_fn(&mut self, fk: &visit::fn_kind, decl: &ast::fn_decl,
-                body: &ast::Block, span: Span, id: ast::NodeId, _: ()) {
+                body: ast::P<ast::Block>, span: Span, id: ast::NodeId, _: ()) {
         let recurse = |this: &mut Context| {
             visit::walk_fn(this, fk, decl, body, span, id, ());
         };
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index ec86efdad75..d800b52df0f 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -155,7 +155,7 @@ fn live_node_kind_to_str(lnk: LiveNodeKind, cx: ty::ctxt) -> ~str {
 struct LivenessVisitor;
 
 impl Visitor<@mut IrMaps> for LivenessVisitor {
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, e:@mut IrMaps) {
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, e:@mut IrMaps) {
         visit_fn(self, fk, fd, b, s, n, e);
     }
     fn visit_local(&mut self, l:@Local, e:@mut IrMaps) { visit_local(self, l, e); }
@@ -347,7 +347,7 @@ impl IrMaps {
 }
 
 impl Visitor<()> for Liveness {
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, _:()) {
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<Block>, s:Span, n:NodeId, _:()) {
         check_fn(self, fk, fd, b, s, n);
     }
     fn visit_local(&mut self, l:@Local, _:()) {
@@ -364,7 +364,7 @@ impl Visitor<()> for Liveness {
 fn visit_fn(v: &mut LivenessVisitor,
             fk: &visit::fn_kind,
             decl: &fn_decl,
-            body: &Block,
+            body: P<Block>,
             sp: Span,
             id: NodeId,
             this: @mut IrMaps) {
@@ -1024,7 +1024,7 @@ impl Liveness {
               self.propagate_through_expr(e, succ)
           }
 
-          ExprFnBlock(_, ref blk) | ExprProc(_, ref blk) => {
+          ExprFnBlock(_, blk) | ExprProc(_, blk) => {
               debug!("{} is an ExprFnBlock or ExprProc",
                    expr_to_str(expr, self.tcx.sess.intr()));
 
@@ -1047,7 +1047,7 @@ impl Liveness {
               })
           }
 
-          ExprIf(cond, ref then, els) => {
+          ExprIf(cond, then, els) => {
             //
             //     (cond)
             //       |
@@ -1069,7 +1069,7 @@ impl Liveness {
             self.propagate_through_expr(cond, ln)
           }
 
-          ExprWhile(cond, ref blk) => {
+          ExprWhile(cond, blk) => {
             self.propagate_through_loop(expr, Some(cond), blk, succ)
           }
 
@@ -1077,7 +1077,7 @@ impl Liveness {
 
           // Note that labels have been resolved, so we don't need to look
           // at the label ident
-          ExprLoop(ref blk, _) => {
+          ExprLoop(blk, _) => {
             self.propagate_through_loop(expr, None, blk, succ)
           }
 
@@ -1101,7 +1101,7 @@ impl Liveness {
             let mut first_merge = true;
             for arm in arms.iter() {
                 let body_succ =
-                    self.propagate_through_block(&arm.body, succ);
+                    self.propagate_through_block(arm.body, succ);
                 let guard_succ =
                     self.propagate_through_opt_expr(arm.guard, body_succ);
                 let arm_succ =
@@ -1247,7 +1247,7 @@ impl Liveness {
             succ
           }
 
-          ExprBlock(ref blk) => {
+          ExprBlock(blk) => {
             self.propagate_through_block(blk, succ)
           }
 
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index f23ebac5e96..8cdca441d8a 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -193,7 +193,7 @@ enum UseMode {
 
 impl visit::Visitor<()> for VisitContext {
     fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&fn_decl,
-                b:&Block, s:Span, n:NodeId, _:()) {
+                b:P<Block>, s:Span, n:NodeId, _:()) {
         compute_modes_for_fn(self, fk, fd, b, s, n);
     }
     fn visit_expr(&mut self, ex:@Expr, _:()) {
@@ -247,7 +247,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: &Block,
+                        body: P<Block>,
                         span: Span,
                         id: NodeId) {
     for a in decl.inputs.iter() {
@@ -450,7 +450,7 @@ impl VisitContext {
                 self.consume_exprs(*exprs);
             }
 
-            ExprIf(cond_expr, ref then_blk, opt_else_expr) => {
+            ExprIf(cond_expr, then_blk, opt_else_expr) => {
                 self.consume_expr(cond_expr);
                 self.consume_block(then_blk);
                 for else_expr in opt_else_expr.iter() {
@@ -489,11 +489,11 @@ impl VisitContext {
             ExprAgain(..) |
             ExprLit(..) => {}
 
-            ExprLoop(ref blk, _) => {
+            ExprLoop(blk, _) => {
                 self.consume_block(blk);
             }
 
-            ExprWhile(cond_expr, ref blk) => {
+            ExprWhile(cond_expr, blk) => {
                 self.consume_expr(cond_expr);
                 self.consume_block(blk);
             }
@@ -515,7 +515,7 @@ impl VisitContext {
                 }
             }
 
-            ExprBlock(ref blk) => {
+            ExprBlock(blk) => {
                 self.consume_block(blk);
             }
 
@@ -553,8 +553,8 @@ impl VisitContext {
                 self.use_expr(base, comp_mode);
             }
 
-            ExprFnBlock(ref decl, ref body) |
-            ExprProc(ref decl, ref body) => {
+            ExprFnBlock(ref decl, body) |
+            ExprProc(ref decl, body) => {
                 for a in decl.inputs.iter() {
                     self.use_pat(a.pat);
                 }
@@ -604,7 +604,7 @@ impl VisitContext {
             self.consume_expr(*guard);
         }
 
-        self.consume_block(&arm.body);
+        self.consume_block(arm.body);
     }
 
     pub fn use_pat(&mut self, pat: @Pat) {
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 100d9329f18..2556397caf9 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -96,7 +96,7 @@ impl Visitor<()> for ParentVisitor {
     }
 
     fn visit_fn(&mut self, a: &visit::fn_kind, b: &ast::fn_decl,
-                c: &ast::Block, d: Span, id: ast::NodeId, _: ()) {
+                c: ast::P<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.
@@ -801,7 +801,7 @@ impl Visitor<()> for SanePrivacyVisitor {
     }
 
     fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &ast::fn_decl,
-                b: &ast::Block, s: Span, n: ast::NodeId, _: ()) {
+                b: ast::P<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, ());
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index bc62e6afeee..a6cd431c603 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -304,7 +304,7 @@ impl ReachableContext {
         match *node {
             ast_map::node_item(item, _) => {
                 match item.node {
-                    ast::item_fn(_, _, _, _, ref search_block) => {
+                    ast::item_fn(_, _, _, _, search_block) => {
                         if item_might_be_inlined(item) {
                             visit::walk_block(visitor, search_block, ())
                         }
@@ -331,13 +331,13 @@ impl ReachableContext {
                         // Keep going, nothing to get exported
                     }
                     ast::provided(ref method) => {
-                        visit::walk_block(visitor, &method.body, ())
+                        visit::walk_block(visitor, method.body, ())
                     }
                 }
             }
             ast_map::node_method(method, did, _) => {
                 if method_might_be_inlined(self.tcx, method, did) {
-                    visit::walk_block(visitor, &method.body, ())
+                    visit::walk_block(visitor, method.body, ())
                 }
             }
             // Nothing to recurse on for these
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index fc7dfdf5624..2a372a9e717 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -29,7 +29,7 @@ use std::hashmap::{HashMap, HashSet};
 use syntax::codemap::Span;
 use syntax::{ast, visit};
 use syntax::visit::{Visitor,fn_kind};
-use syntax::ast::{Block,item,fn_decl,NodeId,Arm,Pat,Stmt,Expr,Local};
+use syntax::ast::{P,Block,item,fn_decl,NodeId,Arm,Pat,Stmt,Expr,Local};
 
 /**
 The region maps encode information about region relationships.
@@ -322,7 +322,7 @@ fn parent_to_expr(visitor: &mut RegionResolutionVisitor,
 }
 
 fn resolve_block(visitor: &mut RegionResolutionVisitor,
-                 blk: &ast::Block,
+                 blk: ast::P<ast::Block>,
                  cx: Context) {
     // Record the parent of this block.
     parent_to_expr(visitor, cx, blk.id, blk.span);
@@ -424,7 +424,7 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor,
 fn resolve_fn(visitor: &mut RegionResolutionVisitor,
               fk: &visit::fn_kind,
               decl: &ast::fn_decl,
-              body: &ast::Block,
+              body: ast::P<ast::Block>,
               sp: Span,
               id: ast::NodeId,
               cx: Context) {
@@ -466,7 +466,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
 
 impl Visitor<Context> for RegionResolutionVisitor {
 
-    fn visit_block(&mut self, b:&Block, cx:Context) {
+    fn visit_block(&mut self, b:P<Block>, cx:Context) {
         resolve_block(self, b, cx);
     }
 
@@ -474,7 +474,7 @@ impl Visitor<Context> for RegionResolutionVisitor {
         resolve_item(self, i, cx);
     }
 
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, cx:Context) {
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<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) {
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 0d4c23d3dfb..74e7a2d9219 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -159,7 +159,7 @@ impl Visitor<()> for Resolver {
     fn visit_arm(&mut self, arm:&Arm, _:()) {
         self.resolve_arm(arm);
     }
-    fn visit_block(&mut self, block:&Block, _:()) {
+    fn visit_block(&mut self, block:P<Block>, _:()) {
         self.resolve_block(block);
     }
     fn visit_expr(&mut self, expr:@Expr, _:()) {
@@ -921,7 +921,7 @@ impl<'self> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'self> {
         self.resolver.build_reduced_graph_for_view_item(view_item, context);
     }
 
-    fn visit_block(&mut self, block:&Block, context:ReducedGraphParent) {
+    fn visit_block(&mut self, block:P<Block>, context:ReducedGraphParent) {
         let np = self.resolver.build_reduced_graph_for_block(block, context);
         visit::walk_block(self, block, np);
     }
@@ -1203,7 +1203,7 @@ impl Resolver {
                 name_bindings.define_type
                     (DefTy(local_def(item.id)), sp, is_public);
 
-                for variant in (*enum_definition).variants.iter() {
+                for &variant in (*enum_definition).variants.iter() {
                     self.build_reduced_graph_for_variant(
                         variant,
                         local_def(item.id),
@@ -1240,7 +1240,7 @@ impl Resolver {
                 new_parent
             }
 
-            item_impl(_, None, ref ty, ref methods) => {
+            item_impl(_, None, ty, ref methods) => {
                 // If this implements an anonymous trait, then add all the
                 // methods within to a new module, if the type was defined
                 // within this module.
@@ -1250,11 +1250,8 @@ impl Resolver {
                 // the same module that declared the type.
 
                 // Create the module and add all methods.
-                match ty {
-                    &Ty {
-                        node: ty_path(ref path, _, _),
-                        ..
-                    } if path.segments.len() == 1 => {
+                match ty.node {
+                    ty_path(ref path, _, _) if path.segments.len() == 1 => {
                         let name = path_to_ident(path);
 
                         let new_parent = match parent.children.find(&name.name) {
@@ -3569,7 +3566,7 @@ impl Resolver {
 
             item_impl(ref generics,
                       ref implemented_traits,
-                      ref self_type,
+                      self_type,
                       ref methods) => {
                 self.resolve_implementation(item.id,
                                             generics,
@@ -3621,10 +3618,10 @@ impl Resolver {
                                     &ty_m.generics.ty_params);
 
                                 for argument in ty_m.decl.inputs.iter() {
-                                    this.resolve_type(&argument.ty);
+                                    this.resolve_type(argument.ty);
                                 }
 
-                                this.resolve_type(&ty_m.decl.output);
+                                this.resolve_type(ty_m.decl.output);
                             });
                           }
                           provided(m) => {
@@ -3676,7 +3673,7 @@ impl Resolver {
                 });
             }
 
-            item_fn(ref fn_decl, _, _, ref generics, ref block) => {
+            item_fn(fn_decl, _, _, ref generics, block) => {
                 self.resolve_function(OpaqueFunctionRibKind,
                                       Some(fn_decl),
                                       HasTypeParameters
@@ -3760,9 +3757,9 @@ impl Resolver {
 
     fn resolve_function(&mut self,
                             rib_kind: RibKind,
-                            optional_declaration: Option<&fn_decl>,
+                            optional_declaration: Option<P<fn_decl>>,
                             type_parameters: TypeParameters,
-                            block: &Block,
+                            block: P<Block>,
                             self_binding: SelfBinding) {
         // Create a value rib for the function.
         let function_value_rib = @Rib::new(rib_kind);
@@ -3811,12 +3808,12 @@ impl Resolver {
                                              binding_mode,
                                              None);
 
-                        this.resolve_type(&argument.ty);
+                        this.resolve_type(argument.ty);
 
                         debug!("(resolving function) recorded argument");
                     }
 
-                    this.resolve_type(&declaration.output);
+                    this.resolve_type(declaration.output);
                 }
             }
 
@@ -3909,7 +3906,7 @@ impl Resolver {
 
             // Resolve fields.
             for field in fields.iter() {
-                this.resolve_type(&field.node.ty);
+                this.resolve_type(field.node.ty);
             }
         });
     }
@@ -3933,9 +3930,9 @@ impl Resolver {
         };
 
         self.resolve_function(rib_kind,
-                              Some(&method.decl),
+                              Some(method.decl),
                               type_parameters,
-                              &method.body,
+                              method.body,
                               self_binding);
     }
 
@@ -3995,7 +3992,7 @@ impl Resolver {
                     self.resolve_function(MethodRibKind(
                                           id,
                                           Provided(method.id)),
-                                          Some(@method.decl),
+                                          Some(method.decl),
                                           HasTypeParameters
                                             (borrowed_type_parameters,
                                              method.id,
@@ -4027,7 +4024,7 @@ impl Resolver {
 
     fn resolve_local(&mut self, local: @Local) {
         // Resolve the type.
-        self.resolve_type(&local.ty);
+        self.resolve_type(local.ty);
 
         // Resolve the initializer, if necessary.
         match local.init {
@@ -4112,12 +4109,12 @@ impl Resolver {
         self.check_consistent_bindings(arm);
 
         visit::walk_expr_opt(self, arm.guard, ());
-        self.resolve_block(&arm.body);
+        self.resolve_block(arm.body);
 
         self.value_ribs.pop();
     }
 
-    fn resolve_block(&mut self, block: &Block) {
+    fn resolve_block(&mut self, block: P<Block>) {
         debug!("(resolving block) entering block");
         self.value_ribs.push(@Rib::new(NormalRibKind));
 
@@ -4374,7 +4371,7 @@ impl Resolver {
                     }
 
                     // Check the types in the path pattern.
-                    for ty in path.segments
+                    for &ty in path.segments
                                   .iter()
                                   .flat_map(|seg| seg.types.iter()) {
                         self.resolve_type(ty);
@@ -4409,7 +4406,7 @@ impl Resolver {
                     }
 
                     // Check the types in the path pattern.
-                    for ty in path.segments
+                    for &ty in path.segments
                                   .iter()
                                   .flat_map(|s| s.types.iter()) {
                         self.resolve_type(ty);
@@ -4446,7 +4443,7 @@ impl Resolver {
                     }
 
                     // Check the types in the path pattern.
-                    for ty in path.segments
+                    for &ty in path.segments
                                   .iter()
                                   .flat_map(|s| s.types.iter()) {
                         self.resolve_type(ty);
@@ -4550,7 +4547,7 @@ impl Resolver {
                     namespace: Namespace,
                     check_ribs: bool) -> Option<(Def, LastPrivate)> {
         // First, resolve the types.
-        for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
+        for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
             self.resolve_type(ty);
         }
 
@@ -5034,8 +5031,8 @@ impl Resolver {
                 visit::walk_expr(self, expr, ());
             }
 
-            ExprFnBlock(ref fn_decl, ref block) |
-            ExprProc(ref fn_decl, ref block) => {
+            ExprFnBlock(fn_decl, block) |
+            ExprProc(fn_decl, block) => {
                 self.resolve_function(FunctionRibKind(expr.id, block.id),
                                       Some(fn_decl),
                                       NoTypeParameters,
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index fe1e2036b92..1ff4d395356 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -84,7 +84,7 @@ impl<'self> Visitor<&'self ScopeChain<'self>> for LifetimeContext {
     fn visit_fn(&mut self,
                 fk: &visit::fn_kind,
                 fd: &ast::fn_decl,
-                b: &ast::Block,
+                b: ast::P<ast::Block>,
                 s: Span,
                 n: ast::NodeId,
                 scope: &'self ScopeChain<'self>) {
@@ -132,7 +132,7 @@ impl<'self> Visitor<&'self ScopeChain<'self>> for LifetimeContext {
     }
 
     fn visit_block(&mut self,
-                   b: &ast::Block,
+                   b: ast::P<ast::Block>,
                    scope: &'self ScopeChain<'self>) {
         let scope1 = BlockScope(b.id, scope);
         debug!("pushing block scope {}", b.id);
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index bd87ab43650..f4479b98e61 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -1935,7 +1935,7 @@ fn trans_match_inner(scope_cx: @mut Block,
         // insert bindings into the lllocals map and add cleanups
         bcx = insert_lllocals(bcx, arm_data.bindings_map, true);
 
-        bcx = controlflow::trans_block(bcx, &arm_data.arm.body, dest);
+        bcx = controlflow::trans_block(bcx, arm_data.arm.body, dest);
         bcx = trans_block_cleanups(bcx, block_cleanups(arm_data.bodycx));
         arm_cxs.push(bcx);
     }
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index ac7b8240176..ac20c3e22f6 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2054,17 +2054,17 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext,
 
 trait IdAndTy {
     fn id(&self) -> ast::NodeId;
-    fn ty<'a>(&'a self) -> &'a ast::Ty;
+    fn ty(&self) -> ast::P<ast::Ty>;
 }
 
 impl IdAndTy for ast::variant_arg {
     fn id(&self) -> ast::NodeId { self.id }
-    fn ty<'a>(&'a self) -> &'a ast::Ty { &self.ty }
+    fn ty(&self) -> ast::P<ast::Ty> { self.ty }
 }
 
 impl IdAndTy for @ast::struct_field {
     fn id(&self) -> ast::NodeId { self.node.id }
-    fn ty<'a>(&'a self) -> &'a ast::Ty { &self.node.ty }
+    fn ty(&self) -> ast::P<ast::Ty> { self.node.ty }
 }
 
 pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
@@ -2078,7 +2078,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
     // Translate variant arguments to function arguments.
     let fn_args = args.map(|varg| {
         ast::arg {
-            ty: (*varg.ty()).clone(),
+            ty: varg.ty(),
             pat: ast_util::ident_to_pat(
                 ccx.tcx.sess.next_node_id(),
                 codemap::dummy_sp(),
@@ -2149,7 +2149,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
 pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
                       id: ast::NodeId, vi: @~[@ty::VariantInfo],
                       i: &mut uint) {
-    for variant in enum_definition.variants.iter() {
+    for &variant in enum_definition.variants.iter() {
         let disr_val = vi[*i].disr_val;
         *i += 1;
 
@@ -2187,7 +2187,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
         _ => fail!("trans_item"),
     };
     match item.node {
-      ast::item_fn(ref decl, purity, _abis, ref generics, ref body) => {
+      ast::item_fn(decl, purity, _abis, ref generics, body) => {
         if purity == ast::extern_fn  {
             let llfndecl = get_item_val(ccx, item.id);
             foreign::trans_rust_fn_with_foreign_abi(
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index b1aa8a1f26a..d0aeafeef07 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -590,12 +590,6 @@ impl Visitor<()> for CalleeTranslationVisitor {
 
 }
 
-pub fn body_contains_ret(body: &ast::Block) -> bool {
-    let mut v = CalleeTranslationVisitor{ flag: false };
-    visit::walk_block(&mut v, body, ());
-    v.flag
-}
-
 pub fn trans_call_inner(in_cx: @mut Block,
                         call_info: Option<NodeInfo>,
                         callee_ty: ty::t,
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index 952854e7d04..bdba95d4fc5 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -47,7 +47,7 @@ pub fn trans_block(bcx: @mut Block, b: &ast::Block, dest: expr::Dest) -> @mut Bl
 
 pub fn trans_if(bcx: @mut Block,
             cond: &ast::Expr,
-            thn: &ast::Block,
+            thn: ast::P<ast::Block>,
             els: Option<@ast::Expr>,
             dest: expr::Dest)
          -> @mut Block {
@@ -142,9 +142,9 @@ pub fn trans_if(bcx: @mut Block,
         let else_bcx_out = match elexpr.node {
             ast::ExprIf(_, _, _) => {
                 let elseif_blk = ast_util::block_from_expr(elexpr);
-                trans_block(else_bcx_in, &elseif_blk, dest)
+                trans_block(else_bcx_in, elseif_blk, dest)
             }
-            ast::ExprBlock(ref blk) => {
+            ast::ExprBlock(blk) => {
                 trans_block(else_bcx_in, blk, dest)
             }
             // would be nice to have a constraint on ifs
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index ad242a9bfe6..04b906a559c 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -554,7 +554,7 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
     let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
         ast_map::node_item(ref item, _) => {
             match item.node {
-                ast::item_fn(ref fn_decl, _, _, ref generics, ref top_level_block) => {
+                ast::item_fn(fn_decl, _, _, ref generics, top_level_block) => {
                     (item.ident, fn_decl, generics, top_level_block, item.span, true)
                 }
                 _ => {
@@ -565,10 +565,10 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
         }
         ast_map::node_method(
             @ast::method {
-                decl: ref fn_decl,
+                decl: fn_decl,
                 ident: ident,
                 generics: ref generics,
-                body: ref top_level_block,
+                body: top_level_block,
                 span: span,
                 ..
             },
@@ -578,8 +578,8 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
         }
         ast_map::node_expr(ref expr) => {
             match expr.node {
-                ast::ExprFnBlock(ref fn_decl, ref top_level_block) |
-                ast::ExprProc(ref fn_decl, ref top_level_block) => {
+                ast::ExprFnBlock(fn_decl, top_level_block) |
+                ast::ExprProc(fn_decl, top_level_block) => {
                     let name = format!("fn{}", token::gensym("fn"));
                     let name = token::str_to_ident(name);
                     (name, fn_decl,
@@ -598,10 +598,10 @@ pub fn create_function_debug_context(cx: &mut CrateContext,
         ast_map::node_trait_method(
             @ast::provided(
                 @ast::method {
-                    decl: ref fn_decl,
+                    decl: fn_decl,
                     ident: ident,
                     generics: ref generics,
-                    body: ref top_level_block,
+                    body: top_level_block,
                     span: span,
                     ..
                 }),
@@ -2554,7 +2554,7 @@ fn populate_scope_map(cx: &mut CrateContext,
                 walk_expr(cx, sub_exp2, scope_stack, scope_map);
             }
 
-            ast::ExprIf(@ref cond_exp, ref then_block, ref opt_else_exp) => {
+            ast::ExprIf(@ref cond_exp, then_block, ref opt_else_exp) => {
                 walk_expr(cx, cond_exp, scope_stack, scope_map);
 
                 with_new_scope(cx,
@@ -2571,7 +2571,7 @@ fn populate_scope_map(cx: &mut CrateContext,
                 }
             }
 
-            ast::ExprWhile(@ref cond_exp, ref loop_body) => {
+            ast::ExprWhile(@ref cond_exp, loop_body) => {
                 walk_expr(cx, cond_exp, scope_stack, scope_map);
 
                 with_new_scope(cx,
@@ -2593,8 +2593,8 @@ fn populate_scope_map(cx: &mut CrateContext,
                                             Found unexpanded macro.");
             }
 
-            ast::ExprLoop(ref block, _) |
-            ast::ExprBlock(ref block)   => {
+            ast::ExprLoop(block, _) |
+            ast::ExprBlock(block)   => {
                 with_new_scope(cx,
                                block.span,
                                scope_stack,
@@ -2604,14 +2604,14 @@ fn populate_scope_map(cx: &mut CrateContext,
                 })
             }
 
-            ast::ExprFnBlock(ast::fn_decl { inputs: ref inputs, .. }, ref block) |
-            ast::ExprProc(ast::fn_decl { inputs: ref inputs, .. }, ref block) => {
+            ast::ExprFnBlock(decl, block) |
+            ast::ExprProc(decl, block) => {
                 with_new_scope(cx,
                                block.span,
                                scope_stack,
                                scope_map,
                                |cx, scope_stack, scope_map| {
-                    for &ast::arg { pat: pattern, .. } in inputs.iter() {
+                    for &ast::arg { pat: pattern, .. } in decl.inputs.iter() {
                         walk_pattern(cx, pattern, scope_stack, scope_map);
                     }
 
@@ -2674,7 +2674,7 @@ fn populate_scope_map(cx: &mut CrateContext,
                             walk_expr(cx, guard_exp, scope_stack, scope_map)
                         }
 
-                        walk_block(cx, &arm_ref.body, scope_stack, scope_map);
+                        walk_block(cx, arm_ref.body, scope_stack, scope_map);
                     })
                 }
             }
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 47bd57e88f5..09218b53424 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -637,10 +637,10 @@ fn trans_rvalue_stmt_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> @mut Block
         ast::ExprRet(ex) => {
             return controlflow::trans_ret(bcx, ex);
         }
-        ast::ExprWhile(cond, ref body) => {
+        ast::ExprWhile(cond, body) => {
             return controlflow::trans_while(bcx, cond, body);
         }
-        ast::ExprLoop(ref body, opt_label) => {
+        ast::ExprLoop(body, opt_label) => {
             // FIXME #6993: map can go away when ast.rs is changed
             return controlflow::trans_loop(bcx, body, opt_label.map(|x| x.name));
         }
@@ -686,13 +686,13 @@ fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: &ast::Expr,
             return trans_def_dps_unadjusted(bcx, expr,
                                             bcx.def(expr.id), dest);
         }
-        ast::ExprIf(cond, ref thn, els) => {
+        ast::ExprIf(cond, thn, els) => {
             return controlflow::trans_if(bcx, cond, thn, els, dest);
         }
         ast::ExprMatch(discr, ref arms) => {
             return _match::trans_match(bcx, expr, discr, *arms, dest);
         }
-        ast::ExprBlock(ref blk) => {
+        ast::ExprBlock(blk) => {
             return base::with_scope(bcx,
                                     blk.info(),
                                     "block-expr body",
@@ -719,8 +719,8 @@ fn trans_rvalue_dps_unadjusted(bcx: @mut Block, expr: &ast::Expr,
         ast::ExprVec(..) | ast::ExprRepeat(..) => {
             return tvec::trans_fixed_vstore(bcx, expr, expr, dest);
         }
-        ast::ExprFnBlock(ref decl, ref body) |
-        ast::ExprProc(ref decl, ref body) => {
+        ast::ExprFnBlock(decl, body) |
+        ast::ExprProc(decl, body) => {
             let expr_ty = expr_ty(bcx, expr);
             let sigil = ty::ty_closure_sigil(expr_ty);
             debug!("translating block function {} with type {}",
diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs
index bbabba3381d..a3f6b7db326 100644
--- a/src/librustc/middle/trans/inline.rs
+++ b/src/librustc/middle/trans/inline.rs
@@ -151,8 +151,8 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::DefId)
               };
               trans_fn(ccx,
                        path,
-                       &mth.decl,
-                       &mth.body,
+                       mth.decl,
+                       mth.body,
                        llfn,
                        self_kind,
                        None,
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 3c4aeb9e762..dff9f55e04c 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -129,8 +129,8 @@ pub fn trans_method(ccx: @mut CrateContext,
     // generate the actual code
     trans_fn(ccx,
              path,
-             &method.decl,
-             &method.body,
+             method.decl,
+             method.body,
              llfn,
              self_arg,
              param_substs,
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 9f26b5c4caf..3350a52e2bc 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -207,7 +207,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
 
     let lldecl = match map_node {
       ast_map::node_item(i@@ast::item {
-                node: ast::item_fn(ref decl, _, _, _, ref body),
+                node: ast::item_fn(decl, _, _, _, body),
                 ..
             }, _) => {
         let d = mk_lldecl();
@@ -232,7 +232,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
                                      ref_id);
           d
       }
-      ast_map::node_variant(ref v, enum_item, _) => {
+      ast_map::node_variant(v, enum_item, _) => {
         let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
         let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
         let d = mk_lldecl();
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index cabe65b097b..a557332c8de 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3868,7 +3868,7 @@ pub fn enum_variants(cx: ctxt, id: ast::DefId) -> @~[@VariantInfo] {
                     ..
                 }, _) => {
             let mut last_discriminant: Option<Disr> = None;
-            @enum_definition.variants.iter().map(|variant| {
+            @enum_definition.variants.iter().map(|&variant| {
 
                 let mut discriminant = match last_discriminant {
                     Some(val) => val + 1,
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 74a51f1dbce..26b9a1b25d5 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -208,7 +208,7 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>(
     let tps = path.segments
                   .iter()
                   .flat_map(|s| s.types.iter())
-                  .map(|a_t| ast_ty_to_ty(this, rscope, a_t))
+                  .map(|&a_t| ast_ty_to_ty(this, rscope, a_t))
                   .collect();
 
     substs {
@@ -413,7 +413,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                    |tmt| ty::mk_rptr(tcx, r, tmt))
       }
       ast::ty_tup(ref fields) => {
-        let flds = fields.map(|t| ast_ty_to_ty(this, rscope, t));
+        let flds = fields.map(|&t| ast_ty_to_ty(this, rscope, t));
         ty::mk_tup(tcx, flds)
       }
       ast::ty_bare_fn(ref bf) => {
@@ -421,7 +421,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
             tcx.sess.span_err(ast_ty.span, "variadic function must have C calling convention");
           }
           ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.purity,
-                                            bf.abis, &bf.decl))
+                                            bf.abis, bf.decl))
       }
       ast::ty_closure(ref f) => {
         if f.sigil == ast::ManagedSigil {
@@ -444,7 +444,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
                                       f.onceness,
                                       bounds,
                                       &f.region,
-                                      &f.decl,
+                                      f.decl,
                                       None,
                                       ast_ty.span);
           ty::mk_closure(tcx, fn_decl)
@@ -583,7 +583,7 @@ pub fn ty_of_arg<AC:AstConv,
     match a.ty.node {
         ast::ty_infer if expected_ty.is_some() => expected_ty.unwrap(),
         ast::ty_infer => this.ty_infer(a.ty.span),
-        _ => ast_ty_to_ty(this, rscope, &a.ty),
+        _ => ast_ty_to_ty(this, rscope, a.ty),
     }
 }
 
@@ -643,7 +643,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(
 
     let output_ty = match decl.output.node {
         ast::ty_infer => this.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(this, &rb, &decl.output)
+        _ => ast_ty_to_ty(this, &rb, decl.output)
     };
 
     return (opt_transformed_self_ty,
@@ -743,7 +743,7 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
     let output_ty = match decl.output.node {
         ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(),
         ast::ty_infer => this.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(this, &rb, &decl.output)
+        _ => ast_ty_to_ty(this, &rb, decl.output)
     };
 
     ty::ClosureTy {
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 809f465fb28..2e2d2232421 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -72,7 +72,7 @@ pub fn check_match(fcx: @mut FnCtxt,
           },
           None => ()
         }
-        check_block(fcx, &arm.body);
+        check_block(fcx, arm.body);
         let bty = fcx.node_ty(arm.body.id);
         saw_err = saw_err || ty::type_is_error(bty);
         if guard_err {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 8caf873a889..37934ca13b3 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -316,7 +316,7 @@ pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) {
 
 pub fn check_bare_fn(ccx: @mut CrateCtxt,
                      decl: &ast::fn_decl,
-                     body: &ast::Block,
+                     body: ast::P<ast::Block>,
                      id: ast::NodeId,
                      self_info: Option<SelfInfo>,
                      fty: ty::t,
@@ -364,7 +364,7 @@ impl Visitor<()> for GatherLocalsVisitor {
     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))
+              _ => Some(self.fcx.to_ty(local.ty))
             };
             self.assign(local.id, o_ty);
             debug!("Local variable {} is assigned type {}",
@@ -391,7 +391,7 @@ impl Visitor<()> for GatherLocalsVisitor {
 
     }
 
-    fn visit_block(&mut self, b:&ast::Block, _:()) {
+    fn visit_block(&mut self, b:ast::P<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.
@@ -400,7 +400,7 @@ impl Visitor<()> for GatherLocalsVisitor {
 
         // Don't descend into fns and items
     fn visit_fn(&mut self, _:&visit::fn_kind, _:&ast::fn_decl,
-                _:&ast::Block, _:Span, _:ast::NodeId, _:()) { }
+                _:ast::P<ast::Block>, _:Span, _:ast::NodeId, _:()) { }
     fn visit_item(&mut self, _:@ast::item, _:()) { }
 
 }
@@ -411,7 +411,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
                 fn_sig: &ty::FnSig,
                 decl: &ast::fn_decl,
                 id: ast::NodeId,
-                body: &ast::Block,
+                body: ast::P<ast::Block>,
                 fn_kind: FnKind,
                 inherited: @Inherited) -> @mut FnCtxt
 {
@@ -497,7 +497,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
 
     fn gather_locals(fcx: @mut FnCtxt,
                      decl: &ast::fn_decl,
-                     body: &ast::Block,
+                     body: ast::P<ast::Block>,
                      arg_tys: &[ty::t],
                      opt_self_info: Option<SelfInfo>) {
         let tcx = fcx.ccx.tcx;
@@ -579,7 +579,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
                             enum_definition.variants,
                             it.id);
       }
-      ast::item_fn(ref decl, _, _, _, ref body) => {
+      ast::item_fn(decl, _, _, _, body) => {
         let fn_tpt = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
 
         // FIXME(#5121) -- won't work for lifetimes that appear in type bounds
@@ -712,8 +712,8 @@ fn check_method_body(ccx: @mut CrateCtxt,
 
     check_bare_fn(
         ccx,
-        &method.decl,
-        &method.body,
+        method.decl,
+        method.body,
         method.id,
         opt_self_info,
         fty,
@@ -1908,7 +1908,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                          rcvr: @ast::Expr,
                          method_name: ast::Ident,
                          args: &[@ast::Expr],
-                         tps: &[ast::Ty],
+                         tps: &[ast::P<ast::Ty>],
                          sugar: ast::CallSugar) {
         check_expr(fcx, rcvr);
 
@@ -1917,7 +1917,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                                                 expr.span,
                                                 fcx.expr_ty(rcvr));
 
-        let tps = tps.map(|ast_ty| fcx.to_ty(ast_ty));
+        let tps = tps.map(|&ast_ty| fcx.to_ty(ast_ty));
         match method::lookup(fcx,
                              expr,
                              rcvr,
@@ -2214,7 +2214,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                      expr: @ast::Expr,
                      ast_sigil_opt: Option<ast::Sigil>,
                      decl: &ast::fn_decl,
-                     body: &ast::Block,
+                     body: ast::P<ast::Block>,
                      fn_kind: FnKind,
                      expected: Option<ty::t>) {
         let tcx = fcx.ccx.tcx;
@@ -2308,7 +2308,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                    expr: @ast::Expr,
                    base: @ast::Expr,
                    field: ast::Name,
-                   tys: &[ast::Ty]) {
+                   tys: &[ast::P<ast::Ty>]) {
         let tcx = fcx.ccx.tcx;
         let bot = check_expr(fcx, base);
         let expr_t = structurally_resolved_type(fcx, expr.span,
@@ -2338,7 +2338,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
             _ => ()
         }
 
-        let tps : ~[ty::t] = tys.iter().map(|ty| fcx.to_ty(ty)).collect();
+        let tps : ~[ty::t] = tys.iter().map(|&ty| fcx.to_ty(ty)).collect();
         match method::lookup(fcx,
                              expr,
                              base,
@@ -2871,11 +2871,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
             fcx.write_nil(id);
         }
       }
-      ast::ExprIf(cond, ref then_blk, opt_else_expr) => {
+      ast::ExprIf(cond, then_blk, opt_else_expr) => {
         check_then_else(fcx, cond, then_blk, opt_else_expr,
                         id, expr.span, expected);
       }
-      ast::ExprWhile(cond, ref body) => {
+      ast::ExprWhile(cond, body) => {
         check_expr_has_type(fcx, cond, ty::mk_bool());
         check_block_no_value(fcx, body);
         let cond_ty = fcx.expr_ty(cond);
@@ -2892,7 +2892,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
       }
       ast::ExprForLoop(..) =>
           fail!("non-desugared expr_for_loop"),
-      ast::ExprLoop(ref body, _) => {
+      ast::ExprLoop(body, _) => {
         check_block_no_value(fcx, (body));
         if !may_break(tcx, expr.id, body) {
             fcx.write_bot(id);
@@ -2904,7 +2904,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
       ast::ExprMatch(discrim, ref arms) => {
         _match::check_match(fcx, expr, discrim, *arms);
       }
-      ast::ExprFnBlock(ref decl, ref body) => {
+      ast::ExprFnBlock(decl, body) => {
         check_expr_fn(fcx,
                       expr,
                       Some(ast::BorrowedSigil),
@@ -2913,7 +2913,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                       Vanilla,
                       expected);
       }
-      ast::ExprProc(ref decl, ref body) => {
+      ast::ExprProc(decl, body) => {
         check_expr_fn(fcx,
                       expr,
                       Some(ast::OwnedSigil),
@@ -2950,7 +2950,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
             }
         };
         match b.node {
-          ast::ExprFnBlock(ref decl, ref body) => {
+          ast::ExprFnBlock(decl, body) => {
             check_expr_fn(fcx, b, None,
                           decl, body, DoBlock, Some(inner_ty));
             demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
@@ -2960,7 +2960,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         }
         fcx.write_ty(expr.id, fcx.node_ty(b.id));
       }
-      ast::ExprBlock(ref b) => {
+      ast::ExprBlock(b) => {
         check_block_with_expected(fcx, b, expected);
         fcx.write_ty(id, fcx.node_ty(b.id));
       }
@@ -2995,7 +2995,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
             fcx.write_bot(id);
         }
       }
-      ast::ExprCast(e, ref t) => {
+      ast::ExprCast(e, t) => {
         check_expr(fcx, e);
         let t_1 = fcx.to_ty(t);
         let t_e = fcx.expr_ty(e);
@@ -3493,7 +3493,7 @@ pub fn check_simd(tcx: ty::ctxt, sp: Span, id: ast::NodeId) {
 
 pub fn check_enum_variants(ccx: @mut CrateCtxt,
                            sp: Span,
-                           vs: &[ast::variant],
+                           vs: &[ast::P<ast::variant>],
                            id: ast::NodeId) {
 
     fn disr_in_range(ccx: @mut CrateCtxt,
@@ -3524,7 +3524,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
     }
 
     fn do_check(ccx: @mut CrateCtxt,
-                vs: &[ast::variant],
+                vs: &[ast::P<ast::variant>],
                 id: ast::NodeId,
                 hint: attr::ReprAttr)
                 -> ~[@ty::VariantInfo] {
@@ -3534,7 +3534,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
         let mut disr_vals: ~[ty::Disr] = ~[];
         let mut prev_disr_val: Option<ty::Disr> = None;
 
-        for v in vs.iter() {
+        for &v in vs.iter() {
 
             // If the discriminant value is specified explicitly in the enum check whether the
             // initialization expression is valid, otherwise use the last value plus one.
@@ -3765,7 +3765,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
         // at the appropriate position.
         let mut result = ~[];
         let mut pushed = false;
-        for (i, ast_type) in pth.segments
+        for (i, &ast_type) in pth.segments
                                 .iter()
                                 .flat_map(|segment| segment.types.iter())
                                 .enumerate() {
@@ -3870,7 +3870,7 @@ pub fn ast_expr_vstore_to_vstore(fcx: @mut FnCtxt,
 }
 
 // Returns true if b contains a break that can exit from b
-pub fn may_break(cx: ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
+pub fn may_break(cx: ty::ctxt, id: ast::NodeId, b: ast::P<ast::Block>) -> bool {
     // First: is there an unlabeled break immediately
     // inside the loop?
     (loop_query(b, |e| {
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 57781fbe6cc..10120a69c31 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -152,7 +152,7 @@ pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::Expr) {
     fcx.infcx().resolve_regions();
 }
 
-pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::Block) {
+pub fn regionck_fn(fcx: @mut FnCtxt, blk: ast::P<ast::Block>) {
     let mut rcx = Rcx { fcx: fcx, errors_reported: 0,
                          repeating_scope: blk.id };
     let rcx = &mut rcx;
@@ -182,14 +182,14 @@ impl Visitor<()> for Rcx {
 
     fn visit_local(&mut self, l:@ast::Local, _:()) { visit_local(self, l); }
 
-    fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(self, b); }
+    fn visit_block(&mut self, b:ast::P<ast::Block>, _:()) { visit_block(self, b); }
 }
 
 fn visit_item(_rcx: &mut Rcx, _item: @ast::item) {
     // Ignore items
 }
 
-fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
+fn visit_block(rcx: &mut Rcx, b: ast::P<ast::Block>) {
     rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id);
     visit::walk_block(rcx, b, ());
 }
@@ -431,13 +431,13 @@ fn visit_expr(rcx: &mut Rcx, expr: @ast::Expr) {
             check_expr_fn_block(rcx, expr);
         }
 
-        ast::ExprLoop(ref body, _) => {
+        ast::ExprLoop(body, _) => {
             let repeating_scope = rcx.set_repeating_scope(body.id);
             visit::walk_expr(rcx, expr, ());
             rcx.set_repeating_scope(repeating_scope);
         }
 
-        ast::ExprWhile(cond, ref body) => {
+        ast::ExprWhile(cond, body) => {
             let repeating_scope = rcx.set_repeating_scope(cond.id);
             rcx.visit_expr(cond, ());
 
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index abdab02dedd..6e588faeaf7 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -788,7 +788,7 @@ impl visit::Visitor<()> for @mut FnCtxt {
 
 // Detect points where a trait-bounded type parameter is
 // instantiated, resolve the impls for the parameters.
-pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) {
+pub fn resolve_in_block(fcx: @mut FnCtxt, bl: ast::P<ast::Block>) {
     let mut fcx = fcx;
     visit::walk_block(&mut fcx, bl, ());
 }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index e2da054527c..93463f507c7 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -269,7 +269,7 @@ fn visit_expr(e: @ast::Expr, wbcx: &mut WbCtxt) {
     visit::walk_expr(wbcx, e, ());
 }
 
-fn visit_block(b: &ast::Block, wbcx: &mut WbCtxt) {
+fn visit_block(b: ast::P<ast::Block>, wbcx: &mut WbCtxt) {
     if !wbcx.success {
         return;
     }
@@ -322,7 +322,7 @@ impl Visitor<()> for WbCtxt {
     fn visit_item(&mut self, i:@ast::item, _:()) { visit_item(i, self); }
     fn visit_stmt(&mut self, s:@ast::Stmt, _:()) { visit_stmt(s, self); }
     fn visit_expr(&mut self, ex:@ast::Expr, _:()) { visit_expr(ex, self); }
-    fn visit_block(&mut self, b:&ast::Block, _:()) { visit_block(b, self); }
+    fn visit_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); }
 }
@@ -336,7 +336,7 @@ pub fn resolve_type_vars_in_expr(fcx: @mut FnCtxt, e: @ast::Expr) -> bool {
 
 pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt,
                                decl: &ast::fn_decl,
-                               blk: &ast::Block,
+                               blk: ast::P<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 f7a1662ca12..a0264848b47 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -190,7 +190,7 @@ impl visit::Visitor<()> for PrivilegedScopeVisitor {
                         // Then visit the module items.
                         visit::walk_mod(self, module_, ());
                     }
-                    item_impl(_, None, ref ast_ty, _) => {
+                    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;
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 11cbcd4cbdd..bb0e1d42ac6 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -134,7 +134,7 @@ impl AstConv for CrateCtxt {
 
 pub fn get_enum_variant_types(ccx: &CrateCtxt,
                               enum_ty: ty::t,
-                              variants: &[ast::variant],
+                              variants: &[ast::P<ast::variant>],
                               generics: &ast::Generics) {
     let tcx = ccx.tcx;
 
@@ -146,7 +146,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
         let result_ty = match variant.node.kind {
             ast::tuple_variant_kind(ref args) if args.len() > 0 => {
                 let rs = ExplicitRscope;
-                let input_tys = args.map(|va| ccx.to_ty(&rs, &va.ty));
+                let input_tys = args.map(|va| ccx.to_ty(&rs, va.ty));
                 ty::mk_ctor_fn(tcx, scope, input_tys, enum_ty)
             }
 
@@ -197,14 +197,14 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
                         ty_method_of_trait_method(
                             ccx, trait_id, &trait_ty_generics,
                             &m.id, &m.ident, &m.explicit_self,
-                            &m.generics, &m.purity, &m.decl)
+                            &m.generics, &m.purity, m.decl)
                     }
 
                     &ast::provided(ref m) => {
                         ty_method_of_trait_method(
                             ccx, trait_id, &trait_ty_generics,
                             &m.id, &m.ident, &m.explicit_self,
-                            &m.generics, &m.purity, &m.decl)
+                            &m.generics, &m.purity, m.decl)
                     }
                 };
 
@@ -414,7 +414,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt,
 pub fn convert_field(ccx: &CrateCtxt,
                      struct_generics: &ty::Generics,
                      v: &ast::struct_field) {
-    let tt = ccx.to_ty(&ExplicitRscope, &v.node.ty);
+    let tt = ccx.to_ty(&ExplicitRscope, v.node.ty);
     write_ty_to_tcx(ccx.tcx, v.node.id, tt);
     /* add the field to the tcache */
     ccx.tcx.tcache.insert(local_def(v.node.id),
@@ -475,7 +475,7 @@ fn convert_methods(ccx: &CrateCtxt,
         let (transformed_self_ty, fty) =
             astconv::ty_of_method(ccx, m.id, m.purity,
                                   untransformed_rcvr_ty,
-                                  m.explicit_self, &m.decl);
+                                  m.explicit_self, m.decl);
 
         // if the method specifies a visibility, use that, otherwise
         // inherit the visibility from the impl (so `foo` in `pub impl
@@ -528,7 +528,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
                                  enum_definition.variants,
                                  generics);
       }
-      ast::item_impl(ref generics, ref opt_trait_ref, ref selfty, ref ms) => {
+      ast::item_impl(ref generics, ref opt_trait_ref, selfty, ref ms) => {
         let i_ty_generics = ty_generics(ccx, generics, 0);
         let selfty = ccx.to_ty(&ExplicitRscope, selfty);
         write_ty_to_tcx(tcx, it.id, selfty);
@@ -755,13 +755,13 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item)
         _ => {}
     }
     match it.node {
-        ast::item_static(ref t, _, _) => {
+        ast::item_static(t, _, _) => {
             let typ = ccx.to_ty(&ExplicitRscope, t);
             let tpt = no_params(typ);
             tcx.tcache.insert(local_def(it.id), tpt);
             return tpt;
         }
-        ast::item_fn(ref decl, purity, abi, ref generics, _) => {
+        ast::item_fn(decl, purity, abi, ref generics, _) => {
             let ty_generics = ty_generics(ccx, generics, 0);
             let tofd = astconv::ty_of_bare_fn(ccx,
                                               it.id,
@@ -782,7 +782,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item)
             ccx.tcx.tcache.insert(local_def(it.id), tpt);
             return tpt;
         }
-        ast::item_ty(ref t, ref generics) => {
+        ast::item_ty(t, ref generics) => {
             match tcx.tcache.find(&local_def(it.id)) {
                 Some(&tpt) => return tpt,
                 None => { }
@@ -838,14 +838,14 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
                           abis: AbiSet) -> ty::ty_param_bounds_and_ty
 {
     match it.node {
-        ast::foreign_item_fn(ref fn_decl, ref generics) => {
+        ast::foreign_item_fn(fn_decl, ref generics) => {
             ty_of_foreign_fn_decl(ccx,
                                   fn_decl,
                                   local_def(it.id),
                                   generics,
                                   abis)
         }
-        ast::foreign_item_static(ref t, _) => {
+        ast::foreign_item_static(t, _) => {
             ty::ty_param_bounds_and_ty {
                 generics: ty::Generics {
                     type_param_defs: @~[],
@@ -935,7 +935,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
     let ty_generics = ty_generics(ccx, ast_generics, 0);
     let rb = BindingRscope::new(def_id.node);
     let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, a, None) );
-    let output_ty = ast_ty_to_ty(ccx, &rb, &decl.output);
+    let output_ty = ast_ty_to_ty(ccx, &rb, decl.output);
 
     let t_fn = ty::mk_bare_fn(
         ccx.tcx,
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 95fe4ec34c6..84dff19e452 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -449,7 +449,7 @@ impl<'self> Visitor<()> for ConstraintContext<'self> {
                 // `ty::VariantInfo::from_ast_variant()` ourselves
                 // here, mainly so as to mask the differences between
                 // struct-like enums and so forth.
-                for ast_variant in enum_definition.variants.iter() {
+                for &ast_variant in enum_definition.variants.iter() {
                     let variant =
                         ty::VariantInfo::from_ast_variant(tcx,
                                                           ast_variant,
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index a0823a584c3..643e0440860 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -79,7 +79,7 @@ impl<'self> Visitor<()> for LoopQueryVisitor<'self> {
 
 // 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::Block, p: |&ast::Expr_| -> bool) -> bool {
+pub fn loop_query(b: ast::P<ast::Block>, p: |&ast::Expr_| -> bool) -> bool {
     let mut v = LoopQueryVisitor {
         p: p,
         flag: false,
@@ -102,7 +102,7 @@ impl<'self> Visitor<()> for BlockQueryVisitor<'self> {
 
 // 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::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,
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 835781907f3..93d1db447e7 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -115,7 +115,7 @@ pub struct Function {
 }
 
 pub struct Typedef {
-    ty: ast::Ty,
+    ty: ast::P<ast::Ty>,
     gen: ast::Generics,
     name: Ident,
     id: ast::NodeId,
@@ -125,7 +125,7 @@ pub struct Typedef {
 }
 
 pub struct Static {
-    type_: ast::Ty,
+    type_: ast::P<ast::Ty>,
     mutability: ast::Mutability,
     expr: @ast::Expr,
     name: Ident,
@@ -149,7 +149,7 @@ pub struct Trait {
 pub struct Impl {
     generics: ast::Generics,
     trait_: Option<ast::trait_ref>,
-    for_: ast::Ty,
+    for_: ast::P<ast::Ty>,
     methods: ~[@ast::method],
     attrs: ~[ast::Attribute],
     where: Span,
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 79ab752f295..1a4a9a0aee8 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -121,11 +121,11 @@ impl RustdocVisitor {
                 },
                 ast::item_enum(ref ed, ref gen) => om.enums.push(visit_enum_def(item, ed, gen)),
                 ast::item_struct(sd, ref gen) => om.structs.push(visit_struct_def(item, sd, gen)),
-                ast::item_fn(ref fd, ref pur, ref abi, ref gen, _) =>
+                ast::item_fn(fd, ref pur, ref abi, ref gen, _) =>
                     om.fns.push(visit_fn(item, fd, pur, abi, gen)),
-                ast::item_ty(ref ty, ref gen) => {
+                ast::item_ty(ty, ref gen) => {
                     let t = Typedef {
-                        ty: ty.clone(),
+                        ty: ty,
                         gen: gen.clone(),
                         name: item.ident,
                         id: item.id,
@@ -135,9 +135,9 @@ impl RustdocVisitor {
                     };
                     om.typedefs.push(t);
                 },
-                ast::item_static(ref ty, ref mut_, ref exp) => {
+                ast::item_static(ty, ref mut_, ref exp) => {
                     let s = Static {
-                        type_: ty.clone(),
+                        type_: ty,
                         mutability: mut_.clone(),
                         expr: exp.clone(),
                         id: item.id,
@@ -161,11 +161,11 @@ impl RustdocVisitor {
                     };
                     om.traits.push(t);
                 },
-                ast::item_impl(ref gen, ref tr, ref ty, ref meths) => {
+                ast::item_impl(ref gen, ref tr, ty, ref meths) => {
                     let i = Impl {
                         generics: gen.clone(),
                         trait_: tr.clone(),
-                        for_: ty.clone(),
+                        for_: ty,
                         methods: meths.clone(),
                         attrs: item.attrs.clone(),
                         id: item.id,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 7bde8083b50..aebb5303cd4 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -20,6 +20,13 @@ use std::option::Option;
 use std::to_str::ToStr;
 use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
 
+/// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
+pub type P<T> = @T;
+
+/// Construct a P<T> from a T value.
+pub fn P<T: 'static>(value: T) -> P<T> {
+    @value
+}
 
 // FIXME #6993: in librustc, uses of "ident" should be replaced
 // by just "Name".
@@ -160,7 +167,7 @@ pub struct PathSegment {
     /// The lifetime parameters for this path segment.
     lifetimes: OptVec<Lifetime>,
     /// The type parameters for this path segment, if present.
-    types: OptVec<Ty>,
+    types: OptVec<P<Ty>>,
 }
 
 pub type CrateNum = u32;
@@ -460,7 +467,7 @@ pub enum Stmt_ {
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
 #[deriving(Eq, Encodable, Decodable,IterBytes)]
 pub struct Local {
-    ty: Ty,
+    ty: P<Ty>,
     pat: @Pat,
     init: Option<@Expr>,
     id: NodeId,
@@ -481,7 +488,7 @@ pub enum Decl_ {
 pub struct Arm {
     pats: ~[@Pat],
     guard: Option<@Expr>,
-    body: Block,
+    body: P<Block>,
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
@@ -537,28 +544,28 @@ pub enum Expr_ {
     ExprVstore(@Expr, ExprVstore),
     ExprVec(~[@Expr], Mutability),
     ExprCall(@Expr, ~[@Expr], CallSugar),
-    ExprMethodCall(NodeId, @Expr, Ident, ~[Ty], ~[@Expr], CallSugar),
+    ExprMethodCall(NodeId, @Expr, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
     ExprTup(~[@Expr]),
     ExprBinary(NodeId, BinOp, @Expr, @Expr),
     ExprUnary(NodeId, UnOp, @Expr),
     ExprLit(@lit),
-    ExprCast(@Expr, Ty),
-    ExprIf(@Expr, Block, Option<@Expr>),
-    ExprWhile(@Expr, Block),
+    ExprCast(@Expr, P<Ty>),
+    ExprIf(@Expr, P<Block>, Option<@Expr>),
+    ExprWhile(@Expr, P<Block>),
     // FIXME #6993: change to Option<Name>
-    ExprForLoop(@Pat, @Expr, Block, Option<Ident>),
+    ExprForLoop(@Pat, @Expr, P<Block>, Option<Ident>),
     // Conditionless loop (can be exited with break, cont, or ret)
     // FIXME #6993: change to Option<Name>
-    ExprLoop(Block, Option<Ident>),
+    ExprLoop(P<Block>, Option<Ident>),
     ExprMatch(@Expr, ~[Arm]),
-    ExprFnBlock(fn_decl, Block),
-    ExprProc(fn_decl, Block),
+    ExprFnBlock(P<fn_decl>, P<Block>),
+    ExprProc(P<fn_decl>, P<Block>),
     ExprDoBody(@Expr),
-    ExprBlock(Block),
+    ExprBlock(P<Block>),
 
     ExprAssign(@Expr, @Expr),
     ExprAssignOp(NodeId, BinOp, @Expr, @Expr),
-    ExprField(@Expr, Ident, ~[Ty]),
+    ExprField(@Expr, Ident, ~[P<Ty>]),
     ExprIndex(NodeId, @Expr, @Expr),
 
     /// Expression that looks like a "name". For example,
@@ -727,7 +734,7 @@ pub enum lit_ {
 // type structure in middle/ty.rs as well.
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct mt {
-    ty: ~Ty,
+    ty: P<Ty>,
     mutbl: Mutability,
 }
 
@@ -743,7 +750,7 @@ pub struct TypeMethod {
     ident: Ident,
     attrs: ~[Attribute],
     purity: purity,
-    decl: fn_decl,
+    decl: P<fn_decl>,
     generics: Generics,
     explicit_self: explicit_self,
     id: NodeId,
@@ -842,7 +849,7 @@ pub struct TyClosure {
     lifetimes: OptVec<Lifetime>,
     purity: purity,
     onceness: Onceness,
-    decl: fn_decl,
+    decl: P<fn_decl>,
     // Optional optvec distinguishes between "fn()" and "fn:()" so we can
     // implement issue #7264. None means "fn()", which means infer a default
     // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
@@ -855,7 +862,7 @@ pub struct TyBareFn {
     purity: purity,
     abis: AbiSet,
     lifetimes: OptVec<Lifetime>,
-    decl: fn_decl
+    decl: P<fn_decl>
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
@@ -870,7 +877,7 @@ pub enum ty_ {
     ty_rptr(Option<Lifetime>, mt),
     ty_closure(@TyClosure),
     ty_bare_fn(@TyBareFn),
-    ty_tup(~[Ty]),
+    ty_tup(~[P<Ty>]),
     ty_path(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
     ty_typeof(@Expr),
     // ty_infer means the type should be inferred instead of it having been
@@ -899,7 +906,7 @@ pub struct inline_asm {
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct arg {
-    ty: Ty,
+    ty: P<Ty>,
     pat: @Pat,
     id: NodeId,
 }
@@ -907,7 +914,7 @@ pub struct arg {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct fn_decl {
     inputs: ~[arg],
-    output: Ty,
+    output: P<Ty>,
     cf: ret_style,
     variadic: bool
 }
@@ -954,8 +961,8 @@ pub struct method {
     generics: Generics,
     explicit_self: explicit_self,
     purity: purity,
-    decl: fn_decl,
-    body: Block,
+    decl: P<fn_decl>,
+    body: P<Block>,
     id: NodeId,
     span: Span,
     self_id: NodeId,
@@ -977,7 +984,7 @@ pub struct foreign_mod {
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct variant_arg {
-    ty: Ty,
+    ty: P<Ty>,
     id: NodeId,
 }
 
@@ -989,7 +996,7 @@ pub enum variant_kind {
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct enum_def {
-    variants: ~[variant],
+    variants: ~[P<variant>],
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
@@ -1102,7 +1109,7 @@ impl visibility {
 pub struct struct_field_ {
     kind: struct_field_kind,
     id: NodeId,
-    ty: Ty,
+    ty: P<Ty>,
     attrs: ~[Attribute],
 }
 
@@ -1138,17 +1145,17 @@ pub struct item {
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum item_ {
-    item_static(Ty, Mutability, @Expr),
-    item_fn(fn_decl, purity, AbiSet, Generics, Block),
+    item_static(P<Ty>, Mutability, @Expr),
+    item_fn(P<fn_decl>, purity, AbiSet, Generics, P<Block>),
     item_mod(_mod),
     item_foreign_mod(foreign_mod),
-    item_ty(Ty, Generics),
+    item_ty(P<Ty>, Generics),
     item_enum(enum_def, Generics),
     item_struct(@struct_def, Generics),
     item_trait(Generics, ~[trait_ref], ~[trait_method]),
     item_impl(Generics,
               Option<trait_ref>, // (optional) trait this impl implements
-              Ty, // self
+              P<Ty>, // self
               ~[@method]),
     // a macro invocation (which includes macro definition)
     item_mac(mac),
@@ -1166,8 +1173,8 @@ pub struct foreign_item {
 
 #[deriving(Eq, Encodable, Decodable,IterBytes)]
 pub enum foreign_item_ {
-    foreign_item_fn(fn_decl, Generics),
-    foreign_item_static(Ty, /* is_mutbl */ bool),
+    foreign_item_fn(P<fn_decl>, Generics),
+    foreign_item_static(P<Ty>, /* is_mutbl */ bool),
 }
 
 // The data we save and restore about an inlined item or method.  This is not
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index aed6af3d7ed..961d8170fd3 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -115,12 +115,12 @@ pub enum ast_node {
     /// node_variant represents a variant of an enum, e.g., for
     /// `enum A { B, C, D }`, there would be a node_item for `A`, and a
     /// node_variant item for each of `B`, `C`, and `D`.
-    node_variant(variant, @item, @path),
+    node_variant(P<variant>, @item, @path),
     node_expr(@Expr),
     node_stmt(@Stmt),
     node_arg(@Pat),
     node_local(Ident),
-    node_block(Block),
+    node_block(P<Block>),
 
     /// node_struct_ctor represents a tuple struct.
     node_struct_ctor(@struct_def, @item, @path),
@@ -214,7 +214,7 @@ impl Ctx {
     fn map_fn(&mut self,
               fk: &visit::fn_kind,
               decl: &fn_decl,
-              body: &Block,
+              body: P<Block>,
               sp: codemap::Span,
               id: NodeId) {
         for a in decl.inputs.iter() {
@@ -236,9 +236,8 @@ impl Ctx {
         visit::walk_stmt(self, stmt, ());
     }
 
-    fn map_block(&mut self, b: &Block) {
-        // clone is FIXME #2543
-        self.map.insert(b.id, node_block((*b).clone()));
+    fn map_block(&mut self, b: P<Block>) {
+        self.map.insert(b.id, node_block(b));
         visit::walk_block(self, b, ());
     }
 
@@ -262,7 +261,7 @@ impl Visitor<()> for Ctx {
         let item_path = @self.path.clone();
         self.map.insert(i.id, node_item(i, item_path));
         match i.node {
-            item_impl(_, ref maybe_trait, ref ty, ref ms) => {
+            item_impl(_, ref maybe_trait, ty, ref ms) => {
                 // Right now the ident on impls is __extensions__ which isn't
                 // very pretty when debugging, so attempt to select a better
                 // name to use.
@@ -277,13 +276,10 @@ impl Visitor<()> for Ctx {
                 self.path.push(elt);
             }
             item_enum(ref enum_definition, _) => {
-                for v in (*enum_definition).variants.iter() {
+                for &v in enum_definition.variants.iter() {
                     let elt = path_name(i.ident);
-                    // FIXME #2543: bad clone
                     self.map.insert(v.node.id,
-                                    node_variant((*v).clone(),
-                                                 i,
-                                                 self.extend(elt)));
+                                    node_variant(v, i, self.extend(elt)));
                 }
             }
             item_foreign_mod(ref nm) => {
@@ -361,14 +357,14 @@ impl Visitor<()> for Ctx {
     fn visit_fn(&mut self,
                 function_kind: &fn_kind,
                 function_declaration: &fn_decl,
-                block: &Block,
+                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: &Block, _: ()) {
+    fn visit_block(&mut self, block: P<Block>, _: ()) {
         self.map_block(block)
     }
 
@@ -477,7 +473,7 @@ pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str {
       Some(&node_local(ident)) => {
         format!("local (id={}, name={})", id, itr.get(ident.name))
       }
-      Some(&node_block(ref block)) => {
+      Some(&node_block(block)) => {
         format!("block {} (id={})", pprust::block_to_str(block, itr), id)
       }
       Some(&node_struct_ctor(_, _, path)) => {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index dcb15ad85df..094ad7afea6 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -11,7 +11,7 @@
 use ast::*;
 use ast;
 use ast_util;
-use codemap::{Span, dummy_sp};
+use codemap::Span;
 use opt_vec;
 use parse::token;
 use visit::Visitor;
@@ -21,7 +21,6 @@ use std::hashmap::HashMap;
 use std::u32;
 use std::local_data;
 use std::num;
-use std::option;
 
 pub fn path_name_i(idents: &[Ident]) -> ~str {
     // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
@@ -197,25 +196,15 @@ pub fn is_call_expr(e: @Expr) -> bool {
     match e.node { ExprCall(..) => true, _ => false }
 }
 
-pub fn block_from_expr(e: @Expr) -> Block {
-    let mut blk = default_block(~[], option::Some::<@Expr>(e), e.id);
-    blk.span = e.span;
-    return blk;
-}
-
-pub fn default_block(
-    stmts1: ~[@Stmt],
-    expr1: Option<@Expr>,
-    id1: NodeId
-) -> Block {
-    ast::Block {
+pub fn block_from_expr(e: @Expr) -> P<Block> {
+    P(Block {
         view_items: ~[],
-        stmts: stmts1,
-        expr: expr1,
-        id: id1,
+        stmts: ~[],
+        expr: Some(e),
+        id: e.id,
         rules: DefaultBlock,
-        span: dummy_sp(),
-    }
+        span: e.span
+    })
 }
 
 pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
@@ -272,7 +261,7 @@ pub fn trait_method_to_ty_method(method: &trait_method) -> TypeMethod {
                 ident: m.ident,
                 attrs: m.attrs.clone(),
                 purity: m.purity,
-                decl: m.decl.clone(),
+                decl: m.decl,
                 generics: m.generics.clone(),
                 explicit_self: m.explicit_self,
                 id: m.id,
@@ -487,7 +476,7 @@ impl<'self, O: IdVisitingOperation> Visitor<()> for IdVisitor<'self, O> {
         visit::walk_local(self, local, env)
     }
 
-    fn visit_block(&mut self, block: &Block, env: ()) {
+    fn visit_block(&mut self, block: P<Block>, env: ()) {
         self.operation.visit_id(block.id);
         visit::walk_block(self, block, env)
     }
@@ -531,7 +520,7 @@ impl<'self, O: IdVisitingOperation> Visitor<()> for IdVisitor<'self, O> {
     fn visit_fn(&mut self,
                 function_kind: &visit::fn_kind,
                 function_declaration: &fn_decl,
-                block: &Block,
+                block: P<Block>,
                 span: Span,
                 node_id: NodeId,
                 env: ()) {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 2a7f6dfe2d2..8a8de3906c4 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use abi::AbiSet;
-use ast::Ident;
+use ast::{P, Ident};
 use ast;
 use ast_util;
 use codemap::{Span, respan, dummy_sp};
@@ -39,30 +39,30 @@ pub trait AstBuilder {
                 global: bool,
                 idents: ~[ast::Ident],
                 lifetimes: OptVec<ast::Lifetime>,
-                types: ~[ast::Ty])
+                types: ~[P<ast::Ty>])
         -> ast::Path;
 
     // types
-    fn ty_mt(&self, ty: ast::Ty, mutbl: ast::Mutability) -> ast::mt;
+    fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::mt;
 
-    fn ty(&self, span: Span, ty: ast::ty_) -> ast::Ty;
-    fn ty_path(&self, ast::Path, Option<OptVec<ast::TyParamBound>>) -> ast::Ty;
-    fn ty_ident(&self, span: Span, idents: ast::Ident) -> ast::Ty;
+    fn ty(&self, span: Span, ty: ast::ty_) -> P<ast::Ty>;
+    fn ty_path(&self, ast::Path, Option<OptVec<ast::TyParamBound>>) -> P<ast::Ty>;
+    fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>;
 
     fn ty_rptr(&self, span: Span,
-               ty: ast::Ty,
+               ty: P<ast::Ty>,
                lifetime: Option<ast::Lifetime>,
-               mutbl: ast::Mutability) -> ast::Ty;
-    fn ty_uniq(&self, span: Span, ty: ast::Ty) -> ast::Ty;
-    fn ty_box(&self, span: Span, ty: ast::Ty, mutbl: ast::Mutability) -> ast::Ty;
+               mutbl: ast::Mutability) -> P<ast::Ty>;
+    fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>;
+    fn ty_box(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty>;
 
-    fn ty_option(&self, ty: ast::Ty) -> ast::Ty;
-    fn ty_infer(&self, sp: Span) -> ast::Ty;
-    fn ty_nil(&self) -> ast::Ty;
+    fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
+    fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
+    fn ty_nil(&self) -> P<ast::Ty>;
 
-    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[ast::Ty];
-    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[ast::Ty];
-    fn ty_field_imm(&self, span: Span, name: Ident, ty: ast::Ty) -> ast::TypeField;
+    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[P<ast::Ty>];
+    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[P<ast::Ty>];
+    fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField;
     fn strip_bounds(&self, bounds: &Generics) -> Generics;
 
     fn typaram(&self, id: ast::Ident, bounds: OptVec<ast::TyParamBound>) -> ast::TyParam;
@@ -78,17 +78,17 @@ pub trait AstBuilder {
                       sp: Span,
                       mutbl: bool,
                       ident: ast::Ident,
-                      typ: ast::Ty,
+                      typ: P<ast::Ty>,
                       ex: @ast::Expr)
                       -> @ast::Stmt;
 
     // blocks
-    fn block(&self, span: Span, stmts: ~[@ast::Stmt], expr: Option<@ast::Expr>) -> ast::Block;
-    fn block_expr(&self, expr: @ast::Expr) -> ast::Block;
+    fn block(&self, span: Span, stmts: ~[@ast::Stmt], expr: Option<@ast::Expr>) -> P<ast::Block>;
+    fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block>;
     fn block_all(&self, span: Span,
                  view_items: ~[ast::view_item],
                  stmts: ~[@ast::Stmt],
-                 expr: Option<@ast::Expr>) -> ast::Block;
+                 expr: Option<@ast::Expr>) -> P<ast::Block>;
 
     // expressions
     fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr;
@@ -112,8 +112,8 @@ pub trait AstBuilder {
     fn expr_method_call(&self, span: Span,
                         expr: @ast::Expr, ident: ast::Ident,
                         args: ~[@ast::Expr]) -> @ast::Expr;
-    fn expr_block(&self, b: ast::Block) -> @ast::Expr;
-    fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: ast::Ty) -> @ast::Expr;
+    fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr;
+    fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr;
 
     fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field;
     fn expr_struct(&self, span: Span, path: ast::Path, fields: ~[ast::Field]) -> @ast::Expr;
@@ -159,11 +159,12 @@ pub trait AstBuilder {
     fn expr_if(&self, span: Span,
                cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr;
 
-    fn lambda_fn_decl(&self, span: Span, fn_decl: ast::fn_decl, blk: ast::Block) -> @ast::Expr;
+    fn lambda_fn_decl(&self, span: Span,
+                      fn_decl: P<ast::fn_decl>, blk: P<ast::Block>) -> @ast::Expr;
 
-    fn lambda(&self, span: Span, ids: ~[ast::Ident], blk: ast::Block) -> @ast::Expr;
-    fn lambda0(&self, span: Span, blk: ast::Block) -> @ast::Expr;
-    fn lambda1(&self, span: Span, blk: ast::Block, ident: ast::Ident) -> @ast::Expr;
+    fn lambda(&self, span: Span, ids: ~[ast::Ident], blk: P<ast::Block>) -> @ast::Expr;
+    fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr;
+    fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr;
 
     fn lambda_expr(&self, span: Span, ids: ~[ast::Ident], blk: @ast::Expr) -> @ast::Expr;
     fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
@@ -177,25 +178,25 @@ pub trait AstBuilder {
     fn item(&self, span: Span,
             name: Ident, attrs: ~[ast::Attribute], node: ast::item_) -> @ast::item;
 
-    fn arg(&self, span: Span, name: Ident, ty: ast::Ty) -> ast::arg;
+    fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::arg;
     // XXX unused self
-    fn fn_decl(&self, inputs: ~[ast::arg], output: ast::Ty) -> ast::fn_decl;
+    fn fn_decl(&self, inputs: ~[ast::arg], output: P<ast::Ty>) -> P<ast::fn_decl>;
 
     fn item_fn_poly(&self,
                     span: Span,
                     name: Ident,
                     inputs: ~[ast::arg],
-                    output: ast::Ty,
+                    output: P<ast::Ty>,
                     generics: Generics,
-                    body: ast::Block) -> @ast::item;
+                    body: P<ast::Block>) -> @ast::item;
     fn item_fn(&self,
                span: Span,
                name: Ident,
                inputs: ~[ast::arg],
-               output: ast::Ty,
-               body: ast::Block) -> @ast::item;
+               output: P<ast::Ty>,
+               body: P<ast::Block>) -> @ast::item;
 
-    fn variant(&self, span: Span, name: Ident, tys: ~[ast::Ty]) -> ast::variant;
+    fn variant(&self, span: Span, name: Ident, tys: ~[P<ast::Ty>]) -> ast::variant;
     fn item_enum_poly(&self,
                       span: Span,
                       name: Ident,
@@ -217,9 +218,9 @@ pub trait AstBuilder {
     fn item_ty_poly(&self,
                     span: Span,
                     name: Ident,
-                    ty: ast::Ty,
+                    ty: P<ast::Ty>,
                     generics: Generics) -> @ast::item;
-    fn item_ty(&self, span: Span, name: Ident, ty: ast::Ty) -> @ast::item;
+    fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::item;
 
     fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
 
@@ -250,7 +251,7 @@ impl AstBuilder for @ExtCtxt {
                 global: bool,
                 mut idents: ~[ast::Ident],
                 lifetimes: OptVec<ast::Lifetime>,
-                types: ~[ast::Ty])
+                types: ~[P<ast::Ty>])
                 -> ast::Path {
         let last_identifier = idents.pop();
         let mut segments: ~[ast::PathSegment] = idents.move_iter()
@@ -273,23 +274,23 @@ impl AstBuilder for @ExtCtxt {
         }
     }
 
-    fn ty_mt(&self, ty: ast::Ty, mutbl: ast::Mutability) -> ast::mt {
+    fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::mt {
         ast::mt {
-            ty: ~ty,
+            ty: ty,
             mutbl: mutbl
         }
     }
 
-    fn ty(&self, span: Span, ty: ast::ty_) -> ast::Ty {
-        ast::Ty {
+    fn ty(&self, span: Span, ty: ast::ty_) -> P<ast::Ty> {
+        P(ast::Ty {
             id: ast::DUMMY_NODE_ID,
             span: span,
             node: ty
-        }
+        })
     }
 
     fn ty_path(&self, path: ast::Path, bounds: Option<OptVec<ast::TyParamBound>>)
-              -> ast::Ty {
+              -> P<ast::Ty> {
         self.ty(path.span,
                 ast::ty_path(path, bounds, ast::DUMMY_NODE_ID))
     }
@@ -297,28 +298,28 @@ impl AstBuilder for @ExtCtxt {
     // Might need to take bounds as an argument in the future, if you ever want
     // to generate a bounded existential trait type.
     fn ty_ident(&self, span: Span, ident: ast::Ident)
-        -> ast::Ty {
+        -> P<ast::Ty> {
         self.ty_path(self.path_ident(span, ident), None)
     }
 
     fn ty_rptr(&self,
                span: Span,
-               ty: ast::Ty,
+               ty: P<ast::Ty>,
                lifetime: Option<ast::Lifetime>,
                mutbl: ast::Mutability)
-        -> ast::Ty {
+        -> P<ast::Ty> {
         self.ty(span,
                 ast::ty_rptr(lifetime, self.ty_mt(ty, mutbl)))
     }
-    fn ty_uniq(&self, span: Span, ty: ast::Ty) -> ast::Ty {
+    fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> {
         self.ty(span, ast::ty_uniq(self.ty_mt(ty, ast::MutImmutable)))
     }
     fn ty_box(&self, span: Span,
-                 ty: ast::Ty, mutbl: ast::Mutability) -> ast::Ty {
+                 ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty> {
         self.ty(span, ast::ty_box(self.ty_mt(ty, mutbl)))
     }
 
-    fn ty_option(&self, ty: ast::Ty) -> ast::Ty {
+    fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
         self.ty_path(
             self.path_all(dummy_sp(),
                           true,
@@ -331,24 +332,24 @@ impl AstBuilder for @ExtCtxt {
                           ~[ ty ]), None)
     }
 
-    fn ty_field_imm(&self, span: Span, name: Ident, ty: ast::Ty) -> ast::TypeField {
+    fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField {
         ast::TypeField {
             ident: name,
-            mt: ast::mt { ty: ~ty, mutbl: ast::MutImmutable },
+            mt: ast::mt { ty: ty, mutbl: ast::MutImmutable },
             span: span,
         }
     }
 
-    fn ty_infer(&self, span: Span) -> ast::Ty {
+    fn ty_infer(&self, span: Span) -> P<ast::Ty> {
         self.ty(span, ast::ty_infer)
     }
 
-    fn ty_nil(&self) -> ast::Ty {
-        ast::Ty {
+    fn ty_nil(&self) -> P<ast::Ty> {
+        P(ast::Ty {
             id: ast::DUMMY_NODE_ID,
             node: ast::ty_nil,
             span: dummy_sp(),
-        }
+        })
     }
 
     fn typaram(&self, id: ast::Ident, bounds: OptVec<ast::TyParamBound>) -> ast::TyParam {
@@ -358,12 +359,12 @@ impl AstBuilder for @ExtCtxt {
     // these are strange, and probably shouldn't be used outside of
     // pipes. Specifically, the global version possible generates
     // incorrect code.
-    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[ast::Ty] {
+    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[P<ast::Ty>] {
         opt_vec::take_vec(
             ty_params.map(|p| self.ty_ident(dummy_sp(), p.ident)))
     }
 
-    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[ast::Ty] {
+    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[P<ast::Ty>] {
         opt_vec::take_vec(
             ty_params.map(|p| self.ty_path(
                 self.path_global(dummy_sp(), ~[p.ident]), None)))
@@ -419,7 +420,7 @@ impl AstBuilder for @ExtCtxt {
                       sp: Span,
                       mutbl: bool,
                       ident: ast::Ident,
-                      typ: ast::Ty,
+                      typ: P<ast::Ty>,
                       ex: @ast::Expr)
                       -> @ast::Stmt {
         let pat = if mutbl {
@@ -438,26 +439,26 @@ impl AstBuilder for @ExtCtxt {
         @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))
     }
 
-    fn block(&self, span: Span, stmts: ~[@ast::Stmt], expr: Option<@Expr>) -> ast::Block {
+    fn block(&self, span: Span, stmts: ~[@ast::Stmt], expr: Option<@Expr>) -> P<ast::Block> {
         self.block_all(span, ~[], stmts, expr)
     }
 
-    fn block_expr(&self, expr: @ast::Expr) -> ast::Block {
+    fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block> {
         self.block_all(expr.span, ~[], ~[], Some(expr))
     }
     fn block_all(&self,
                  span: Span,
                  view_items: ~[ast::view_item],
                  stmts: ~[@ast::Stmt],
-                 expr: Option<@ast::Expr>) -> ast::Block {
-           ast::Block {
+                 expr: Option<@ast::Expr>) -> P<ast::Block> {
+            P(ast::Block {
                view_items: view_items,
                stmts: stmts,
                expr: expr,
                id: ast::DUMMY_NODE_ID,
                rules: ast::DefaultBlock,
                span: span,
-           }
+            })
     }
 
     fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr {
@@ -525,7 +526,7 @@ impl AstBuilder for @ExtCtxt {
         self.expr(span,
                   ast::ExprMethodCall(ast::DUMMY_NODE_ID, expr, ident, ~[], args, ast::NoSugar))
     }
-    fn expr_block(&self, b: ast::Block) -> @ast::Expr {
+    fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
         self.expr(b.span, ast::ExprBlock(b))
     }
     fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field {
@@ -575,7 +576,7 @@ impl AstBuilder for @ExtCtxt {
     }
 
 
-    fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: ast::Ty) -> @ast::Expr {
+    fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr {
         self.expr(sp, ast::ExprCast(expr, ty))
     }
 
@@ -673,23 +674,24 @@ impl AstBuilder for @ExtCtxt {
         self.expr(span, ast::ExprIf(cond, self.block_expr(then), els))
     }
 
-    fn lambda_fn_decl(&self, span: Span, fn_decl: ast::fn_decl, blk: ast::Block) -> @ast::Expr {
+    fn lambda_fn_decl(&self, span: Span,
+                      fn_decl: P<ast::fn_decl>, blk: P<ast::Block>) -> @ast::Expr {
         self.expr(span, ast::ExprFnBlock(fn_decl, blk))
     }
-    fn lambda(&self, span: Span, ids: ~[ast::Ident], blk: ast::Block) -> @ast::Expr {
+    fn lambda(&self, span: Span, ids: ~[ast::Ident], blk: P<ast::Block>) -> @ast::Expr {
         let fn_decl = self.fn_decl(
             ids.map(|id| self.arg(span, *id, self.ty_infer(span))),
             self.ty_infer(span));
 
         self.expr(span, ast::ExprFnBlock(fn_decl, blk))
     }
-    fn lambda0(&self, _span: Span, blk: ast::Block) -> @ast::Expr {
-        let blk_e = self.expr(blk.span, ast::ExprBlock(blk.clone()));
+    fn lambda0(&self, _span: Span, blk: P<ast::Block>) -> @ast::Expr {
+        let blk_e = self.expr(blk.span, ast::ExprBlock(blk));
         quote_expr!(*self, || $blk_e )
     }
 
-    fn lambda1(&self, _span: Span, blk: ast::Block, ident: ast::Ident) -> @ast::Expr {
-        let blk_e = self.expr(blk.span, ast::ExprBlock(blk.clone()));
+    fn lambda1(&self, _span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr {
+        let blk_e = self.expr(blk.span, ast::ExprBlock(blk));
         quote_expr!(*self, |$ident| $blk_e )
     }
 
@@ -713,7 +715,7 @@ impl AstBuilder for @ExtCtxt {
         self.lambda1(span, self.block(span, stmts, None), ident)
     }
 
-    fn arg(&self, span: Span, ident: ast::Ident, ty: ast::Ty) -> ast::arg {
+    fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::arg {
         let arg_pat = self.pat_ident(span, ident);
         ast::arg {
             ty: ty,
@@ -723,13 +725,13 @@ impl AstBuilder for @ExtCtxt {
     }
 
     // XXX unused self
-    fn fn_decl(&self, inputs: ~[ast::arg], output: ast::Ty) -> ast::fn_decl {
-        ast::fn_decl {
+    fn fn_decl(&self, inputs: ~[ast::arg], output: P<ast::Ty>) -> P<ast::fn_decl> {
+        P(ast::fn_decl {
             inputs: inputs,
             output: output,
             cf: ast::return_val,
             variadic: false
-        }
+        })
     }
 
     fn item(&self, span: Span,
@@ -748,9 +750,9 @@ impl AstBuilder for @ExtCtxt {
                     span: Span,
                     name: Ident,
                     inputs: ~[ast::arg],
-                    output: ast::Ty,
+                    output: P<ast::Ty>,
                     generics: Generics,
-                    body: ast::Block) -> @ast::item {
+                    body: P<ast::Block>) -> @ast::item {
         self.item(span,
                   name,
                   ~[],
@@ -765,8 +767,8 @@ impl AstBuilder for @ExtCtxt {
                span: Span,
                name: Ident,
                inputs: ~[ast::arg],
-               output: ast::Ty,
-               body: ast::Block
+               output: P<ast::Ty>,
+               body: P<ast::Block>
               ) -> @ast::item {
         self.item_fn_poly(
             span,
@@ -777,7 +779,7 @@ impl AstBuilder for @ExtCtxt {
             body)
     }
 
-    fn variant(&self, span: Span, name: Ident, tys: ~[ast::Ty]) -> ast::variant {
+    fn variant(&self, span: Span, name: Ident, tys: ~[P<ast::Ty>]) -> ast::variant {
         let args = tys.move_iter().map(|ty| {
             ast::variant_arg { ty: ty, id: ast::DUMMY_NODE_ID }
         }).collect();
@@ -844,12 +846,12 @@ impl AstBuilder for @ExtCtxt {
         )
     }
 
-    fn item_ty_poly(&self, span: Span, name: Ident, ty: ast::Ty,
+    fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>,
                     generics: Generics) -> @ast::item {
         self.item(span, name, ~[], ast::item_ty(ty, generics))
     }
 
-    fn item_ty(&self, span: Span, name: Ident, ty: ast::Ty) -> @ast::item {
+    fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::item {
         self.item_ty_poly(span, name, ty, ast_util::empty_generics())
     }
 
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index e882650f046..627e799f2d3 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -175,7 +175,7 @@ StaticEnum(<ast::enum_def of C>, ~[(<ident of C0>, Unnamed(~[<span of int>])),
 */
 
 use ast;
-use ast::{enum_def, Expr, Ident, Generics, struct_def};
+use ast::{P, enum_def, Expr, Ident, Generics, struct_def};
 
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -279,7 +279,7 @@ pub enum SubstructureFields<'self> {
     [field span, field ident, fields])] (i.e. all fields for self are in the
     first tuple, for other1 are in the second tuple, etc.)
     */
-    EnumNonMatching(&'self [(uint, ast::variant, ~[(Span, Option<Ident>, @Expr)])]),
+    EnumNonMatching(&'self [(uint, P<ast::variant>, ~[(Span, Option<Ident>, @Expr)])]),
 
     /// A static method where Self is a struct.
     StaticStruct(&'self ast::struct_def, StaticFields),
@@ -304,7 +304,7 @@ representing each variant: (variant index, ast::variant instance,
 pub type EnumNonMatchFunc<'self> =
     'self |@ExtCtxt,
            Span,
-           &[(uint, ast::variant, ~[(Span, Option<Ident>, @Expr)])],
+           &[(uint, P<ast::variant>, ~[(Span, Option<Ident>, @Expr)])],
            &[@Expr]|
            -> @Expr;
 
@@ -484,7 +484,7 @@ impl<'self> MethodDef<'self> {
     }
 
     fn get_ret_ty(&self, cx: @ExtCtxt, trait_span: Span,
-                  generics: &Generics, type_ident: Ident) -> ast::Ty {
+                  generics: &Generics, type_ident: Ident) -> P<ast::Ty> {
         self.ret_ty.to_ty(cx, trait_span, type_ident, generics)
     }
 
@@ -494,7 +494,7 @@ impl<'self> MethodDef<'self> {
 
     fn split_self_nonself_args(&self, cx: @ExtCtxt, trait_span: Span,
                                type_ident: Ident, generics: &Generics)
-        -> (ast::explicit_self, ~[@Expr], ~[@Expr], ~[(Ident, ast::Ty)]) {
+        -> (ast::explicit_self, ~[@Expr], ~[@Expr], ~[(Ident, P<ast::Ty>)]) {
 
         let mut self_args = ~[];
         let mut nonself_args = ~[];
@@ -542,7 +542,7 @@ impl<'self> MethodDef<'self> {
                      type_ident: Ident,
                      generics: &Generics,
                      explicit_self: ast::explicit_self,
-                     arg_types: ~[(Ident, ast::Ty)],
+                     arg_types: ~[(Ident, P<ast::Ty>)],
                      body: @Expr) -> @ast::method {
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(cx, trait_span, type_ident, generics);
@@ -745,7 +745,7 @@ impl<'self> MethodDef<'self> {
                         self_args: &[@Expr],
                         nonself_args: &[@Expr],
                         matching: Option<uint>,
-                        matches_so_far: &mut ~[(uint, ast::variant,
+                        matches_so_far: &mut ~[(uint, P<ast::variant>,
                                               ~[(Span, Option<Ident>, @Expr)])],
                         match_count: uint) -> @Expr {
         if match_count == self_args.len() {
@@ -772,7 +772,7 @@ impl<'self> MethodDef<'self> {
                     // `ref` inside let matches is buggy. Causes havoc wih rusc.
                     // let (variant_index, ref self_vec) = matches_so_far[0];
                     let (variant, self_vec) = match matches_so_far[0] {
-                        (_, ref v, ref s) => (v, s)
+                        (_, v, ref s) => (v, s)
                     };
 
                     let mut enum_matching_fields = vec::from_elem(self_vec.len(), ~[]);
@@ -828,15 +828,13 @@ impl<'self> MethodDef<'self> {
                 };
 
                 // matching-variant match
-                let variant = &enum_def.variants[index];
+                let variant = enum_def.variants[index];
                 let (pattern, idents) = create_enum_variant_pattern(cx,
                                                                     variant,
                                                                     current_match_str,
                                                                     ast::MutImmutable);
 
-                matches_so_far.push((index,
-                                     /*bad*/ (*variant).clone(),
-                                     idents));
+                matches_so_far.push((index, variant, idents));
                 let arm_expr = self.build_enum_match(cx, trait_span,
                                                      enum_def,
                                                      type_ident,
@@ -859,15 +857,13 @@ impl<'self> MethodDef<'self> {
                 }
             } else {
                 // create an arm matching on each variant
-                for (index, variant) in enum_def.variants.iter().enumerate() {
+                for (index, &variant) in enum_def.variants.iter().enumerate() {
                     let (pattern, idents) = create_enum_variant_pattern(cx,
                                                                         variant,
                                                                         current_match_str,
                                                                         ast::MutImmutable);
 
-                    matches_so_far.push((index,
-                                         /*bad*/ (*variant).clone(),
-                                         idents));
+                    matches_so_far.push((index, variant, idents));
                     let new_matching =
                         match matching {
                             _ if match_count == 0 => Some(index),
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index af6379d476e..87381d25dc7 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -14,7 +14,7 @@ explicit `Self` type to use when specifying impls to be derived.
 */
 
 use ast;
-use ast::{Expr,Generics,Ident};
+use ast::{P,Expr,Generics,Ident};
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use codemap::{Span,respan};
@@ -62,7 +62,7 @@ impl<'self> Path<'self> {
                  span: Span,
                  self_ty: Ident,
                  self_generics: &Generics)
-                 -> ast::Ty {
+                 -> P<ast::Ty> {
         cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None)
     }
     pub fn to_path(&self,
@@ -130,7 +130,7 @@ impl<'self> Ty<'self> {
                  span: Span,
                  self_ty: Ident,
                  self_generics: &Generics)
-                 -> ast::Ty {
+                 -> P<ast::Ty> {
         match *self {
             Ptr(ref ty, ref ptr) => {
                 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 85839691b48..acf0326aefd 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{Block, Crate, DeclLocal, Expr_, ExprMac, SyntaxContext};
+use ast::{P, Block, Crate, DeclLocal, Expr_, ExprMac, SyntaxContext};
 use ast::{Local, Ident, mac_invoc_tt};
 use ast::{item_mac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi};
 use ast::{token_tree};
@@ -131,11 +131,11 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
         // Desugar expr_for_loop
         // From: `['<ident>:] for <src_pat> in <src_expr> <src_loop_block>`
         // FIXME #6993 : change type of opt_ident to Option<Name>
-        ast::ExprForLoop(src_pat, src_expr, ref src_loop_block, opt_ident) => {
+        ast::ExprForLoop(src_pat, src_expr, src_loop_block, opt_ident) => {
             // Expand any interior macros etc.
             // NB: we don't fold pats yet. Curious.
             let src_expr = fld.fold_expr(src_expr).clone();
-            let src_loop_block = fld.fold_block(src_loop_block).clone();
+            let src_loop_block = fld.fold_block(src_loop_block);
 
             let span = e.span;
 
@@ -148,21 +148,6 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                 }
             }
 
-            fn mk_block(_: @ExtCtxt,
-                        stmts: &[@ast::Stmt],
-                        expr: Option<@ast::Expr>,
-                        span: Span)
-                        -> ast::Block {
-                ast::Block {
-                    view_items: ~[],
-                    stmts: stmts.to_owned(),
-                    expr: expr,
-                    id: ast::DUMMY_NODE_ID,
-                    rules: ast::DefaultBlock,
-                    span: span,
-                }
-            }
-
             fn mk_simple_path(ident: ast::Ident, span: Span) -> ast::Path {
                 ast::Path {
                     span: span,
@@ -556,8 +541,6 @@ fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
                 id: id,
                 span: span
             } = *local;
-            // types can't be copied automatically because of the owned ptr in ty_tup...
-            let ty = local.ty.clone();
             // expand the pat (it might contain exprs... #:(o)>
             let expanded_pat = fld.fold_pat(pat);
             // find the pat_idents in the pattern:
@@ -582,7 +565,7 @@ fn expand_non_macro_stmt(exts: SyntaxEnv, s: &Stmt, fld: &MacroExpander)
             let new_init_opt = init.map(|e| fld.fold_expr(e));
             let rewritten_local =
                 @Local {
-                    ty: ty,
+                    ty: local.ty,
                     pat: rewritten_pat,
                     init: new_init_opt,
                     id: id,
@@ -664,7 +647,7 @@ pub fn expand_block(extsbox: @mut SyntaxEnv,
                     _: @ExtCtxt,
                     blk: &Block,
                     fld: &MacroExpander)
-                    -> Block {
+                    -> P<Block> {
     // see note below about treatment of exts table
     with_exts_frame!(extsbox,false,
                      expand_block_elts(*extsbox, blk, fld))
@@ -672,7 +655,7 @@ pub fn expand_block(extsbox: @mut SyntaxEnv,
 
 // expand the elements of a block.
 pub fn expand_block_elts(exts: SyntaxEnv, b: &Block, fld: &MacroExpander)
-                         -> Block {
+                         -> P<Block> {
     let block_info = get_block_info(exts);
     let pending_renames = block_info.pending_renames;
     let rename_fld = renames_to_fold(pending_renames);
@@ -683,14 +666,14 @@ pub fn expand_block_elts(exts: SyntaxEnv, b: &Block, fld: &MacroExpander)
             .flat_map(|x| fld.fold_stmt(x).move_iter())
             .collect();
     let new_expr = b.expr.map(|x| fld.fold_expr(rename_fld.fold_expr(x)));
-    Block{
+    P(Block {
         view_items: new_view_items,
         stmts: new_stmts,
         expr: new_expr,
         id: fld.new_id(b.id),
         rules: b.rules,
         span: b.span,
-    }
+    })
 }
 
 // get the (innermost) BlockInfo from an exts stack
@@ -1024,7 +1007,7 @@ impl ast_fold for MacroExpander {
                     self)
     }
 
-    fn fold_block(&self, block: &ast::Block) -> ast::Block {
+    fn fold_block(&self, block: P<Block>) -> P<Block> {
         expand_block(self.extsbox,
                      self.cx,
                      block,
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index c7354b0601c..f6fb521ff7c 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use ast;
+use ast::P;
 use codemap::{Span, respan};
 use ext::base::*;
 use ext::base;
@@ -587,7 +588,7 @@ impl Context {
                 ~[]
             ), None);
         let ty = ast::ty_fixed_length_vec(
-            self.ecx.ty_mt(piece_ty.clone(), ast::MutImmutable),
+            self.ecx.ty_mt(piece_ty, ast::MutImmutable),
             self.ecx.expr_uint(self.fmtsp, self.pieces.len())
         );
         let ty = self.ecx.ty(self.fmtsp, ty);
@@ -639,14 +640,14 @@ impl Context {
 
         // We did all the work of making sure that the arguments
         // structure is safe, so we can safely have an unsafe block.
-        let result = self.ecx.expr_block(ast::Block {
+        let result = self.ecx.expr_block(P(ast::Block {
            view_items: ~[],
            stmts: ~[],
            expr: Some(result),
            id: ast::DUMMY_NODE_ID,
            rules: ast::UnsafeBlock(ast::CompilerGenerated),
            span: self.fmtsp,
-        });
+        }));
         let resname = self.ecx.ident_of("__args");
         lets.push(self.ecx.stmt_let(self.fmtsp, false, resname, result));
         let res = self.ecx.expr_ident(self.fmtsp, resname);
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 3da2eac1a3d..a450bfeccfe 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -432,11 +432,11 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal {
         Some(i) => token::nt_item(i),
         None => p.fatal("expected an item keyword")
       },
-      "block" => token::nt_block(~p.parse_block()),
+      "block" => token::nt_block(p.parse_block()),
       "stmt" => token::nt_stmt(p.parse_stmt(~[])),
       "pat" => token::nt_pat(p.parse_pat()),
       "expr" => token::nt_expr(p.parse_expr()),
-      "ty" => token::nt_ty(~p.parse_ty(false /* no need to disambiguate*/)),
+      "ty" => token::nt_ty(p.parse_ty(false /* no need to disambiguate*/)),
       // this could be handled like a token, since it is one
       "ident" => match *p.token {
         token::IDENT(sn,b) => { p.bump(); token::nt_ident(~sn,b) }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 887d3d2014a..945d22a0f5a 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -95,16 +95,16 @@ pub trait ast_fold {
                 match ni.node {
                     foreign_item_fn(ref fdec, ref generics) => {
                         foreign_item_fn(
-                            ast::fn_decl {
+                            P(fn_decl {
                                 inputs: fdec.inputs.map(|a| fold_arg_(a,
                                                                       self)),
-                                output: self.fold_ty(&fdec.output),
+                                output: self.fold_ty(fdec.output),
                                 cf: fdec.cf,
                                 variadic: fdec.variadic
-                            },
+                            }),
                             fold_generics(generics, self))
                     }
-                    foreign_item_static(ref t, m) => {
+                    foreign_item_static(t, m) => {
                         foreign_item_static(self.fold_ty(t), m)
                     }
                 },
@@ -125,7 +125,7 @@ pub trait ast_fold {
             node: ast::struct_field_ {
                 kind: sf.node.kind,
                 id: self.new_id(sf.node.id),
-                ty: self.fold_ty(&sf.node.ty),
+                ty: self.fold_ty(sf.node.ty),
                 attrs: sf.node.attrs.map(|e| fold_attribute(*e))
             },
             span: self.new_span(sf.span)
@@ -147,8 +147,8 @@ pub trait ast_fold {
             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),
+            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),
@@ -156,7 +156,7 @@ pub trait ast_fold {
         }
     }
 
-    fn fold_block(&self, b: &Block) -> Block {
+    fn fold_block(&self, b: P<Block>) -> P<Block> {
         noop_fold_block(b, self)
     }
 
@@ -168,7 +168,7 @@ pub trait ast_fold {
         Arm {
             pats: a.pats.map(|x| self.fold_pat(*x)),
             guard: a.guard.map(|x| self.fold_expr(x)),
-            body: self.fold_block(&a.body),
+            body: self.fold_block(a.body),
         }
     }
 
@@ -237,7 +237,7 @@ pub trait ast_fold {
         noop_fold_expr(e, self)
     }
 
-    fn fold_ty(&self, t: &Ty) -> Ty {
+    fn fold_ty(&self, t: P<Ty>) -> P<Ty> {
         let node = match t.node {
             ty_nil | ty_bot | ty_infer => t.node.clone(),
             ty_box(ref mt) => ty_box(fold_mt(mt, self)),
@@ -254,7 +254,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: fold_fn_decl(f.decl, self),
                     lifetimes: f.lifetimes.map(|l| fold_lifetime(l, self)),
                 })
             }
@@ -263,10 +263,10 @@ 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: fold_fn_decl(f.decl, self)
                 })
             }
-            ty_tup(ref tys) => ty_tup(tys.map(|ty| self.fold_ty(ty))),
+            ty_tup(ref tys) => ty_tup(tys.map(|&ty| self.fold_ty(ty))),
             ty_path(ref path, ref bounds, id) => {
                 ty_path(self.fold_path(path),
                         fold_opt_bounds(bounds, self),
@@ -277,11 +277,11 @@ pub trait ast_fold {
             }
             ty_typeof(expr) => ty_typeof(self.fold_expr(expr)),
         };
-        Ty {
+        P(Ty {
             id: self.new_id(t.id),
             span: self.new_span(t.span),
             node: node,
-        }
+        })
     }
 
     fn fold_mod(&self, m: &_mod) -> _mod {
@@ -302,7 +302,7 @@ pub trait ast_fold {
         }
     }
 
-    fn fold_variant(&self, v: &variant) -> variant {
+    fn fold_variant(&self, v: &variant) -> P<variant> {
         let kind;
         match v.node.kind {
             tuple_variant_kind(ref variant_args) => {
@@ -333,10 +333,10 @@ pub trait ast_fold {
             disr_expr: de,
             vis: v.node.vis,
         };
-        Spanned {
+        P(Spanned {
             node: node,
             span: self.new_span(v.span),
-        }
+        })
     }
 
     fn fold_ident(&self, i: Ident) -> Ident {
@@ -350,14 +350,14 @@ pub trait ast_fold {
             segments: p.segments.map(|segment| ast::PathSegment {
                 identifier: self.fold_ident(segment.identifier),
                 lifetimes: segment.lifetimes.map(|l| fold_lifetime(l, self)),
-                types: segment.types.map(|typ| self.fold_ty(typ)),
+                types: segment.types.map(|&typ| self.fold_ty(typ)),
             })
         }
     }
 
     fn fold_local(&self, l: @Local) -> @Local {
         @Local {
-            ty: self.fold_ty(&l.ty),
+            ty: self.fold_ty(l.ty),
             pat: self.fold_pat(l.pat),
             init: l.init.map(|e| self.fold_expr(e)),
             id: self.new_id(l.id),
@@ -444,7 +444,7 @@ fn fold_attribute_<T:ast_fold>(at: Attribute, fld: &T) -> Attribute {
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_<T:ast_fold>(a: &arg, fld: &T) -> arg {
     ast::arg {
-        ty: fld.fold_ty(&a.ty),
+        ty: fld.fold_ty(a.ty),
         pat: fld.fold_pat(a.pat),
         id: fld.new_id(a.id),
     }
@@ -480,13 +480,13 @@ fn maybe_fold_ident<T:ast_fold>(t: &token::Token, fld: &T) -> token::Token {
 }
 
 pub fn fold_fn_decl<T:ast_fold>(decl: &ast::fn_decl, fld: &T)
-                                -> ast::fn_decl {
-    ast::fn_decl {
+                                -> P<fn_decl> {
+    P(fn_decl {
         inputs: decl.inputs.map(|x| fold_arg_(x, fld)), // bad copy
-        output: fld.fold_ty(&decl.output),
+        output: fld.fold_ty(decl.output),
         cf: decl.cf,
         variadic: decl.variadic
-    }
+    })
 }
 
 fn fold_ty_param_bound<T:ast_fold>(tpb: &TyParamBound, fld: &T)
@@ -567,7 +567,7 @@ fn fold_struct_field<T:ast_fold>(f: @struct_field, fld: &T) -> @struct_field {
         node: ast::struct_field_ {
             kind: f.node.kind,
             id: fld.new_id(f.node.id),
-            ty: fld.fold_ty(&f.node.ty),
+            ty: fld.fold_ty(f.node.ty),
             attrs: f.node.attrs.map(|a| fold_attribute_(*a, fld)),
         },
         span: fld.new_span(f.span),
@@ -584,7 +584,7 @@ fn fold_field_<T:ast_fold>(field: Field, folder: &T) -> Field {
 
 fn fold_mt<T:ast_fold>(mt: &mt, folder: &T) -> mt {
     mt {
-        ty: ~folder.fold_ty(mt.ty),
+        ty: folder.fold_ty(mt.ty),
         mutbl: mt.mutbl,
     }
 }
@@ -609,30 +609,30 @@ fn fold_opt_bounds<T:ast_fold>(b: &Option<OptVec<TyParamBound>>, folder: &T)
 fn fold_variant_arg_<T:ast_fold>(va: &variant_arg, folder: &T)
                                  -> variant_arg {
     ast::variant_arg {
-        ty: folder.fold_ty(&va.ty),
+        ty: folder.fold_ty(va.ty),
         id: folder.new_id(va.id)
     }
 }
 
-pub fn noop_fold_block<T:ast_fold>(b: &Block, folder: &T) -> Block {
+pub fn noop_fold_block<T:ast_fold>(b: P<Block>, folder: &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();
-    ast::Block {
+    P(Block {
         view_items: view_items,
         stmts: stmts,
         expr: b.expr.map(|x| folder.fold_expr(x)),
         id: folder.new_id(b.id),
         rules: b.rules,
         span: folder.new_span(b.span),
-    }
+    })
 }
 
 pub fn noop_fold_item_underscore<T:ast_fold>(i: &item_, folder: &T) -> item_ {
     match *i {
-        item_static(ref t, m, e) => {
+        item_static(t, m, e) => {
             item_static(folder.fold_ty(t), m, folder.fold_expr(e))
         }
-        item_fn(ref decl, purity, abi, ref generics, ref body) => {
+        item_fn(decl, purity, abi, ref generics, body) => {
             item_fn(
                 fold_fn_decl(decl, folder),
                 purity,
@@ -645,14 +645,14 @@ pub fn noop_fold_item_underscore<T:ast_fold>(i: &item_, folder: &T) -> item_ {
         item_foreign_mod(ref nm) => {
             item_foreign_mod(folder.fold_foreign_mod(nm))
         }
-        item_ty(ref t, ref generics) => {
+        item_ty(t, ref generics) => {
             item_ty(folder.fold_ty(t),
                     fold_generics(generics, folder))
         }
         item_enum(ref enum_definition, ref generics) => {
             item_enum(
                 ast::enum_def {
-                    variants: enum_definition.variants.map(|x| {
+                    variants: enum_definition.variants.map(|&x| {
                         folder.fold_variant(x)
                     }),
                 },
@@ -662,7 +662,7 @@ pub fn noop_fold_item_underscore<T:ast_fold>(i: &item_, folder: &T) -> item_ {
             let struct_def = fold_struct_def(*struct_def, folder);
             item_struct(struct_def, fold_generics(generics, folder))
         }
-        item_impl(ref generics, ref ifce, ref ty, ref methods) => {
+        item_impl(ref generics, ref ifce, ty, ref methods) => {
             item_impl(fold_generics(generics, folder),
                       ifce.as_ref().map(|p| fold_trait_ref(p, folder)),
                       folder.fold_ty(ty),
@@ -690,7 +690,7 @@ pub fn noop_fold_type_method<T:ast_fold>(m: &TypeMethod, fld: &T)
         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: fold_fn_decl(m.decl, fld),
         generics: fold_generics(&m.generics, fld),
         explicit_self: fld.fold_explicit_self(&m.explicit_self),
         id: fld.new_id(m.id),
@@ -757,7 +757,7 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &T) -> @ast::Expr {
                 folder.new_id(callee_id),
                 folder.fold_expr(f),
                 folder.fold_ident(i),
-                tps.map(|x| folder.fold_ty(x)),
+                tps.map(|&x| folder.fold_ty(x)),
                 folder.map_exprs(|x| folder.fold_expr(x), *args),
                 blk
             )
@@ -773,25 +773,25 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &T) -> @ast::Expr {
         }
         ExprDoBody(f) => ExprDoBody(folder.fold_expr(f)),
         ExprLit(_) => e.node.clone(),
-        ExprCast(expr, ref ty) => {
+        ExprCast(expr, ty) => {
             ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
         }
         ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
-        ExprIf(cond, ref tr, fl) => {
+        ExprIf(cond, tr, fl) => {
             ExprIf(folder.fold_expr(cond),
                    folder.fold_block(tr),
                    fl.map(|x| folder.fold_expr(x)))
         }
-        ExprWhile(cond, ref body) => {
+        ExprWhile(cond, body) => {
             ExprWhile(folder.fold_expr(cond), folder.fold_block(body))
         }
-        ExprForLoop(pat, iter, ref body, ref maybe_ident) => {
+        ExprForLoop(pat, iter, body, ref maybe_ident) => {
             ExprForLoop(folder.fold_pat(pat),
                         folder.fold_expr(iter),
                         folder.fold_block(body),
                         maybe_ident.map(|i| folder.fold_ident(i)))
         }
-        ExprLoop(ref body, opt_ident) => {
+        ExprLoop(body, opt_ident) => {
             ExprLoop(folder.fold_block(body),
                      opt_ident.map(|x| folder.fold_ident(x)))
         }
@@ -799,16 +799,16 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &T) -> @ast::Expr {
             ExprMatch(folder.fold_expr(expr),
                       arms.map(|x| folder.fold_arm(x)))
         }
-        ExprFnBlock(ref decl, ref body) => {
+        ExprFnBlock(decl, body) => {
             ExprFnBlock(
                 fold_fn_decl(decl, folder),
                 folder.fold_block(body)
             )
         }
-        ExprProc(ref decl, ref body) => {
+        ExprProc(decl, body) => {
             ExprProc(fold_fn_decl(decl, folder), folder.fold_block(body))
         }
-        ExprBlock(ref blk) => ExprBlock(folder.fold_block(blk)),
+        ExprBlock(blk) => ExprBlock(folder.fold_block(blk)),
         ExprAssign(el, er) => {
             ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
         }
@@ -821,7 +821,7 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &T) -> @ast::Expr {
         ExprField(el, id, ref tys) => {
             ExprField(folder.fold_expr(el),
                       folder.fold_ident(id),
-                      tys.map(|x| folder.fold_ty(x)))
+                      tys.map(|&x| folder.fold_ty(x)))
         }
         ExprIndex(callee_id, el, er) => {
             ExprIndex(folder.new_id(callee_id),
diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs
index 81b98e537f4..1204cbc2eea 100644
--- a/src/libsyntax/parse/classify.rs
+++ b/src/libsyntax/parse/classify.rs
@@ -39,9 +39,7 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool {
 
 pub fn expr_is_simple_block(e: @ast::Expr) -> bool {
     match e.node {
-        ast::ExprBlock(
-            ast::Block { rules: ast::DefaultBlock, .. }
-        ) => true,
+        ast::ExprBlock(block) => block.rules == ast::DefaultBlock,
       _ => false
     }
 }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 8fbd152543d..a1ccf4771a7 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -654,10 +654,10 @@ mod test {
                       @ast::item{ident:str_to_ident("a"),
                             attrs:~[],
                             id: ast::DUMMY_NODE_ID,
-                            node: ast::item_fn(ast::fn_decl{
+                            node: ast::item_fn(ast::P(ast::fn_decl{
                                 inputs: ~[ast::arg{
-                                    ty: ast::Ty{id: ast::DUMMY_NODE_ID,
-                                                node: ast::ty_path(ast::Path{
+                                    ty: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID,
+                                                       node: ast::ty_path(ast::Path{
                                         span:sp(10,13),
                                         global:false,
                                         segments: ~[
@@ -670,7 +670,7 @@ mod test {
                                         ],
                                         }, None, ast::DUMMY_NODE_ID),
                                         span:sp(10,13)
-                                    },
+                                    }),
                                     pat: @ast::Pat {
                                         id: ast::DUMMY_NODE_ID,
                                         node: ast::PatIdent(
@@ -693,19 +693,19 @@ mod test {
                                     },
                                     id: ast::DUMMY_NODE_ID
                                 }],
-                                output: ast::Ty{id: ast::DUMMY_NODE_ID,
-                                                 node: ast::ty_nil,
-                                                 span:sp(15,15)}, // not sure
+                                output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID,
+                                                       node: ast::ty_nil,
+                                                       span:sp(15,15)}), // not sure
                                 cf: ast::return_val,
                                 variadic: false
-                            },
+                            }),
                                     ast::impure_fn,
                                     abi::AbiSet::Rust(),
                                     ast::Generics{ // no idea on either of these:
                                         lifetimes: opt_vec::Empty,
                                         ty_params: opt_vec::Empty,
                                     },
-                                    ast::Block {
+                                    ast::P(ast::Block {
                                         view_items: ~[],
                                         stmts: ~[@Spanned{
                                             node: ast::StmtSemi(@ast::Expr{
@@ -733,7 +733,7 @@ mod test {
                                         id: ast::DUMMY_NODE_ID,
                                         rules: ast::DefaultBlock, // no idea
                                         span: sp(15,21),
-                                    }),
+                                    })),
                             vis: ast::inherited,
                             span: sp(0,21)}));
     }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8263906d925..5807098c91e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -41,7 +41,7 @@ use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int, lit_char};
 use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local};
 use ast::{MutImmutable, MutMutable, mac_, mac_invoc_tt, matcher, match_nonterminal};
 use ast::{match_seq, match_tok, method, mt, BiMul, Mutability};
-use ast::{named_field, UnNeg, noreturn, UnNot, Pat, PatBox, PatEnum};
+use ast::{named_field, UnNeg, noreturn, UnNot, P, Pat, PatBox, PatEnum};
 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatUniq, PatWild, PatWildMulti, private};
 use ast::{BiRem, required};
@@ -190,6 +190,22 @@ macro_rules! maybe_whole (
             }
         }
     );
+    (no_clone $p:expr, $constructor:ident) => (
+        {
+            let __found__ = match *($p).token {
+                INTERPOLATED(token::$constructor(_)) => {
+                    Some(($p).bump_and_get())
+                }
+                _ => None
+            };
+            match __found__ {
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return x
+                }
+                _ => {}
+            }
+        }
+    );
     (deref $p:expr, $constructor:ident) => (
         {
             let __found__ = match *($p).token {
@@ -247,8 +263,8 @@ macro_rules! maybe_whole (
                 _ => None
             };
             match __found__ {
-                Some(INTERPOLATED(token::$constructor(ref x))) => {
-                    return (~[], (**x).clone())
+                Some(INTERPOLATED(token::$constructor(x))) => {
+                    return (~[], x)
                 }
                 _ => {}
             }
@@ -960,12 +976,12 @@ impl Parser {
                 let bounds = self.parse_optional_ty_param_bounds();
 
                 let (return_style, output) = self.parse_ret_ty();
-                let decl = ast::fn_decl {
+                let decl = P(ast::fn_decl {
                     inputs: inputs,
                     output: output,
                     cf: return_style,
                     variadic: false
-                };
+                });
 
                 (BorrowedSigil, decl, lifetimes, bounds)
             }
@@ -999,7 +1015,7 @@ impl Parser {
     }
 
     // parse a function type (following the 'fn')
-    pub fn parse_ty_fn_decl(&self, allow_variadic: bool) -> (fn_decl, OptVec<ast::Lifetime>) {
+    pub fn parse_ty_fn_decl(&self, allow_variadic: bool) -> (P<fn_decl>, OptVec<ast::Lifetime>) {
         /*
 
         (fn) <'lt> (S) -> T
@@ -1020,12 +1036,12 @@ impl Parser {
 
         let (inputs, variadic) = self.parse_fn_args(false, allow_variadic);
         let (ret_style, ret_ty) = self.parse_ret_ty();
-        let decl = ast::fn_decl {
+        let decl = P(ast::fn_decl {
             inputs: inputs,
             output: ret_ty,
             cf: ret_style,
             variadic: variadic
-        };
+        });
         (decl, lifetimes)
     }
 
@@ -1114,7 +1130,7 @@ impl Parser {
     // parse a possibly mutable type
     pub fn parse_mt(&self) -> mt {
         let mutbl = self.parse_mutability();
-        let t = ~self.parse_ty(false);
+        let t = self.parse_ty(false);
         mt { ty: t, mutbl: mutbl }
     }
 
@@ -1125,7 +1141,7 @@ impl Parser {
         let mutbl = self.parse_mutability();
         let id = self.parse_ident();
         self.expect(&token::COLON);
-        let ty = ~self.parse_ty(false);
+        let ty = self.parse_ty(false);
         let hi = ty.span.hi;
         ast::TypeField {
             ident: id,
@@ -1135,17 +1151,17 @@ impl Parser {
     }
 
     // parse optional return type [ -> TY ] in function decl
-    pub fn parse_ret_ty(&self) -> (ret_style, Ty) {
+    pub fn parse_ret_ty(&self) -> (ret_style, P<Ty>) {
         return if self.eat(&token::RARROW) {
             let lo = self.span.lo;
             if self.eat(&token::NOT) {
                 (
                     noreturn,
-                    Ty {
+                    P(Ty {
                         id: ast::DUMMY_NODE_ID,
                         node: ty_bot,
                         span: mk_sp(lo, self.last_span.hi)
-                    }
+                    })
                 )
             } else {
                 (return_val, self.parse_ty(false))
@@ -1154,11 +1170,11 @@ impl Parser {
             let pos = self.span.lo;
             (
                 return_val,
-                Ty {
+                P(Ty {
                     id: ast::DUMMY_NODE_ID,
                     node: ty_nil,
                     span: mk_sp(pos, pos),
-                }
+                })
             )
         }
     }
@@ -1166,8 +1182,8 @@ impl Parser {
     // parse a type.
     // Useless second parameter for compatibility with quasiquote macros.
     // Bleh!
-    pub fn parse_ty(&self, _: bool) -> Ty {
-        maybe_whole!(deref self, nt_ty);
+    pub fn parse_ty(&self, _: bool) -> P<Ty> {
+        maybe_whole!(no_clone self, nt_ty);
 
         let lo = self.span.lo;
 
@@ -1216,7 +1232,7 @@ impl Parser {
         } else if *self.token == token::LBRACKET {
             // VECTOR
             self.expect(&token::LBRACKET);
-            let mt = mt { ty: ~self.parse_ty(false), mutbl: MutImmutable };
+            let mt = mt { ty: self.parse_ty(false), mutbl: MutImmutable };
 
             // Parse the `, ..e` in `[ int, ..e ]`
             // where `e` is a const expression
@@ -1270,7 +1286,7 @@ impl Parser {
         };
 
         let sp = mk_sp(lo, self.last_span.hi);
-        Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp}
+        P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})
     }
 
     // parse the type following a @ or a ~
@@ -1300,7 +1316,7 @@ impl Parser {
         // rather than boxed ptrs.  But the special casing of str/vec is not
         // reflected in the AST type.
         if sigil == OwnedSigil {
-            ctor(mt { ty: ~self.parse_ty(false), mutbl: MutImmutable })
+            ctor(mt { ty: self.parse_ty(false), mutbl: MutImmutable })
         } else {
             ctor(self.parse_mt())
         }
@@ -1375,11 +1391,11 @@ impl Parser {
         let t = if self.eat(&token::COLON) {
             self.parse_ty(false)
         } else {
-            Ty {
+            P(Ty {
                 id: ast::DUMMY_NODE_ID,
                 node: ty_infer,
                 span: mk_sp(self.span.lo, self.span.hi),
-            }
+            })
         };
         ast::arg {
             ty: t,
@@ -1691,7 +1707,7 @@ impl Parser {
     pub fn mk_method_call(&self,
                       rcvr: @Expr,
                       ident: Ident,
-                      tps: ~[Ty],
+                      tps: ~[P<Ty>],
                       args: ~[@Expr],
                       sugar: CallSugar) -> ast::Expr_ {
         ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar)
@@ -1701,7 +1717,7 @@ impl Parser {
         ExprIndex(ast::DUMMY_NODE_ID, expr, idx)
     }
 
-    pub fn mk_field(&self, expr: @Expr, ident: Ident, tys: ~[Ty]) -> ast::Expr_ {
+    pub fn mk_field(&self, expr: @Expr, ident: Ident, tys: ~[P<Ty>]) -> ast::Expr_ {
         ExprField(expr, ident, tys)
     }
 
@@ -1784,14 +1800,14 @@ impl Parser {
         } else if self.eat_keyword(keywords::Proc) {
             let decl = self.parse_proc_decl();
             let body = self.parse_expr();
-            let fakeblock = ast::Block {
+            let fakeblock = P(ast::Block {
                 view_items: ~[],
                 stmts: ~[],
                 expr: Some(body),
                 id: ast::DUMMY_NODE_ID,
                 rules: DefaultBlock,
                 span: body.span,
-            };
+            });
 
             return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
         } else if self.eat_keyword(keywords::Self) {
@@ -2442,16 +2458,16 @@ impl Parser {
                   }
                   _ => {
                     // No argument list - `do foo {`
-                      ast::fn_decl {
+                      P(ast::fn_decl {
                           inputs: ~[],
-                          output: Ty {
+                          output: P(Ty {
                               id: ast::DUMMY_NODE_ID,
                               node: ty_infer,
                               span: *self.span
-                          },
+                          }),
                           cf: return_val,
                           variadic: false
-                      }
+                      })
                   }
                 }
             },
@@ -2471,20 +2487,20 @@ impl Parser {
     // this is used both in parsing a lambda expr
     // and in parsing a block expr as e.g. in for...
     pub fn parse_lambda_expr_(&self,
-                              parse_decl: || -> fn_decl,
+                              parse_decl: || -> P<fn_decl>,
                               parse_body: || -> @Expr)
                               -> @Expr {
         let lo = self.last_span.lo;
         let decl = parse_decl();
         let body = parse_body();
-        let fakeblock = ast::Block {
+        let fakeblock = P(ast::Block {
             view_items: ~[],
             stmts: ~[],
             expr: Some(body),
             id: ast::DUMMY_NODE_ID,
             rules: DefaultBlock,
             span: body.span,
-        };
+        });
 
         return self.mk_expr(lo, body.span.hi,
                             ExprFnBlock(decl, fakeblock));
@@ -2659,14 +2675,14 @@ impl Parser {
                 self.eat(&token::COMMA);
             }
 
-            let blk = ast::Block {
+            let blk = P(ast::Block {
                 view_items: ~[],
                 stmts: ~[],
                 expr: Some(expr),
                 id: ast::DUMMY_NODE_ID,
                 rules: DefaultBlock,
                 span: expr.span,
-            };
+            });
 
             arms.push(ast::Arm { pats: pats, guard: guard, body: blk });
         }
@@ -3132,11 +3148,11 @@ impl Parser {
         let lo = self.span.lo;
         let pat = self.parse_pat();
 
-        let mut ty = Ty {
+        let mut ty = P(Ty {
             id: ast::DUMMY_NODE_ID,
             node: ty_infer,
             span: mk_sp(lo, lo),
-        };
+        });
         if self.eat(&token::COLON) { ty = self.parse_ty(false); }
         let init = self.parse_initializer();
         @ast::Local {
@@ -3280,8 +3296,8 @@ impl Parser {
     }
 
     // parse a block. No inner attrs are allowed.
-    pub fn parse_block(&self) -> Block {
-        maybe_whole!(deref self, nt_block);
+    pub fn parse_block(&self) -> P<Block> {
+        maybe_whole!(no_clone self, nt_block);
 
         let lo = self.span.lo;
         if self.eat_keyword(keywords::Unsafe) {
@@ -3294,7 +3310,7 @@ impl Parser {
 
     // parse a block. Inner attrs are allowed.
     fn parse_inner_attrs_and_block(&self)
-        -> (~[Attribute], Block) {
+        -> (~[Attribute], P<Block>) {
 
         maybe_whole!(pair_empty self, nt_block);
 
@@ -3312,13 +3328,13 @@ impl Parser {
     // I guess that also means "already parsed the 'impure'" if
     // necessary, and this should take a qualifier.
     // some blocks start with "#{"...
-    fn parse_block_tail(&self, lo: BytePos, s: BlockCheckMode) -> Block {
+    fn parse_block_tail(&self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
         self.parse_block_tail_(lo, s, ~[])
     }
 
     // parse the rest of a block expression or function body
     fn parse_block_tail_(&self, lo: BytePos, s: BlockCheckMode,
-                         first_item_attrs: ~[Attribute]) -> Block {
+                         first_item_attrs: ~[Attribute]) -> P<Block> {
         let mut stmts = ~[];
         let mut expr = None;
 
@@ -3429,14 +3445,14 @@ impl Parser {
 
         let hi = self.span.hi;
         self.bump();
-        ast::Block {
+        P(ast::Block {
             view_items: view_items,
             stmts: stmts,
             expr: expr,
             id: ast::DUMMY_NODE_ID,
             rules: s,
             span: mk_sp(lo, hi),
-        }
+        })
     }
 
     fn parse_optional_purity(&self) -> ast::purity {
@@ -3516,7 +3532,7 @@ impl Parser {
     }
 
     // parse a generic use site
-    fn parse_generic_values(&self) -> (OptVec<ast::Lifetime>, ~[Ty]) {
+    fn parse_generic_values(&self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
         if !self.eat(&token::LT) {
             (opt_vec::Empty, ~[])
         } else {
@@ -3524,7 +3540,7 @@ impl Parser {
         }
     }
 
-    fn parse_generic_values_after_lt(&self) -> (OptVec<ast::Lifetime>, ~[Ty]) {
+    fn parse_generic_values_after_lt(&self) -> (OptVec<ast::Lifetime>, ~[P<Ty>]) {
         let lifetimes = self.parse_lifetimes();
         let result = self.parse_seq_to_gt(
             Some(token::COMMA),
@@ -3579,17 +3595,17 @@ impl Parser {
     }
 
     // parse the argument list and result type of a function declaration
-    pub fn parse_fn_decl(&self, allow_variadic: bool) -> fn_decl {
+    pub fn parse_fn_decl(&self, allow_variadic: bool) -> P<fn_decl> {
 
         let (args, variadic) = self.parse_fn_args(true, allow_variadic);
         let (ret_style, ret_ty) = self.parse_ret_ty();
 
-        ast::fn_decl {
+        P(ast::fn_decl {
             inputs: args,
             output: ret_ty,
             cf: ret_style,
             variadic: variadic
-        }
+        })
     }
 
     fn is_self_ident(&self) -> bool {
@@ -3614,7 +3630,7 @@ impl Parser {
     // parse the argument list and result type of a function
     // that may have a self type.
     fn parse_fn_decl_with_self(&self, parse_arg_fn: |&Parser| -> arg)
-                               -> (explicit_self, fn_decl) {
+                               -> (explicit_self, P<fn_decl>) {
         fn maybe_parse_explicit_self(cnstr: |v: Mutability| ->
                                         ast::explicit_self_,
                                      p: &Parser)
@@ -3775,18 +3791,18 @@ impl Parser {
 
         let (ret_style, ret_ty) = self.parse_ret_ty();
 
-        let fn_decl = ast::fn_decl {
+        let fn_decl = P(ast::fn_decl {
             inputs: fn_inputs,
             output: ret_ty,
             cf: ret_style,
             variadic: false
-        };
+        });
 
         (spanned(lo, hi, explicit_self), fn_decl)
     }
 
     // parse the |arg, arg| header on a lambda
-    fn parse_fn_block_decl(&self) -> fn_decl {
+    fn parse_fn_block_decl(&self) -> P<fn_decl> {
         let inputs_captures = {
             if self.eat(&token::OROR) {
                 ~[]
@@ -3802,19 +3818,19 @@ impl Parser {
         let output = if self.eat(&token::RARROW) {
             self.parse_ty(false)
         } else {
-            Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span }
+            P(Ty { id: ast::DUMMY_NODE_ID, node: ty_infer, span: *self.span })
         };
 
-        ast::fn_decl {
+        P(ast::fn_decl {
             inputs: inputs_captures,
             output: output,
             cf: return_val,
             variadic: false
-        }
+        })
     }
 
     // Parses the `(arg, arg) -> return_type` header on a procedure.
-    fn parse_proc_decl(&self) -> fn_decl {
+    fn parse_proc_decl(&self) -> P<fn_decl> {
         let inputs =
             self.parse_unspanned_seq(&token::LPAREN,
                                      &token::RPAREN,
@@ -3824,19 +3840,19 @@ impl Parser {
         let output = if self.eat(&token::RARROW) {
             self.parse_ty(false)
         } else {
-            Ty {
+            P(Ty {
                 id: ast::DUMMY_NODE_ID,
                 node: ty_infer,
                 span: *self.span,
-            }
+            })
         };
 
-        ast::fn_decl {
+        P(ast::fn_decl {
             inputs: inputs,
             output: output,
             cf: return_val,
             variadic: false
-        }
+        })
     }
 
     // parse the name and optional generic types of a function header.
@@ -4517,7 +4533,7 @@ impl Parser {
                 disr_expr: disr_expr,
                 vis: vis,
             };
-            variants.push(spanned(vlo, self.last_span.hi, vr));
+            variants.push(P(spanned(vlo, self.last_span.hi, vr)));
 
             if !self.eat(&token::COMMA) { break; }
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 8f8b956315f..04f03b4b58c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use ast;
-use ast::{Name, Mrk};
+use ast::{P, Name, Mrk};
 use ast_util;
 use parse::token;
 use util::interner::StrInterner;
@@ -101,11 +101,11 @@ pub enum Token {
 /// For interpolation during macro expansion.
 pub enum nonterminal {
     nt_item(@ast::item),
-    nt_block(~ast::Block),
+    nt_block(P<ast::Block>),
     nt_stmt(@ast::Stmt),
     nt_pat( @ast::Pat),
     nt_expr(@ast::Expr),
-    nt_ty(  ~ast::Ty),
+    nt_ty(  P<ast::Ty>),
     nt_ident(~ast::Ident, bool),
     nt_attr(@ast::Attribute),   // #[foo]
     nt_path(~ast::Path),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 9c1023c6cb8..9eb61728e59 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use abi::AbiSet;
-use ast::{RegionTyParamBound, TraitTyParamBound, required, provided};
+use ast::{P, RegionTyParamBound, TraitTyParamBound, required, provided};
 use ast;
 use ast_util;
 use opt_vec::OptVec;
@@ -418,7 +418,7 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
       }
       ast::ty_tup(ref elts) => {
         popen(s);
-        commasep(s, inconsistent, *elts, print_type);
+        commasep(s, inconsistent, *elts, print_type_ref);
         if elts.len() == 1 {
             word(s.s, ",");
         }
@@ -430,7 +430,7 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
             ty_params: opt_vec::Empty
           };
           print_ty_fn(s, Some(f.abis), None, &None,
-                      f.purity, ast::Many, &f.decl, None, &None,
+                      f.purity, ast::Many, f.decl, None, &None,
                       Some(&generics), None);
       }
       ast::ty_closure(f) => {
@@ -439,7 +439,7 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
             ty_params: opt_vec::Empty
           };
           print_ty_fn(s, None, Some(f.sigil), &f.region,
-                      f.purity, f.onceness, &f.decl, None, &f.bounds,
+                      f.purity, f.onceness, f.decl, None, &f.bounds,
                       Some(&generics), None);
       }
       ast::ty_path(ref path, ref bounds, _) => print_bounded_path(s, path, bounds),
@@ -467,19 +467,23 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
     end(s);
 }
 
+pub fn print_type_ref(s: @ps, ty: &P<ast::Ty>) {
+    print_type(s, *ty);
+}
+
 pub fn print_foreign_item(s: @ps, item: &ast::foreign_item) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, item.span.lo);
     print_outer_attributes(s, item.attrs);
     match item.node {
-      ast::foreign_item_fn(ref decl, ref generics) => {
+      ast::foreign_item_fn(decl, ref generics) => {
         print_fn(s, decl, None, AbiSet::Rust(), item.ident, generics, None,
                  item.vis);
         end(s); // end head-ibox
         word(s.s, ";");
         end(s); // end the outer fn box
       }
-      ast::foreign_item_static(ref t, m) => {
+      ast::foreign_item_static(t, m) => {
         head(s, visibility_qualified(item.vis, "static"));
         if m {
             word_space(s, "mut");
@@ -501,7 +505,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
     let ann_node = node_item(s, item);
     s.ann.pre(ann_node);
     match item.node {
-      ast::item_static(ref ty, m, expr) => {
+      ast::item_static(ty, m, expr) => {
         head(s, visibility_qualified(item.vis, "static"));
         if m == ast::MutMutable {
             word_space(s, "mut");
@@ -518,7 +522,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
         end(s); // end the outer cbox
 
       }
-      ast::item_fn(ref decl, purity, abi, ref typarams, ref body) => {
+      ast::item_fn(decl, purity, abi, ref typarams, body) => {
         print_fn(
             s,
             decl,
@@ -547,7 +551,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
         print_foreign_mod(s, nmod, item.attrs);
         bclose(s, item.span);
       }
-      ast::item_ty(ref ty, ref params) => {
+      ast::item_ty(ty, ref params) => {
         ibox(s, indent_unit);
         ibox(s, 0u);
         word_nbsp(s, visibility_qualified(item.vis, "type"));
@@ -576,7 +580,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
           print_struct(s, struct_def, generics, item.ident, item.span);
       }
 
-      ast::item_impl(ref generics, ref opt_trait, ref ty, ref methods) => {
+      ast::item_impl(ref generics, ref opt_trait, ty, ref methods) => {
         head(s, visibility_qualified(item.vis, "impl"));
         if generics.is_parameterized() {
             print_generics(s, generics);
@@ -655,10 +659,10 @@ pub fn print_enum_def(s: @ps, enum_definition: &ast::enum_def,
 }
 
 pub fn print_variants(s: @ps,
-                      variants: &[ast::variant],
+                      variants: &[P<ast::variant>],
                       span: codemap::Span) {
     bopen(s);
-    for v in variants.iter() {
+    for &v in variants.iter() {
         space_if_not_bol(s);
         maybe_print_comment(s, v.span.lo);
         print_outer_attributes(s, v.node.attrs);
@@ -709,7 +713,7 @@ pub fn print_struct(s: @ps,
                     ast::named_field(..) => fail!("unexpected named field"),
                     ast::unnamed_field => {
                         maybe_print_comment(s, field.span.lo);
-                        print_type(s, &field.node.ty);
+                        print_type(s, field.node.ty);
                     }
                 }
             });
@@ -733,7 +737,7 @@ pub fn print_struct(s: @ps,
                     print_visibility(s, visibility);
                     print_ident(s, ident);
                     word_nbsp(s, ":");
-                    print_type(s, &field.node.ty);
+                    print_type(s, field.node.ty);
                     word(s.s, ",");
                 }
             }
@@ -792,7 +796,7 @@ pub fn print_variant(s: @ps, v: &ast::variant) {
             if !args.is_empty() {
                 popen(s);
                 fn print_variant_arg(s: @ps, arg: &ast::variant_arg) {
-                    print_type(s, &arg.ty);
+                    print_type(s, arg.ty);
                 }
                 commasep(s, consistent, *args, print_variant_arg);
                 pclose(s);
@@ -824,7 +828,7 @@ pub fn print_ty_method(s: @ps, m: &ast::TypeMethod) {
                 &None,
                 m.purity,
                 ast::Many,
-                &m.decl,
+                m.decl,
                 Some(m.ident),
                 &None,
                 Some(&m.generics),
@@ -843,11 +847,11 @@ pub fn print_method(s: @ps, meth: &ast::method) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, meth.span.lo);
     print_outer_attributes(s, meth.attrs);
-    print_fn(s, &meth.decl, Some(meth.purity), AbiSet::Rust(),
+    print_fn(s, meth.decl, Some(meth.purity), AbiSet::Rust(),
              meth.ident, &meth.generics, Some(meth.explicit_self.node),
              meth.vis);
     word(s.s, " ");
-    print_block_with_attrs(s, &meth.body, meth.attrs);
+    print_block_with_attrs(s, meth.body, meth.attrs);
 }
 
 pub fn print_outer_attributes(s: @ps, attrs: &[ast::Attribute]) {
@@ -996,7 +1000,7 @@ pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block,
           Some(_else) => {
             match _else.node {
               // "another else-if"
-              ast::ExprIf(i, ref t, e) => {
+              ast::ExprIf(i, t, e) => {
                 cbox(s, indent_unit - 1u);
                 ibox(s, 0u);
                 word(s.s, " else if ");
@@ -1006,7 +1010,7 @@ pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block,
                 do_else(s, e);
               }
               // "final else"
-              ast::ExprBlock(ref b) => {
+              ast::ExprBlock(b) => {
                 cbox(s, indent_unit - 1u);
                 ibox(s, 0u);
                 word(s.s, " else ");
@@ -1195,7 +1199,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         print_ident(s, ident);
         if tys.len() > 0u {
             word(s.s, "::<");
-            commasep(s, inconsistent, *tys, print_type);
+            commasep(s, inconsistent, *tys, print_type_ref);
             word(s.s, ">");
         }
         print_call_post(s, sugar, &blk, &mut base_args);
@@ -1221,22 +1225,22 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         print_expr(s, expr);
       }
       ast::ExprLit(lit) => print_literal(s, lit),
-      ast::ExprCast(expr, ref ty) => {
+      ast::ExprCast(expr, ty) => {
         print_expr(s, expr);
         space(s.s);
         word_space(s, "as");
         print_type(s, ty);
       }
-      ast::ExprIf(test, ref blk, elseopt) => {
+      ast::ExprIf(test, blk, elseopt) => {
         print_if(s, test, blk, elseopt, false);
       }
-      ast::ExprWhile(test, ref blk) => {
+      ast::ExprWhile(test, blk) => {
         head(s, "while");
         print_expr(s, test);
         space(s.s);
         print_block(s, blk);
       }
-      ast::ExprForLoop(pat, iter, ref blk, opt_ident) => {
+      ast::ExprForLoop(pat, iter, blk, opt_ident) => {
         for ident in opt_ident.iter() {
             word(s.s, "'");
             print_ident(s, *ident);
@@ -1250,7 +1254,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         space(s.s);
         print_block(s, blk);
       }
-      ast::ExprLoop(ref blk, opt_ident) => {
+      ast::ExprLoop(blk, opt_ident) => {
         for ident in opt_ident.iter() {
             word(s.s, "'");
             print_ident(s, *ident);
@@ -1300,7 +1304,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
                 match arm.body.expr {
                     Some(expr) => {
                         match expr.node {
-                            ast::ExprBlock(ref blk) => {
+                            ast::ExprBlock(blk) => {
                                 // the block will close the pattern's ibox
                                 print_block_unclosed_indent(
                                     s, blk, indent_unit);
@@ -1320,12 +1324,12 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
                 }
             } else {
                 // the block will close the pattern's ibox
-                print_block_unclosed_indent(s, &arm.body, indent_unit);
+                print_block_unclosed_indent(s, arm.body, indent_unit);
             }
         }
         bclose_(s, expr.span, indent_unit);
       }
-      ast::ExprFnBlock(ref decl, ref body) => {
+      ast::ExprFnBlock(decl, body) => {
         // in do/for blocks we don't want to show an empty
         // argument list, but at this point we don't know which
         // we are inside.
@@ -1338,7 +1342,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         assert!(body.expr.is_some());
         // we extract the block, so as not to create another set of boxes
         match body.expr.unwrap().node {
-            ast::ExprBlock(ref blk) => {
+            ast::ExprBlock(blk) => {
                 print_block_unclosed(s, blk);
             }
             _ => {
@@ -1352,7 +1356,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         // empty box to satisfy the close.
         ibox(s, 0);
       }
-      ast::ExprProc(ref decl, ref body) => {
+      ast::ExprProc(decl, body) => {
         // in do/for blocks we don't want to show an empty
         // argument list, but at this point we don't know which
         // we are inside.
@@ -1365,7 +1369,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         assert!(body.expr.is_some());
         // we extract the block, so as not to create another set of boxes
         match body.expr.unwrap().node {
-            ast::ExprBlock(ref blk) => {
+            ast::ExprBlock(blk) => {
                 print_block_unclosed(s, blk);
             }
             _ => {
@@ -1382,7 +1386,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
       ast::ExprDoBody(body) => {
         print_expr(s, body);
       }
-      ast::ExprBlock(ref blk) => {
+      ast::ExprBlock(blk) => {
         // containing cbox, will be closed by print-block at }
         cbox(s, indent_unit);
         // head-box, will be closed by print-block after {
@@ -1408,7 +1412,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
         print_ident(s, id);
         if tys.len() > 0u {
             word(s.s, "::<");
-            commasep(s, inconsistent, *tys, print_type);
+            commasep(s, inconsistent, *tys, print_type_ref);
             word(s.s, ">");
         }
       }
@@ -1493,7 +1497,7 @@ pub fn print_local_decl(s: @ps, loc: &ast::Local) {
     print_pat(s, loc.pat);
     match loc.ty.node {
       ast::ty_infer => (),
-      _ => { word_space(s, ":"); print_type(s, &loc.ty); }
+      _ => { word_space(s, ":"); print_type(s, loc.ty); }
     }
 }
 
@@ -1589,8 +1593,8 @@ fn print_path_(s: @ps,
                 }
                 commasep(s,
                          inconsistent,
-                         segment.types.map_to_vec(|t| (*t).clone()),
-                         print_type);
+                         segment.types.map_to_vec(|&t| t),
+                         print_type_ref);
             }
 
             word(s.s, ">")
@@ -1796,7 +1800,7 @@ pub fn print_fn_args_and_ret(s: @ps, decl: &ast::fn_decl,
         _ => {
             space_if_not_bol(s);
             word_space(s, "->");
-            print_type(s, &decl.output);
+            print_type(s, decl.output);
         }
     }
 }
@@ -1811,7 +1815,7 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) {
         _ => {
             space_if_not_bol(s);
             word_space(s, "->");
-            print_type(s, &decl.output);
+            print_type(s, decl.output);
         }
     }
 
@@ -1829,7 +1833,7 @@ pub fn print_proc_args(s: @ps, decl: &ast::fn_decl) {
         _ => {
             space_if_not_bol(s);
             word_space(s, "->");
-            print_type(s, &decl.output);
+            print_type(s, decl.output);
         }
     }
 
@@ -2007,7 +2011,7 @@ pub fn print_arg(s: @ps, input: &ast::arg) {
                 space(s.s);
             }
         }
-        print_type(s, &input.ty);
+        print_type(s, input.ty);
       }
     }
     end(s);
@@ -2094,7 +2098,7 @@ pub fn print_ty_fn(s: @ps,
             ibox(s, indent_unit);
             word_space(s, "->");
             if decl.cf == ast::noreturn { word_nbsp(s, "!"); }
-            else { print_type(s, &decl.output); }
+            else { print_type(s, decl.output); }
             end(s);
         }
     }
@@ -2419,9 +2423,9 @@ mod test {
 
         let decl = ast::fn_decl {
             inputs: ~[],
-            output: ast::Ty {id: 0,
-                              node: ast::ty_nil,
-                              span: codemap::dummy_sp()},
+            output: ast::P(ast::Ty {id: 0,
+                                    node: ast::ty_nil,
+                                    span: codemap::dummy_sp()}),
             cf: ast::return_val,
             variadic: false
         };
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 4100104dd61..e5a06c46d06 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -75,7 +75,7 @@ pub trait Visitor<E:Clone> {
     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_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) }
@@ -84,7 +84,7 @@ pub trait Visitor<E:Clone> {
     fn visit_expr_post(&mut self, _ex:@Expr, _e:E) { }
     fn visit_ty(&mut self, _t:&Ty, _e:E) { }
     fn visit_generics(&mut self, g:&Generics, e:E) { walk_generics(self, g, e) }
-    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:Span, n:NodeId, e:E) {
+    fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:P<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) }
@@ -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) {
     visitor.visit_pat(local.pat, env.clone());
-    visitor.visit_ty(&local.ty, env.clone());
+    visitor.visit_ty(local.ty, env.clone());
     match local.init {
         None => {}
         Some(initializer) => visitor.visit_expr(initializer, env),
@@ -192,11 +192,11 @@ fn walk_trait_ref<E:Clone, V:Visitor<E>>(visitor: &mut V,
 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(ref typ, _, expr) => {
+        item_static(typ, _, expr) => {
             visitor.visit_ty(typ, env.clone());
             visitor.visit_expr(expr, env);
         }
-        item_fn(ref declaration, purity, abi, ref generics, ref body) => {
+        item_fn(declaration, purity, abi, ref generics, body) => {
             visitor.visit_fn(&fk_item_fn(item.ident, generics, purity, abi),
                              declaration,
                              body,
@@ -215,7 +215,7 @@ pub fn walk_item<E:Clone, V:Visitor<E>>(visitor: &mut V, item: &item, env: E) {
                 visitor.visit_foreign_item(*foreign_item, env.clone())
             }
         }
-        item_ty(ref typ, ref type_parameters) => {
+        item_ty(typ, ref type_parameters) => {
             visitor.visit_ty(typ, env.clone());
             visitor.visit_generics(type_parameters, env)
         }
@@ -225,7 +225,7 @@ pub fn walk_item<E:Clone, V:Visitor<E>>(visitor: &mut V, item: &item, env: E) {
         }
         item_impl(ref type_parameters,
                   ref trait_references,
-                  ref typ,
+                  typ,
                   ref methods) => {
             visitor.visit_generics(type_parameters, env.clone());
             for trait_reference in trait_references.iter() {
@@ -261,7 +261,7 @@ pub fn walk_enum_def<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                enum_definition: &ast::enum_def,
                                generics: &Generics,
                                env: E) {
-    for variant in enum_definition.variants.iter() {
+    for &variant in enum_definition.variants.iter() {
         visitor.visit_variant(variant, generics, env.clone());
     }
 }
@@ -275,7 +275,7 @@ pub fn walk_variant<E:Clone, V:Visitor<E>>(visitor:&mut V,
     match variant.node.kind {
         tuple_variant_kind(ref variant_arguments) => {
             for variant_argument in variant_arguments.iter() {
-                visitor.visit_ty(&variant_argument.ty, env.clone())
+                visitor.visit_ty(variant_argument.ty, env.clone())
             }
         }
         struct_variant_kind(struct_definition) => {
@@ -303,15 +303,15 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
             visitor.visit_ty(mutable_type.ty, env)
         }
         ty_tup(ref tuple_element_types) => {
-            for tuple_element_type in tuple_element_types.iter() {
+            for &tuple_element_type in tuple_element_types.iter() {
                 visitor.visit_ty(tuple_element_type, env.clone())
             }
         }
         ty_closure(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
-                visitor.visit_ty(&argument.ty, env.clone())
+                visitor.visit_ty(argument.ty, env.clone())
             }
-            visitor.visit_ty(&function_declaration.decl.output, env.clone());
+            visitor.visit_ty(function_declaration.decl.output, env.clone());
             for bounds in function_declaration.bounds.iter() {
                 walk_ty_param_bounds(visitor, bounds, env.clone())
             }
@@ -324,9 +324,9 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
         }
         ty_bare_fn(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
-                visitor.visit_ty(&argument.ty, env.clone())
+                visitor.visit_ty(argument.ty, env.clone())
             }
-            visitor.visit_ty(&function_declaration.decl.output, env.clone());
+            visitor.visit_ty(function_declaration.decl.output, env.clone());
             walk_lifetime_decls(visitor, &function_declaration.lifetimes,
                                 env.clone());
         }
@@ -359,7 +359,7 @@ 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());
 
-        for typ in segment.types.iter() {
+        for &typ in segment.types.iter() {
             visitor.visit_ty(typ, env.clone());
         }
         for lifetime in segment.lifetimes.iter() {
@@ -427,11 +427,11 @@ pub fn walk_foreign_item<E:Clone, V:Visitor<E>>(visitor: &mut V,
     visitor.visit_ident(foreign_item.span, foreign_item.ident, env.clone());
 
     match foreign_item.node {
-        foreign_item_fn(ref function_declaration, ref generics) => {
+        foreign_item_fn(function_declaration, ref generics) => {
             walk_fn_decl(visitor, function_declaration, env.clone());
             visitor.visit_generics(generics, env)
         }
-        foreign_item_static(ref typ, _) => visitor.visit_ty(typ, env),
+        foreign_item_static(typ, _) => visitor.visit_ty(typ, env),
     }
 }
 
@@ -462,9 +462,9 @@ pub fn walk_fn_decl<E:Clone, V:Visitor<E>>(visitor: &mut V,
                               env: E) {
     for argument in function_declaration.inputs.iter() {
         visitor.visit_pat(argument.pat, env.clone());
-        visitor.visit_ty(&argument.ty, env.clone())
+        visitor.visit_ty(argument.ty, env.clone())
     }
-    visitor.visit_ty(&function_declaration.output, env)
+    visitor.visit_ty(function_declaration.output, env)
 }
 
 // Note: there is no visit_method() method in the visitor, instead override
@@ -476,8 +476,8 @@ pub fn walk_method_helper<E:Clone, V:Visitor<E>>(visitor: &mut V,
                                     env: E) {
     visitor.visit_ident(method.span, method.ident, env.clone());
     visitor.visit_fn(&fk_method(method.ident, &method.generics, method),
-                     &method.decl,
-                     &method.body,
+                     method.decl,
+                     method.body,
                      method.span,
                      method.id,
                      env)
@@ -486,7 +486,7 @@ pub fn walk_method_helper<E:Clone, V:Visitor<E>>(visitor: &mut V,
 pub fn walk_fn<E:Clone, V:Visitor<E>>(visitor: &mut V,
                          function_kind: &fn_kind,
                          function_declaration: &fn_decl,
-                         function_body: &Block,
+                         function_body: P<Block>,
                          _span: Span,
                          _: NodeId,
                          env: E) {
@@ -514,10 +514,10 @@ pub fn walk_ty_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
     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() {
-        visitor.visit_ty(&argument_type.ty, env.clone())
+        visitor.visit_ty(argument_type.ty, env.clone())
     }
     visitor.visit_generics(&method_type.generics, env.clone());
-    visitor.visit_ty(&method_type.decl.output, env);
+    visitor.visit_ty(method_type.decl.output, env);
 }
 
 pub fn walk_trait_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
@@ -552,10 +552,10 @@ pub fn walk_struct_field<E:Clone, V:Visitor<E>>(visitor: &mut V,
         _ => {}
     }
 
-    visitor.visit_ty(&struct_field.node.ty, env)
+    visitor.visit_ty(struct_field.node.ty, env)
 }
 
-pub fn walk_block<E:Clone, V:Visitor<E>>(visitor: &mut V, block: &Block, env: E) {
+pub fn walk_block<E:Clone, V:Visitor<E>>(visitor: &mut V, block: P<Block>, env: E) {
     for view_item in block.view_items.iter() {
         visitor.visit_view_item(view_item, env.clone())
     }
@@ -635,7 +635,7 @@ pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env:
         }
         ExprMethodCall(_, callee, _, ref types, ref arguments, _) => {
             walk_exprs(visitor, *arguments, env.clone());
-            for typ in types.iter() {
+            for &typ in types.iter() {
                 visitor.visit_ty(typ, env.clone())
             }
             visitor.visit_expr(callee, env.clone())
@@ -650,32 +650,32 @@ pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env:
             visitor.visit_expr(subexpression, env.clone())
         }
         ExprLit(_) => {}
-        ExprCast(subexpression, ref typ) => {
+        ExprCast(subexpression, typ) => {
             visitor.visit_expr(subexpression, env.clone());
             visitor.visit_ty(typ, env.clone())
         }
-        ExprIf(head_expression, ref if_block, optional_else) => {
+        ExprIf(head_expression, if_block, optional_else) => {
             visitor.visit_expr(head_expression, env.clone());
             visitor.visit_block(if_block, env.clone());
             walk_expr_opt(visitor, optional_else, env.clone())
         }
-        ExprWhile(subexpression, ref block) => {
+        ExprWhile(subexpression, block) => {
             visitor.visit_expr(subexpression, env.clone());
             visitor.visit_block(block, env.clone())
         }
-        ExprForLoop(pattern, subexpression, ref block, _) => {
+        ExprForLoop(pattern, subexpression, block, _) => {
             visitor.visit_pat(pattern, env.clone());
             visitor.visit_expr(subexpression, env.clone());
             visitor.visit_block(block, env.clone())
         }
-        ExprLoop(ref block, _) => visitor.visit_block(block, env.clone()),
+        ExprLoop(block, _) => visitor.visit_block(block, env.clone()),
         ExprMatch(subexpression, ref arms) => {
             visitor.visit_expr(subexpression, env.clone());
             for arm in arms.iter() {
                 visitor.visit_arm(arm, env.clone())
             }
         }
-        ExprFnBlock(ref function_declaration, ref body) => {
+        ExprFnBlock(function_declaration, body) => {
             visitor.visit_fn(&fk_fn_block,
                              function_declaration,
                              body,
@@ -683,7 +683,7 @@ pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env:
                              expression.id,
                              env.clone())
         }
-        ExprProc(ref function_declaration, ref body) => {
+        ExprProc(function_declaration, body) => {
             visitor.visit_fn(&fk_fn_block,
                              function_declaration,
                              body,
@@ -691,7 +691,7 @@ pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env:
                              expression.id,
                              env.clone())
         }
-        ExprBlock(ref block) => visitor.visit_block(block, env.clone()),
+        ExprBlock(block) => visitor.visit_block(block, env.clone()),
         ExprAssign(left_hand_expression, right_hand_expression) => {
             visitor.visit_expr(right_hand_expression, env.clone());
             visitor.visit_expr(left_hand_expression, env.clone())
@@ -702,7 +702,7 @@ pub fn walk_expr<E:Clone, V:Visitor<E>>(visitor: &mut V, expression: @Expr, env:
         }
         ExprField(subexpression, _, ref types) => {
             visitor.visit_expr(subexpression, env.clone());
-            for typ in types.iter() {
+            for &typ in types.iter() {
                 visitor.visit_ty(typ, env.clone())
             }
         }
@@ -738,5 +738,5 @@ pub fn walk_arm<E:Clone, V:Visitor<E>>(visitor: &mut V, arm: &Arm, env: E) {
         visitor.visit_pat(*pattern, env.clone())
     }
     walk_expr_opt(visitor, arm.guard, env.clone());
-    visitor.visit_block(&arm.body, env)
+    visitor.visit_block(arm.body, env)
 }