about summary refs log tree commit diff
path: root/src/libsyntax/ext/deriving
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2014-09-13 19:06:01 +0300
committerEduard Burtescu <edy.burt@gmail.com>2014-09-14 03:39:36 +0300
commitccd8498afbb371939b7decdbee712f726ccbded3 (patch)
tree8939c9dba98ee7a2f624e82c3c72dcf33576d350 /src/libsyntax/ext/deriving
parentd6fb338d01864e3801cab9f76d608f204d11fc27 (diff)
downloadrust-ccd8498afbb371939b7decdbee712f726ccbded3.tar.gz
rust-ccd8498afbb371939b7decdbee712f726ccbded3.zip
syntax: fix fallout from using ptr::P.
Diffstat (limited to 'src/libsyntax/ext/deriving')
-rw-r--r--src/libsyntax/ext/deriving/bounds.rs9
-rw-r--r--src/libsyntax/ext/deriving/clone.rs13
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs13
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs23
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs12
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs13
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs27
-rw-r--r--src/libsyntax/ext/deriving/default.rs12
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs27
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs264
-rw-r--r--src/libsyntax/ext/deriving/generic/ty.rs7
-rw-r--r--src/libsyntax/ext/deriving/hash.rs22
-rw-r--r--src/libsyntax/ext/deriving/mod.rs13
-rw-r--r--src/libsyntax/ext/deriving/primitive.rs20
-rw-r--r--src/libsyntax/ext/deriving/rand.rs22
-rw-r--r--src/libsyntax/ext/deriving/show.rs19
-rw-r--r--src/libsyntax/ext/deriving/zero.rs12
17 files changed, 253 insertions, 275 deletions
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 7cff6e8ff3c..0595b0bc7f4 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -13,14 +13,13 @@ use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_bound(cx: &mut ExtCtxt,
                              span: Span,
-                             mitem: Gc<MetaItem>,
-                             item: Gc<Item>,
-                             push: |Gc<Item>|) {
+                             mitem: &MetaItem,
+                             item: &Item,
+                             push: |P<Item>|) {
 
     let name = match mitem.node {
         MetaWord(ref tname) => {
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index bbe96018f4b..64607ffd5d4 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -15,14 +15,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                              span: Span,
-                             mitem: Gc<MetaItem>,
-                             item: Gc<Item>,
-                             push: |Gc<Item>|) {
+                             mitem: &MetaItem,
+                             item: &Item,
+                             push: |P<Item>|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
@@ -52,12 +51,12 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
 fn cs_clone(
     name: &str,
     cx: &mut ExtCtxt, trait_span: Span,
-    substr: &Substructure) -> Gc<Expr> {
+    substr: &Substructure) -> P<Expr> {
     let clone_ident = substr.method_ident;
     let ctor_ident;
     let all_fields;
     let subcall = |field: &FieldInfo|
-        cx.expr_method_call(field.span, field.self_, clone_ident, Vec::new());
+        cx.expr_method_call(field.span, field.self_.clone(), clone_ident, Vec::new());
 
     match *substr.fields {
         Struct(ref af) => {
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index 19a979a5655..a27016fde61 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -15,21 +15,20 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_eq(cx: &mut ExtCtxt,
                           span: Span,
-                          mitem: Gc<MetaItem>,
-                          item: Gc<Item>,
-                          push: |Gc<Item>|) {
+                          mitem: &MetaItem,
+                          item: &Item,
+                          push: |P<Item>|) {
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
-    fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> {
+    fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
         cs_and(|cx, span, _, _| cx.expr_bool(span, false),
                                  cx, span, substr)
     }
-    fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> {
+    fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
         cs_or(|cx, span, _, _| cx.expr_bool(span, true),
               cx, span, substr)
     }
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index dcf59ba820e..7cb61d295c0 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -16,14 +16,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_ord(cx: &mut ExtCtxt,
                            span: Span,
-                           mitem: Gc<MetaItem>,
-                           item: Gc<Item>,
-                           push: |Gc<Item>|) {
+                           mitem: &MetaItem,
+                           item: &Item,
+                           push: |P<Item>|) {
     macro_rules! md (
         ($name:expr, $op:expr, $equal:expr) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
@@ -87,7 +86,7 @@ pub enum OrderingOp {
 pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
                                span: Span,
                                op: OrderingOp,
-                               self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> {
+                               self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
     let op_str = match op {
@@ -99,7 +98,7 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
 }
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
-              substr: &Substructure) -> Gc<Expr> {
+              substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__test");
     let ordering = cx.path_global(span,
                                   vec!(cx.ident_of("std"),
@@ -159,8 +158,8 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
 }
 
 /// Strict inequality.
-fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
-         substr: &Substructure) -> Gc<Expr> {
+fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
+         span: Span, substr: &Substructure) -> P<Expr> {
     let op = if less {ast::BiLt} else {ast::BiGt};
     cs_fold(
         false, // need foldr,
@@ -183,14 +182,14 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
             layers of pointers, if the type includes pointers.
             */
             let other_f = match other_fs {
-                [o_f] => o_f,
+                [ref o_f] => o_f,
                 _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
             };
 
-            let cmp = cx.expr_binary(span, op, self_f, other_f);
+            let cmp = cx.expr_binary(span, op, self_f.clone(), other_f.clone());
 
             let not_cmp = cx.expr_unary(span, ast::UnNot,
-                                        cx.expr_binary(span, op, other_f, self_f));
+                                        cx.expr_binary(span, op, other_f.clone(), self_f));
 
             let and = cx.expr_binary(span, ast::BiAnd, not_cmp, subexpr);
             cx.expr_binary(span, ast::BiOr, cmp, and)
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index 42365936c9d..98c8885f7fa 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -15,16 +15,14 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
                                span: Span,
-                               mitem: Gc<MetaItem>,
-                               item: Gc<Item>,
-                               push: |Gc<Item>|) {
-    fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span,
-                          substr: &Substructure) -> Gc<Expr> {
+                               mitem: &MetaItem,
+                               item: &Item,
+                               push: |P<Item>|) {
+    fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
         cs_same_method(|cx, span, exprs| {
             // create `a.<method>(); b.<method>(); c.<method>(); ...`
             // (where method is `assert_receiver_is_total_eq`)
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index e010b635fe4..9ef463f9c63 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -16,14 +16,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                                 span: Span,
-                                mitem: Gc<MetaItem>,
-                                item: Gc<Item>,
-                                push: |Gc<Item>|) {
+                                mitem: &MetaItem,
+                                item: &Item,
+                                push: |P<Item>|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
@@ -53,14 +52,14 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
 
 pub fn ordering_collapsed(cx: &mut ExtCtxt,
                           span: Span,
-                          self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> {
+                          self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
     cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
 }
 
 pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
-              substr: &Substructure) -> Gc<Expr> {
+              substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__test");
     let equals_path = cx.path_global(span,
                                      vec!(cx.ident_of("std"),
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index d909ffd2b49..fd24f5e35a4 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -21,14 +21,13 @@ use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
 use parse::token;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                                  span: Span,
-                                 mitem: Gc<MetaItem>,
-                                 item: Gc<Item>,
-                                 push: |Gc<Item>|) {
+                                 mitem: &MetaItem,
+                                 item: &Item,
+                                 push: |P<Item>|) {
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -64,15 +63,15 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
 }
 
 fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
-                          substr: &Substructure) -> Gc<Expr> {
-    let decoder = substr.nonself_args[0];
+                          substr: &Substructure) -> P<Expr> {
+    let decoder = substr.nonself_args[0].clone();
     let recurse = vec!(cx.ident_of("serialize"),
                     cx.ident_of("Decodable"),
                     cx.ident_of("decode"));
     // throw an underscore in front to suppress unused variable warnings
     let blkarg = cx.ident_of("_d");
     let blkdecoder = cx.expr_ident(trait_span, blkarg);
-    let calldecode = cx.expr_call_global(trait_span, recurse, vec!(blkdecoder));
+    let calldecode = cx.expr_call_global(trait_span, recurse, vec!(blkdecoder.clone()));
     let lambdadecode = cx.lambda_expr_1(trait_span, calldecode, blkarg);
 
     return match *substr.fields {
@@ -89,10 +88,10 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                               summary,
                                               |cx, span, name, field| {
                 cx.expr_try(span,
-                    cx.expr_method_call(span, blkdecoder, read_struct_field,
+                    cx.expr_method_call(span, blkdecoder.clone(), read_struct_field,
                                         vec!(cx.expr_str(span, name),
                                           cx.expr_uint(span, field),
-                                          lambdadecode)))
+                                          lambdadecode.clone())))
             });
             let result = cx.expr_ok(trait_span, result);
             cx.expr_method_call(trait_span,
@@ -121,8 +120,8 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                    |cx, span, _, field| {
                     let idx = cx.expr_uint(span, field);
                     cx.expr_try(span,
-                        cx.expr_method_call(span, blkdecoder, rvariant_arg,
-                                            vec!(idx, lambdadecode)))
+                        cx.expr_method_call(span, blkdecoder.clone(), rvariant_arg,
+                                            vec!(idx, lambdadecode.clone())))
                 });
 
                 arms.push(cx.arm(v_span,
@@ -159,8 +158,8 @@ fn decode_static_fields(cx: &mut ExtCtxt,
                         trait_span: Span,
                         outer_pat_ident: Ident,
                         fields: &StaticFields,
-                        getarg: |&mut ExtCtxt, Span, InternedString, uint| -> Gc<Expr>)
-                        -> Gc<Expr> {
+                        getarg: |&mut ExtCtxt, Span, InternedString, uint| -> P<Expr>)
+                        -> P<Expr> {
     match *fields {
         Unnamed(ref fields) => {
             if fields.is_empty() {
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index f7d0308e1bd..f4a66414d89 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -15,14 +15,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_default(cx: &mut ExtCtxt,
                             span: Span,
-                            mitem: Gc<MetaItem>,
-                            item: Gc<Item>,
-                            push: |Gc<Item>|) {
+                            mitem: &MetaItem,
+                            item: &Item,
+                            push: |P<Item>|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
@@ -47,8 +46,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-fn default_substructure(cx: &mut ExtCtxt, trait_span: Span,
-                        substr: &Substructure) -> Gc<Expr> {
+fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
     let default_ident = vec!(
         cx.ident_of("std"),
         cx.ident_of("default"),
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 02a748eed8e..103253560df 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -86,14 +86,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                  span: Span,
-                                 mitem: Gc<MetaItem>,
-                                 item: Gc<Item>,
-                                 push: |Gc<Item>|) {
+                                 mitem: &MetaItem,
+                                 item: &Item,
+                                 push: |P<Item>|) {
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -131,8 +130,8 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
 }
 
 fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
-                          substr: &Substructure) -> Gc<Expr> {
-    let encoder = substr.nonself_args[0];
+                          substr: &Substructure) -> P<Expr> {
+    let encoder = substr.nonself_args[0].clone();
     // throw an underscore in front to suppress unused variable warnings
     let blkarg = cx.ident_of("_e");
     let blkencoder = cx.expr_ident(trait_span, blkarg);
@@ -145,7 +144,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             let last = fields.len() - 1;
             for (i, &FieldInfo {
                     name,
-                    self_,
+                    ref self_,
                     span,
                     ..
                 }) in fields.iter().enumerate() {
@@ -156,9 +155,10 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                             i).as_slice())
                     }
                 };
-                let enc = cx.expr_method_call(span, self_, encode, vec!(blkencoder));
+                let enc = cx.expr_method_call(span, self_.clone(),
+                                              encode, vec!(blkencoder.clone()));
                 let lambda = cx.lambda_expr_1(span, enc, blkarg);
-                let call = cx.expr_method_call(span, blkencoder,
+                let call = cx.expr_method_call(span, blkencoder.clone(),
                                                emit_struct_field,
                                                vec!(cx.expr_str(span, name),
                                                  cx.expr_uint(span, i),
@@ -202,10 +202,11 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
             let mut stmts = Vec::new();
             let last = fields.len() - 1;
-            for (i, &FieldInfo { self_, span, .. }) in fields.iter().enumerate() {
-                let enc = cx.expr_method_call(span, self_, encode, vec!(blkencoder));
+            for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
+                let enc = cx.expr_method_call(span, self_.clone(),
+                                              encode, vec!(blkencoder.clone()));
                 let lambda = cx.lambda_expr_1(span, enc, blkarg);
-                let call = cx.expr_method_call(span, blkencoder,
+                let call = cx.expr_method_call(span, blkencoder.clone(),
                                                emit_variant_arg,
                                                vec!(cx.expr_uint(span, i),
                                                  lambda));
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index 50bdc296aad..53af5a86ed2 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -181,12 +181,13 @@
 //! ~~~
 
 use std::cell::RefCell;
-use std::gc::{Gc, GC};
+use std::gc::GC;
+use std::vec;
 
 use abi::Abi;
 use abi;
 use ast;
-use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
+use ast::{EnumDef, Expr, Ident, Generics, StructDef};
 use ast_util;
 use attr;
 use attr::AttrMetaMethods;
@@ -194,9 +195,11 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use codemap;
 use codemap::Span;
+use fold::MoveMap;
 use owned_slice::OwnedSlice;
 use parse::token::InternedString;
 use parse::token::special_idents;
+use ptr::P;
 
 use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self, Ty};
 
@@ -251,9 +254,9 @@ pub struct Substructure<'a> {
     /// ident of the method
     pub method_ident: Ident,
     /// dereferenced access to any Self or Ptr(Self, _) arguments
-    pub self_args: &'a [Gc<Expr>],
+    pub self_args: &'a [P<Expr>],
     /// verbatim access to any other arguments
-    pub nonself_args: &'a [Gc<Expr>],
+    pub nonself_args: &'a [P<Expr>],
     pub fields: &'a SubstructureFields<'a>
 }
 
@@ -265,10 +268,10 @@ pub struct FieldInfo {
     pub name: Option<Ident>,
     /// The expression corresponding to this field of `self`
     /// (specifically, a reference to it).
-    pub self_: Gc<Expr>,
+    pub self_: P<Expr>,
     /// The expressions corresponding to references to this field in
     /// the other Self arguments.
-    pub other: Vec<Gc<Expr>>,
+    pub other: Vec<P<Expr>>,
 }
 
 /// Fields for a static method
@@ -298,7 +301,7 @@ pub enum SubstructureFields<'a> {
     Idents bound to the variant index values for each of the actual
     input Self arguments.
     */
-    EnumNonMatchingCollapsed(Vec<Ident>, &'a [Gc<ast::Variant>], &'a [Ident]),
+    EnumNonMatchingCollapsed(Vec<Ident>, &'a [P<ast::Variant>], &'a [Ident]),
 
     /// A static method where Self is a struct.
     StaticStruct(&'a ast::StructDef, StaticFields),
@@ -313,7 +316,7 @@ Combine the values of all the fields together. The last argument is
 all the fields of all the structures, see above for details.
 */
 pub type CombineSubstructureFunc<'a> =
-    |&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>;
+    |&mut ExtCtxt, Span, &Substructure|: 'a -> P<Expr>;
 
 /**
 Deal with non-matching enum variants.  The tuple is a list of
@@ -324,10 +327,10 @@ last argument is all the non-Self args of the method being derived.
 */
 pub type EnumNonMatchCollapsedFunc<'a> =
     |&mut ExtCtxt,
-           Span,
-           (&[Ident], &[Ident]),
-           &[Gc<Expr>]|: 'a
-           -> Gc<Expr>;
+     Span,
+     (&[Ident], &[Ident]),
+     &[P<Expr>]|: 'a
+     -> P<Expr>;
 
 pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
     -> RefCell<CombineSubstructureFunc<'a>> {
@@ -338,9 +341,9 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
 impl<'a> TraitDef<'a> {
     pub fn expand(&self,
                   cx: &mut ExtCtxt,
-                  _mitem: Gc<ast::MetaItem>,
-                  item: Gc<ast::Item>,
-                  push: |Gc<ast::Item>|) {
+                  _mitem: &ast::MetaItem,
+                  item: &ast::Item,
+                  push: |P<ast::Item>|) {
         let newitem = match item.node {
             ast::ItemStruct(ref struct_def, ref generics) => {
                 self.expand_struct_def(cx,
@@ -365,10 +368,10 @@ impl<'a> TraitDef<'a> {
                 _ => false,
             }
         }).map(|a| a.clone()));
-        push(box(GC) ast::Item {
+        push(P(ast::Item {
             attrs: attrs,
             ..(*newitem).clone()
-        })
+        }))
     }
 
     /**
@@ -387,7 +390,7 @@ impl<'a> TraitDef<'a> {
                            cx: &mut ExtCtxt,
                            type_ident: Ident,
                            generics: &Generics,
-                           methods: Vec<Gc<ast::Method>> ) -> Gc<ast::Item> {
+                           methods: Vec<P<ast::Method>>) -> P<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
         let Generics { mut lifetimes, ty_params, where_clause: _ } =
@@ -475,7 +478,7 @@ impl<'a> TraitDef<'a> {
                          cx: &mut ExtCtxt,
                          struct_def: &StructDef,
                          type_ident: Ident,
-                         generics: &Generics) -> Gc<ast::Item> {
+                         generics: &Generics) -> P<ast::Item> {
         let methods = self.methods.iter().map(|method_def| {
             let (explicit_self, self_args, nonself_args, tys) =
                 method_def.split_self_nonself_args(
@@ -515,7 +518,7 @@ impl<'a> TraitDef<'a> {
                        cx: &mut ExtCtxt,
                        enum_def: &EnumDef,
                        type_ident: Ident,
-                       generics: &Generics) -> Gc<ast::Item> {
+                       generics: &Generics) -> P<ast::Item> {
         let methods = self.methods.iter().map(|method_def| {
             let (explicit_self, self_args, nonself_args, tys) =
                 method_def.split_self_nonself_args(cx, self,
@@ -534,7 +537,7 @@ impl<'a> TraitDef<'a> {
                                                    self,
                                                    enum_def,
                                                    type_ident,
-                                                   self_args.as_slice(),
+                                                   self_args,
                                                    nonself_args.as_slice())
             };
 
@@ -553,7 +556,7 @@ impl<'a> TraitDef<'a> {
 }
 
 fn variant_to_pat(cx: &mut ExtCtxt, sp: Span, variant: &ast::Variant)
-                  -> Gc<ast::Pat> {
+                  -> P<ast::Pat> {
     let ident = cx.path_ident(sp, variant.node.name);
     cx.pat(sp, match variant.node.kind {
         ast::TupleVariantKind(..) => ast::PatEnum(ident, None),
@@ -566,10 +569,10 @@ impl<'a> MethodDef<'a> {
                                 cx: &mut ExtCtxt,
                                 trait_: &TraitDef,
                                 type_ident: Ident,
-                                self_args: &[Gc<Expr>],
-                                nonself_args: &[Gc<Expr>],
+                                self_args: &[P<Expr>],
+                                nonself_args: &[P<Expr>],
                                 fields: &SubstructureFields)
-        -> Gc<Expr> {
+        -> P<Expr> {
         let substructure = Substructure {
             type_ident: type_ident,
             method_ident: cx.ident_of(self.name),
@@ -600,8 +603,7 @@ impl<'a> MethodDef<'a> {
                                trait_: &TraitDef,
                                type_ident: Ident,
                                generics: &Generics)
-        -> (ast::ExplicitSelf, Vec<Gc<Expr>>, Vec<Gc<Expr>>,
-            Vec<(Ident, P<ast::Ty>)>) {
+        -> (ast::ExplicitSelf, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
 
         let mut self_args = Vec::new();
         let mut nonself_args = Vec::new();
@@ -654,8 +656,7 @@ impl<'a> MethodDef<'a> {
                      abi: Abi,
                      explicit_self: ast::ExplicitSelf,
                      arg_types: Vec<(Ident, P<ast::Ty>)> ,
-                     body: Gc<Expr>)
-                     -> Gc<ast::Method> {
+                     body: P<Expr>) -> P<ast::Method> {
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
 
@@ -678,7 +679,7 @@ impl<'a> MethodDef<'a> {
         let body_block = cx.block_expr(body);
 
         // Create the method.
-        box(GC) ast::Method {
+        P(ast::Method {
             attrs: self.attributes.clone(),
             id: ast::DUMMY_NODE_ID,
             span: trait_.span,
@@ -690,7 +691,7 @@ impl<'a> MethodDef<'a> {
                                 fn_decl,
                                 body_block,
                                 ast::Inherited)
-        }
+        })
     }
 
     /**
@@ -719,9 +720,9 @@ impl<'a> MethodDef<'a> {
                                  trait_: &TraitDef,
                                  struct_def: &StructDef,
                                  type_ident: Ident,
-                                 self_args: &[Gc<Expr>],
-                                 nonself_args: &[Gc<Expr>])
-        -> Gc<Expr> {
+                                 self_args: &[P<Expr>],
+                                 nonself_args: &[P<Expr>])
+        -> P<Expr> {
 
         let mut raw_fields = Vec::new(); // ~[[fields of self],
                                  // [fields of next Self arg], [etc]]
@@ -740,20 +741,20 @@ impl<'a> MethodDef<'a> {
 
         // transpose raw_fields
         let fields = if raw_fields.len() > 0 {
-            raw_fields.get(0)
-                      .iter()
-                      .enumerate()
-                      .map(|(i, &(span, opt_id, field))| {
-                let other_fields = raw_fields.tail().iter().map(|l| {
-                    match l.get(i) {
-                        &(_, _, ex) => ex
-                    }
-                }).collect();
+            let mut raw_fields = raw_fields.move_iter().map(|v| v.move_iter());
+            let first_field = raw_fields.next().unwrap();
+            let mut other_fields: Vec<vec::MoveItems<(Span, Option<Ident>, P<Expr>)>>
+                = raw_fields.collect();
+            first_field.map(|(span, opt_id, field)| {
                 FieldInfo {
                     span: span,
                     name: opt_id,
                     self_: field,
-                    other: other_fields
+                    other: other_fields.mut_iter().map(|l| {
+                        match l.next().unwrap() {
+                            (_, _, ex) => ex
+                        }
+                    }).collect()
                 }
             }).collect()
         } else {
@@ -774,9 +775,9 @@ impl<'a> MethodDef<'a> {
         // make a series of nested matches, to destructure the
         // structs. This is actually right-to-left, but it shouldn't
         // matter.
-        for (&arg_expr, &pat) in self_args.iter().zip(patterns.iter()) {
-            body = cx.expr_match(trait_.span, arg_expr,
-                                     vec!( cx.arm(trait_.span, vec!(pat), body) ))
+        for (arg_expr, pat) in self_args.iter().zip(patterns.iter()) {
+            body = cx.expr_match(trait_.span, arg_expr.clone(),
+                                     vec!( cx.arm(trait_.span, vec!(pat.clone()), body) ))
         }
         body
     }
@@ -786,9 +787,9 @@ impl<'a> MethodDef<'a> {
                                         trait_: &TraitDef,
                                         struct_def: &StructDef,
                                         type_ident: Ident,
-                                        self_args: &[Gc<Expr>],
-                                        nonself_args: &[Gc<Expr>])
-        -> Gc<Expr> {
+                                        self_args: &[P<Expr>],
+                                        nonself_args: &[P<Expr>])
+        -> P<Expr> {
         let summary = trait_.summarise_struct(cx, struct_def);
 
         self.call_substructure_method(cx,
@@ -834,9 +835,9 @@ impl<'a> MethodDef<'a> {
                                trait_: &TraitDef,
                                enum_def: &EnumDef,
                                type_ident: Ident,
-                               self_args: &[Gc<Expr>],
-                               nonself_args: &[Gc<Expr>])
-                               -> Gc<Expr> {
+                               self_args: Vec<P<Expr>>,
+                               nonself_args: &[P<Expr>])
+                               -> P<Expr> {
         self.build_enum_match_tuple(
             cx, trait_, enum_def, type_ident, self_args, nonself_args)
     }
@@ -875,8 +876,8 @@ impl<'a> MethodDef<'a> {
         trait_: &TraitDef,
         enum_def: &EnumDef,
         type_ident: Ident,
-        self_args: &[Gc<Expr>],
-        nonself_args: &[Gc<Expr>]) -> Gc<Expr> {
+        self_args: Vec<P<Expr>>,
+        nonself_args: &[P<Expr>]) -> P<Expr> {
 
         let sp = trait_.span;
         let variants = &enum_def.variants;
@@ -898,7 +899,7 @@ impl<'a> MethodDef<'a> {
         // The `vi_idents` will be bound, solely in the catch-all, to
         // a series of let statements mapping each self_arg to a uint
         // corresponding to its variant index.
-        let vi_idents : Vec<ast::Ident> = self_arg_names.iter()
+        let vi_idents: Vec<ast::Ident> = self_arg_names.iter()
             .map(|name| { let vi_suffix = format!("{:s}_vi", name.as_slice());
                           cx.ident_of(vi_suffix.as_slice()) })
             .collect::<Vec<ast::Ident>>();
@@ -914,24 +915,29 @@ impl<'a> MethodDef<'a> {
         // (Variant2, Variant2, ...) => Body2
         // ...
         // where each tuple has length = self_args.len()
-        let mut match_arms : Vec<ast::Arm> = variants.iter().enumerate()
-            .map(|(index, &variant)| {
-
-                // These self_pats have form Variant1, Variant2, ...
-                let self_pats : Vec<(Gc<ast::Pat>,
-                                     Vec<(Span, Option<Ident>, Gc<Expr>)>)>;
-                self_pats = self_arg_names.iter()
-                    .map(|self_arg_name|
-                         trait_.create_enum_variant_pattern(
-                             cx, &*variant, self_arg_name.as_slice(),
-                             ast::MutImmutable))
-                    .collect();
+        let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
+            .map(|(index, variant)| {
+                let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| {
+                    let (p, idents) = trait_.create_enum_variant_pattern(cx, &**variant,
+                                                                         self_arg_name,
+                                                                         ast::MutImmutable);
+                    (cx.pat(sp, ast::PatRegion(p)), idents)
+                };
 
                 // A single arm has form (&VariantK, &VariantK, ...) => BodyK
                 // (see "Final wrinkle" note below for why.)
-                let subpats = self_pats.iter()
-                    .map(|&(p, ref _idents)| cx.pat(sp, ast::PatRegion(p)))
-                    .collect::<Vec<Gc<ast::Pat>>>();
+                let mut subpats = Vec::with_capacity(self_arg_names.len());
+                let mut self_pats_idents = Vec::with_capacity(self_arg_names.len() - 1);
+                let first_self_pat_idents = {
+                    let (p, idents) = mk_self_pat(cx, self_arg_names[0].as_slice());
+                    subpats.push(p);
+                    idents
+                };
+                for self_arg_name in self_arg_names.tail().iter() {
+                    let (p, idents) = mk_self_pat(cx, self_arg_name.as_slice());
+                    subpats.push(p);
+                    self_pats_idents.push(idents);
+                }
 
                 // Here is the pat = `(&VariantK, &VariantK, ...)`
                 let single_pat = cx.pat(sp, ast::PatTup(subpats));
@@ -941,39 +947,33 @@ impl<'a> MethodDef<'a> {
                 // we are in.
 
                 // All of the Self args have the same variant in these
-                // cases.  So we transpose the info in self_pats to
-                // gather the getter expressions together, in the form
-                // that EnumMatching expects.
+                // cases.  So we transpose the info in self_pats_idents
+                // to gather the getter expressions together, in the
+                // form that EnumMatching expects.
 
                 // The transposition is driven by walking across the
                 // arg fields of the variant for the first self pat.
-                let &(_, ref self_arg_fields) = self_pats.get(0);
-
-                let field_tuples : Vec<FieldInfo>;
-
-                field_tuples = self_arg_fields.iter().enumerate()
+                let field_tuples = first_self_pat_idents.move_iter().enumerate()
                     // For each arg field of self, pull out its getter expr ...
-                    .map(|(field_index, &(sp, opt_ident, self_getter_expr))| {
+                    .map(|(field_index, (sp, opt_ident, self_getter_expr))| {
                         // ... but FieldInfo also wants getter expr
                         // for matching other arguments of Self type;
-                        // so walk across the *other* self_pats and
-                        // pull out getter for same field in each of
-                        // them (using `field_index` tracked above).
+                        // so walk across the *other* self_pats_idents
+                        // and pull out getter for same field in each
+                        // of them (using `field_index` tracked above).
                         // That is the heart of the transposition.
-                        let others = self_pats.tail().iter()
-                            .map(|&(_pat, ref fields)| {
+                        let others = self_pats_idents.iter().map(|fields| {
+                            let &(_, _opt_ident, ref other_getter_expr) =
+                                fields.get(field_index);
 
-                                let &(_, _opt_ident, other_getter_expr) =
-                                    fields.get(field_index);
+                            // All Self args have same variant, so
+                            // opt_idents are the same.  (Assert
+                            // here to make it self-evident that
+                            // it is okay to ignore `_opt_ident`.)
+                            assert!(opt_ident == _opt_ident);
 
-                                // All Self args have same variant, so
-                                // opt_idents are the same.  (Assert
-                                // here to make it self-evident that
-                                // it is okay to ignore `_opt_ident`.)
-                                assert!(opt_ident == _opt_ident);
-
-                                other_getter_expr
-                            }).collect::<Vec<Gc<Expr>>>();
+                            other_getter_expr.clone()
+                        }).collect::<Vec<P<Expr>>>();
 
                         FieldInfo { span: sp,
                                     name: opt_ident,
@@ -987,10 +987,10 @@ impl<'a> MethodDef<'a> {
                 // Self arg, assuming all are instances of VariantK.
                 // Build up code associated with such a case.
                 let substructure = EnumMatching(index,
-                                                &*variant,
+                                                &**variant,
                                                 field_tuples);
                 let arm_expr = self.call_substructure_method(
-                    cx, trait_, type_ident, self_args, nonself_args,
+                    cx, trait_, type_ident, self_args.as_slice(), nonself_args,
                     &substructure);
 
                 cx.arm(sp, vec![single_pat], arm_expr)
@@ -1012,9 +1012,9 @@ impl<'a> MethodDef<'a> {
         //   unreachable-pattern error.
         //
         if variants.len() > 1 && self_args.len() > 1 {
-            let arms : Vec<ast::Arm> = variants.iter().enumerate()
-                .map(|(index, &variant)| {
-                    let pat = variant_to_pat(cx, sp, &*variant);
+            let arms: Vec<ast::Arm> = variants.iter().enumerate()
+                .map(|(index, variant)| {
+                    let pat = variant_to_pat(cx, sp, &**variant);
                     let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyU));
                     cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
                 }).collect();
@@ -1035,15 +1035,15 @@ impl<'a> MethodDef<'a> {
             //     A => 0u, B(..) => 1u, C(..) => 2u
             // };
             // ```
-            let mut index_let_stmts : Vec<Gc<ast::Stmt>> = Vec::new();
-            for (&ident, &self_arg) in vi_idents.iter().zip(self_args.iter()) {
-                let variant_idx = cx.expr_match(sp, self_arg, arms.clone());
+            let mut index_let_stmts: Vec<P<ast::Stmt>> = Vec::new();
+            for (&ident, self_arg) in vi_idents.iter().zip(self_args.iter()) {
+                let variant_idx = cx.expr_match(sp, self_arg.clone(), arms.clone());
                 let let_stmt = cx.stmt_let(sp, false, ident, variant_idx);
                 index_let_stmts.push(let_stmt);
             }
 
             let arm_expr = self.call_substructure_method(
-                cx, trait_, type_ident, self_args, nonself_args,
+                cx, trait_, type_ident, self_args.as_slice(), nonself_args,
                 &catch_all_substructure);
 
             // Builds the expression:
@@ -1124,9 +1124,7 @@ impl<'a> MethodDef<'a> {
         // them when they are fed as r-values into a tuple
         // expression; here add a layer of borrowing, turning
         // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
-        let borrowed_self_args = self_args.iter()
-            .map(|&self_arg| cx.expr_addr_of(sp, self_arg))
-            .collect::<Vec<Gc<ast::Expr>>>();
+        let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg));
         let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args));
         cx.expr_match(sp, match_arg, match_arms)
     }
@@ -1136,9 +1134,9 @@ impl<'a> MethodDef<'a> {
                                       trait_: &TraitDef,
                                       enum_def: &EnumDef,
                                       type_ident: Ident,
-                                      self_args: &[Gc<Expr>],
-                                      nonself_args: &[Gc<Expr>])
-        -> Gc<Expr> {
+                                      self_args: &[P<Expr>],
+                                      nonself_args: &[P<Expr>])
+        -> P<Expr> {
         let summary = enum_def.variants.iter().map(|v| {
             let ident = v.node.name;
             let summary = match v.node.kind {
@@ -1210,11 +1208,11 @@ impl<'a> TraitDef<'a> {
                           cx: &mut ExtCtxt,
                           field_paths: Vec<ast::SpannedIdent> ,
                           mutbl: ast::Mutability)
-                          -> Vec<Gc<ast::Pat>> {
+                          -> Vec<P<ast::Pat>> {
         field_paths.iter().map(|path| {
             cx.pat(path.span,
                         ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
-            }).collect()
+        }).collect()
     }
 
     fn create_struct_pattern(&self,
@@ -1223,7 +1221,7 @@ impl<'a> TraitDef<'a> {
                              struct_def: &StructDef,
                              prefix: &str,
                              mutbl: ast::Mutability)
-                             -> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)>) {
+                             -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>)>) {
         if struct_def.fields.is_empty() {
             return (
                 cx.pat_ident_binding_mode(
@@ -1266,7 +1264,7 @@ impl<'a> TraitDef<'a> {
         // struct_type is definitely not Unknown, since struct_def.fields
         // must be nonempty to reach here
         let pattern = if struct_type == Record {
-            let field_pats = subpats.iter().zip(ident_expr.iter()).map(|(&pat, &(_, id, _))| {
+            let field_pats = subpats.move_iter().zip(ident_expr.iter()).map(|(pat, &(_, id, _))| {
                 // id is guaranteed to be Some
                 ast::FieldPat { ident: id.unwrap(), pat: pat }
             }).collect();
@@ -1283,7 +1281,7 @@ impl<'a> TraitDef<'a> {
                                    variant: &ast::Variant,
                                    prefix: &str,
                                    mutbl: ast::Mutability)
-        -> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)> ) {
+        -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>)>) {
         let variant_ident = variant.node.name;
         match variant.node.kind {
             ast::TupleVariantKind(ref variant_args) => {
@@ -1327,13 +1325,13 @@ Fold the fields. `use_foldl` controls whether this is done
 left-to-right (`true`) or right-to-left (`false`).
 */
 pub fn cs_fold(use_foldl: bool,
-               f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
-               base: Gc<Expr>,
+               f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]| -> P<Expr>,
+               base: P<Expr>,
                enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                cx: &mut ExtCtxt,
                trait_span: Span,
                substructure: &Substructure)
-               -> Gc<Expr> {
+               -> P<Expr> {
     match *substructure.fields {
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             if use_foldl {
@@ -1341,7 +1339,7 @@ pub fn cs_fold(use_foldl: bool,
                     f(cx,
                       field.span,
                       old,
-                      field.self_,
+                      field.self_.clone(),
                       field.other.as_slice())
                 })
             } else {
@@ -1349,7 +1347,7 @@ pub fn cs_fold(use_foldl: bool,
                     f(cx,
                       field.span,
                       old,
-                      field.self_,
+                      field.self_.clone(),
                       field.other.as_slice())
                 })
             }
@@ -1374,21 +1372,21 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
 ~~~
 */
 #[inline]
-pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
+pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>,
                       enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                       cx: &mut ExtCtxt,
                       trait_span: Span,
                       substructure: &Substructure)
-                      -> Gc<Expr> {
+                      -> P<Expr> {
     match *substructure.fields {
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             // call self_n.method(other_1_n, other_2_n, ...)
             let called = all_fields.iter().map(|field| {
                 cx.expr_method_call(field.span,
-                                    field.self_,
+                                    field.self_.clone(),
                                     substructure.method_ident,
                                     field.other.iter()
-                                               .map(|e| cx.expr_addr_of(field.span, *e))
+                                               .map(|e| cx.expr_addr_of(field.span, e.clone()))
                                                .collect())
             }).collect();
 
@@ -1410,21 +1408,21 @@ fields. `use_foldl` controls whether this is done left-to-right
 */
 #[inline]
 pub fn cs_same_method_fold(use_foldl: bool,
-                           f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
-                           base: Gc<Expr>,
+                           f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>| -> P<Expr>,
+                           base: P<Expr>,
                            enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                            cx: &mut ExtCtxt,
                            trait_span: Span,
                            substructure: &Substructure)
-                           -> Gc<Expr> {
+                           -> P<Expr> {
     cs_same_method(
         |cx, span, vals| {
             if use_foldl {
-                vals.iter().fold(base, |old, &new| {
+                vals.move_iter().fold(base.clone(), |old, new| {
                     f(cx, span, old, new)
                 })
             } else {
-                vals.iter().rev().fold(base, |old, &new| {
+                vals.move_iter().rev().fold(base.clone(), |old, new| {
                     f(cx, span, old, new)
                 })
             }
@@ -1438,10 +1436,10 @@ Use a given binop to combine the result of calling the derived method
 on all the fields.
 */
 #[inline]
-pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
+pub fn cs_binop(binop: ast::BinOp, base: P<Expr>,
                 enum_nonmatch_f: EnumNonMatchCollapsedFunc,
                 cx: &mut ExtCtxt, trait_span: Span,
-                substructure: &Substructure) -> Gc<Expr> {
+                substructure: &Substructure) -> P<Expr> {
     cs_same_method_fold(
         true, // foldl is good enough
         |cx, span, old, new| {
@@ -1459,7 +1457,7 @@ pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
 #[inline]
 pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
              cx: &mut ExtCtxt, span: Span,
-             substructure: &Substructure) -> Gc<Expr> {
+             substructure: &Substructure) -> P<Expr> {
     cs_binop(ast::BiOr, cx.expr_bool(span, false),
              enum_nonmatch_f,
              cx, span, substructure)
@@ -1469,7 +1467,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
 #[inline]
 pub fn cs_and(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
               cx: &mut ExtCtxt, span: Span,
-              substructure: &Substructure) -> Gc<Expr> {
+              substructure: &Substructure) -> P<Expr> {
     cs_binop(ast::BiAnd, cx.expr_bool(span, true),
              enum_nonmatch_f,
              cx, span, substructure)
diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs
index 8b4a9c51cf0..a90618a30b6 100644
--- a/src/libsyntax/ext/deriving/generic/ty.rs
+++ b/src/libsyntax/ext/deriving/generic/ty.rs
@@ -14,14 +14,13 @@ explicit `Self` type to use when specifying impls to be derived.
 */
 
 use ast;
-use ast::{P,Expr,Generics,Ident};
+use ast::{Expr,Generics,Ident};
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use codemap::{Span,respan};
 use owned_slice::OwnedSlice;
 use parse::token::special_idents;
-
-use std::gc::Gc;
+use ptr::P;
 
 /// The types of pointers
 #[deriving(Clone)]
@@ -260,7 +259,7 @@ impl<'a> LifetimeBounds<'a> {
 }
 
 pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
-    -> (Gc<Expr>, ast::ExplicitSelf) {
+    -> (P<Expr>, ast::ExplicitSelf) {
     // this constructs a fresh `self` path, which will match the fresh `self` binding
     // created below.
     let self_path = cx.expr_self(span);
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index f469139177a..b7f11c25825 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -15,14 +15,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                             span: Span,
-                            mitem: Gc<MetaItem>,
-                            item: Gc<Item>,
-                            push: |Gc<Item>|) {
+                            mitem: &MetaItem,
+                            item: &Item,
+                            push: |P<Item>|) {
 
     let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
         (Path::new_(vec!("std", "hash", "Hash"), None,
@@ -64,15 +63,14 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
     hash_trait_def.expand(cx, mitem, item, push);
 }
 
-fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
-                     substr: &Substructure) -> Gc<Expr> {
+fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
     let state_expr = match substr.nonself_args {
-        [state_expr] => state_expr,
+        [ref state_expr] => state_expr,
         _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")
     };
     let hash_ident = substr.method_ident;
     let call_hash = |span, thing_expr| {
-        let expr = cx.expr_method_call(span, thing_expr, hash_ident, vec!(state_expr));
+        let expr = cx.expr_method_call(span, thing_expr, hash_ident, vec!(state_expr.clone()));
         cx.stmt_expr(expr)
     };
     let mut stmts = Vec::new();
@@ -83,7 +81,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
             // Determine the discriminant. We will feed this value to the byte
             // iteration function.
             let discriminant = match variant.node.disr_expr {
-                Some(d) => d,
+                Some(ref d) => d.clone(),
                 None => cx.expr_uint(trait_span, index)
             };
 
@@ -94,8 +92,8 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
         _ => cx.span_bug(trait_span, "impossible substructure in `deriving(Hash)`")
     };
 
-    for &FieldInfo { self_, span, .. } in fields.iter() {
-        stmts.push(call_hash(span, self_));
+    for &FieldInfo { ref self_, span, .. } in fields.iter() {
+        stmts.push(call_hash(span, self_.clone()));
     }
 
     if stmts.len() == 0 {
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index a9b5c8a4134..b8cebd8ea20 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -21,8 +21,7 @@ library.
 use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
 use ext::base::ExtCtxt;
 use codemap::Span;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub mod bounds;
 pub mod clone;
@@ -49,9 +48,9 @@ pub mod generic;
 
 pub fn expand_meta_deriving(cx: &mut ExtCtxt,
                             _span: Span,
-                            mitem: Gc<MetaItem>,
-                            item: Gc<Item>,
-                            push: |Gc<Item>|) {
+                            mitem: &MetaItem,
+                            item: &Item,
+                            push: |P<Item>|) {
     match mitem.node {
         MetaNameValue(_, ref l) => {
             cx.span_err(l.span, "unexpected value in `deriving`");
@@ -63,13 +62,13 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
             cx.span_warn(mitem.span, "empty trait list in `deriving`");
         }
         MetaList(_, ref titems) => {
-            for &titem in titems.iter().rev() {
+            for titem in titems.iter().rev() {
                 match titem.node {
                     MetaNameValue(ref tname, _) |
                     MetaList(ref tname, _) |
                     MetaWord(ref tname) => {
                         macro_rules! expand(($func:path) => ($func(cx, titem.span,
-                                                                   titem, item,
+                                                                   &**titem, item,
                                                                    |i| push(i))));
                         match tname.get() {
                             "Clone" => expand!(clone::expand_deriving_clone),
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index 30dd8e9683a..044a2812c00 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -16,14 +16,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                       span: Span,
-                                      mitem: Gc<MetaItem>,
-                                      item: Gc<Item>,
-                                      push: |Gc<Item>|) {
+                                      mitem: &MetaItem,
+                                      item: &Item,
+                                      push: |P<Item>|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
@@ -70,10 +69,9 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
-           substr: &Substructure) -> Gc<Expr> {
+fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
     let n = match substr.nonself_args {
-        [n] => n,
+        [ref n] => n,
         _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`")
     };
 
@@ -106,8 +104,8 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
                         // expr for `$n == $variant as $name`
                         let variant = cx.expr_ident(span, variant.node.name);
                         let ty = cx.ty_ident(span, cx.ident_of(name));
-                        let cast = cx.expr_cast(span, variant, ty);
-                        let guard = cx.expr_binary(span, ast::BiEq, n, cast);
+                        let cast = cx.expr_cast(span, variant.clone(), ty);
+                        let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
 
                         // expr for `Some($variant)`
                         let body = cx.expr_some(span, variant);
@@ -141,7 +139,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
             };
             arms.push(arm);
 
-            cx.expr_match(trait_span, n, arms)
+            cx.expr_match(trait_span, n.clone(), arms)
         }
         _ => cx.span_bug(trait_span, "expected StaticEnum in deriving(FromPrimitive)")
     }
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index c652b5a5bed..584645bb306 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -15,14 +15,13 @@ use ext::base::ExtCtxt;
 use ext::build::{AstBuilder};
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                             span: Span,
-                            mitem: Gc<MetaItem>,
-                            item: Gc<Item>,
-                            push: |Gc<Item>|) {
+                            mitem: &MetaItem,
+                            item: &Item,
+                            push: |P<Item>|) {
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -54,10 +53,9 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
-                     substr: &Substructure) -> Gc<Expr> {
+fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
     let rng = match substr.nonself_args {
-        [rng] => vec!( rng ),
+        [ref rng] => rng,
         _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
     };
     let rand_ident = vec!(
@@ -69,7 +67,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
     let rand_call = |cx: &mut ExtCtxt, span| {
         cx.expr_call_global(span,
                             rand_ident.clone(),
-                            vec!( *rng.get(0) ))
+                            vec!(rng.clone()))
     };
 
     return match *substr.fields {
@@ -95,7 +93,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
             // ::rand::Rand::rand(rng)
             let rv_call = cx.expr_call(trait_span,
                                        rand_name,
-                                       vec!( *rng.get(0) ));
+                                       vec!(rng.clone()));
 
             // need to specify the uint-ness of the random number
             let uint_ty = cx.ty_ident(trait_span, cx.ident_of("uint"));
@@ -136,8 +134,8 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
                   trait_span: Span,
                   ctor_ident: Ident,
                   summary: &StaticFields,
-                  rand_call: |&mut ExtCtxt, Span| -> Gc<Expr>)
-                  -> Gc<Expr> {
+                  rand_call: |&mut ExtCtxt, Span| -> P<Expr>)
+                  -> P<Expr> {
         match *summary {
             Unnamed(ref fields) => {
                 if fields.is_empty() {
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index e0dfbb232f5..16ce264fe71 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use ast;
-use ast::{MetaItem, Item, Expr};
+use ast::{MetaItem, Item, Expr,};
 use codemap::Span;
 use ext::format;
 use ext::base::ExtCtxt;
@@ -17,16 +17,15 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token;
+use ptr::P;
 
 use std::collections::HashMap;
-use std::string::String;
-use std::gc::Gc;
 
 pub fn expand_deriving_show(cx: &mut ExtCtxt,
                             span: Span,
-                            mitem: Gc<MetaItem>,
-                            item: Gc<Item>,
-                            push: |Gc<Item>|) {
+                            mitem: &MetaItem,
+                            item: &Item,
+                            push: |P<Item>|) {
     // &mut ::std::fmt::Formatter
     let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
                    Borrowed(None, ast::MutMutable));
@@ -57,7 +56,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
 /// We construct a format string and then defer to std::fmt, since that
 /// knows what's up with formatting and so on.
 fn show_substructure(cx: &mut ExtCtxt, span: Span,
-                     substr: &Substructure) -> Gc<Expr> {
+                     substr: &Substructure) -> P<Expr> {
     // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
     // <field>: {}, ... }` based on the "shape".
     //
@@ -91,7 +90,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
 
                     format_string.push_str("{}");
 
-                    exprs.push(field.self_);
+                    exprs.push(field.self_.clone());
                 }
 
                 format_string.push_str(")");
@@ -108,7 +107,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
                     format_string.push_str(name.get());
                     format_string.push_str(": {}");
 
-                    exprs.push(field.self_);
+                    exprs.push(field.self_.clone());
                 }
 
                 format_string.push_str(" }}");
@@ -123,7 +122,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     // format_arg_method!(fmt, write_fmt, "<format_string>", exprs...)
     //
     // but doing it directly via ext::format.
-    let formatter = substr.nonself_args[0];
+    let formatter = substr.nonself_args[0].clone();
 
     let meth = cx.ident_of("write_fmt");
     let s = token::intern_and_get_ident(format_string.as_slice());
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
index 973f9d518cd..7f265b529ff 100644
--- a/src/libsyntax/ext/deriving/zero.rs
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -15,14 +15,13 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use parse::token::InternedString;
-
-use std::gc::Gc;
+use ptr::P;
 
 pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                             span: Span,
-                            mitem: Gc<MetaItem>,
-                            item: Gc<Item>,
-                            push: |Gc<Item>|) {
+                            mitem: &MetaItem,
+                            item: &Item,
+                            push: |P<Item>|) {
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let trait_def = TraitDef {
@@ -63,8 +62,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span,
-                     substr: &Substructure) -> Gc<Expr> {
+fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
     let zero_ident = vec!(
         cx.ident_of("std"),
         cx.ident_of("num"),