about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-12-07 11:57:44 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2013-12-07 11:57:44 +1100
commit09a879460cfa42ecfd4a769bdc21e1d55b795bd8 (patch)
treee8423abcddefb2fc8e102208910048646c6c46de /src/libsyntax
parentaa4455e4c76598fcf6de84de14f050a700a2a14e (diff)
downloadrust-09a879460cfa42ecfd4a769bdc21e1d55b795bd8.tar.gz
rust-09a879460cfa42ecfd4a769bdc21e1d55b795bd8.zip
syntax::deriving: add the cx and span to the TraitDef to reduce duplication.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/deriving/clone.rs8
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs4
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs4
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs4
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs4
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs4
-rw-r--r--src/libsyntax/ext/deriving/default.rs4
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs4
-rw-r--r--src/libsyntax/ext/deriving/generic.rs421
-rw-r--r--src/libsyntax/ext/deriving/iter_bytes.rs4
-rw-r--r--src/libsyntax/ext/deriving/primitive.rs4
-rw-r--r--src/libsyntax/ext/deriving/rand.rs4
-rw-r--r--src/libsyntax/ext/deriving/to_str.rs4
-rw-r--r--src/libsyntax/ext/deriving/zero.rs4
14 files changed, 251 insertions, 226 deletions
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index 0f83f725223..9285defe69e 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -20,6 +20,8 @@ pub fn expand_deriving_clone(cx: @ExtCtxt,
                              in_items: ~[@item])
                           -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "clone", "Clone"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -37,7 +39,7 @@ pub fn expand_deriving_clone(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
@@ -46,6 +48,8 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
                                   in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "clone", "DeepClone"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -65,7 +69,7 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn cs_clone(
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index eb07d2d209c..74680266cb7 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -45,6 +45,8 @@ pub fn expand_deriving_eq(cx: @ExtCtxt,
     );
 
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "cmp", "Eq"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -53,5 +55,5 @@ pub fn expand_deriving_eq(cx: @ExtCtxt,
             md!("ne", cs_ne)
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 95d617af0c7..d48cfbd7dd7 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -35,6 +35,8 @@ pub fn expand_deriving_ord(cx: @ExtCtxt,
     );
 
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "cmp", "Ord"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -45,7 +47,7 @@ pub fn expand_deriving_ord(cx: @ExtCtxt,
             md!("ge", false, true)
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 /// Strict inequality.
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index 51965e1b582..ab822d14b48 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -24,6 +24,8 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt,
     }
 
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "cmp", "TotalEq"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -40,5 +42,5 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt,
             }
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index 217acd98c68..2ace39a3486 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -21,6 +21,8 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt,
                                 mitem: @MetaItem,
                                 in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "cmp", "TotalOrd"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -38,7 +40,7 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 4ab0cc3bc67..0aade760b7b 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -24,6 +24,8 @@ pub fn expand_deriving_decodable(cx: @ExtCtxt,
                                  mitem: @MetaItem,
                                  in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new_(~["extra", "serialize", "Decodable"], None,
                          ~[~Literal(Path::new_local("__D"))], true),
         additional_bounds: ~[],
@@ -46,7 +48,7 @@ pub fn expand_deriving_decodable(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn decodable_substructure(cx: @ExtCtxt, span: Span,
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index 3ecdd5e60fe..393d808a025 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -20,6 +20,8 @@ pub fn expand_deriving_default(cx: @ExtCtxt,
                             in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "default", "Default"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -36,7 +38,7 @@ pub fn expand_deriving_default(cx: @ExtCtxt,
             },
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn default_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 96b77c4c162..09210116c37 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -86,6 +86,8 @@ pub fn expand_deriving_encodable(cx: @ExtCtxt,
                                  mitem: @MetaItem,
                                  in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new_(~["extra", "serialize", "Encodable"], None,
                          ~[~Literal(Path::new_local("__E"))], true),
         additional_bounds: ~[],
@@ -108,7 +110,7 @@ pub fn expand_deriving_encodable(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn encodable_substructure(cx: @ExtCtxt, span: Span,
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index 627e799f2d3..66f1e506ae8 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -179,7 +179,8 @@ use ast::{P, enum_def, Expr, Ident, Generics, struct_def};
 
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
-use codemap::{Span,respan};
+use codemap;
+use codemap::Span;
 use opt_vec;
 
 use std::vec;
@@ -188,6 +189,11 @@ pub use self::ty::*;
 mod ty;
 
 pub struct TraitDef<'self> {
+    /// The extension context
+    cx: @ExtCtxt,
+    /// The span for the current #[deriving(Foo)] header.
+    span: Span,
+
     /// Path of the trait, including any type parameters
     path: Path<'self>,
     /// Additional bounds required of any type parameters of the type,
@@ -310,8 +316,7 @@ pub type EnumNonMatchFunc<'self> =
 
 
 impl<'self> TraitDef<'self> {
-    pub fn expand(&self, cx: @ExtCtxt,
-                  trait_span: Span,
+    pub fn expand(&self,
                   _mitem: @ast::MetaItem,
                   in_items: ~[@ast::item]) -> ~[@ast::item] {
         let mut result = ~[];
@@ -319,14 +324,12 @@ impl<'self> TraitDef<'self> {
             result.push(*item);
             match item.node {
                 ast::item_struct(struct_def, ref generics) => {
-                    result.push(self.expand_struct_def(cx, trait_span,
-                                                       struct_def,
+                    result.push(self.expand_struct_def(struct_def,
                                                        item.ident,
                                                        generics));
                 }
                 ast::item_enum(ref enum_def, ref generics) => {
-                    result.push(self.expand_enum_def(cx, trait_span,
-                                                     enum_def,
+                    result.push(self.expand_enum_def(enum_def,
                                                      item.ident,
                                                      generics));
                 }
@@ -346,12 +349,14 @@ impl<'self> TraitDef<'self> {
      * where B1, B2, ... are the bounds given by `bounds_paths`.'
      *
      */
-    fn create_derived_impl(&self, cx: @ExtCtxt, trait_span: Span,
+    fn create_derived_impl(&self,
                            type_ident: Ident, generics: &Generics,
                            methods: ~[@ast::method]) -> @ast::item {
-        let trait_path = self.path.to_path(cx, trait_span, type_ident, generics);
+        let cx = self.cx;
+        let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
-        let mut trait_generics = self.generics.to_generics(cx, trait_span, type_ident, generics);
+        let mut trait_generics = self.generics.to_generics(cx, self.span,
+                                                           type_ident, generics);
         // Copy the lifetimes
         for l in generics.lifetimes.iter() {
             trait_generics.lifetimes.push(*l)
@@ -363,7 +368,7 @@ impl<'self> TraitDef<'self> {
             let mut bounds = opt_vec::from(
                 // extra restrictions on the generics parameters to the type being derived upon
                 self.additional_bounds.map(|p| {
-                    cx.typarambound(p.to_path(cx, trait_span, type_ident, generics))
+                    cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
                 }));
             // require the current trait
             bounds.push(cx.typarambound(trait_path.clone()));
@@ -376,22 +381,23 @@ impl<'self> TraitDef<'self> {
 
         // Create the type parameters on the `self` path.
         let self_ty_params = generics.ty_params.map(|ty_param| {
-            cx.ty_ident(trait_span, ty_param.ident)
+            cx.ty_ident(self.span, ty_param.ident)
         });
 
         let self_lifetimes = generics.lifetimes.clone();
 
         // Create the type of `self`.
-        let self_type = cx.ty_path(cx.path_all(trait_span, false, ~[ type_ident ], self_lifetimes,
-                                               opt_vec::take_vec(self_ty_params)), None);
+        let self_type = cx.ty_path(
+            cx.path_all(self.span, false, ~[ type_ident ], self_lifetimes,
+                             opt_vec::take_vec(self_ty_params)), None);
 
         let doc_attr = cx.attribute(
-            trait_span,
-            cx.meta_name_value(trait_span,
+            self.span,
+            cx.meta_name_value(self.span,
                                @"doc",
                                ast::lit_str(@"Automatically derived.", ast::CookedStr)));
         cx.item(
-            trait_span,
+            self.span,
             ::parse::token::special_idents::clownshoes_extensions,
             ~[doc_attr],
             ast::item_impl(trait_generics,
@@ -400,73 +406,70 @@ impl<'self> TraitDef<'self> {
                            methods.map(|x| *x)))
     }
 
-    fn expand_struct_def(&self, cx: @ExtCtxt,
-                         trait_span: Span,
+    fn expand_struct_def(&self,
                          struct_def: &struct_def,
                          type_ident: Ident,
                          generics: &Generics) -> @ast::item {
         let methods = self.methods.map(|method_def| {
             let (explicit_self, self_args, nonself_args, tys) =
-                method_def.split_self_nonself_args(cx, trait_span, type_ident, generics);
+                method_def.split_self_nonself_args(self, type_ident, generics);
 
             let body = if method_def.is_static() {
                 method_def.expand_static_struct_method_body(
-                    cx, trait_span,
+                    self,
                     struct_def,
                     type_ident,
                     self_args, nonself_args)
             } else {
-                method_def.expand_struct_method_body(cx, trait_span,
+                method_def.expand_struct_method_body(self,
                                                      struct_def,
                                                      type_ident,
                                                      self_args, nonself_args)
             };
 
-            method_def.create_method(cx, trait_span,
+            method_def.create_method(self,
                                      type_ident, generics,
                                      explicit_self, tys,
                                      body)
         });
 
-        self.create_derived_impl(cx, trait_span, type_ident, generics, methods)
+        self.create_derived_impl(type_ident, generics, methods)
     }
 
     fn expand_enum_def(&self,
-                       cx: @ExtCtxt, trait_span: Span,
                        enum_def: &enum_def,
                        type_ident: Ident,
                        generics: &Generics) -> @ast::item {
         let methods = self.methods.map(|method_def| {
             let (explicit_self, self_args, nonself_args, tys) =
-                method_def.split_self_nonself_args(cx, trait_span, type_ident, generics);
+                method_def.split_self_nonself_args(self, type_ident, generics);
 
             let body = if method_def.is_static() {
                 method_def.expand_static_enum_method_body(
-                    cx, trait_span,
+                    self,
                     enum_def,
                     type_ident,
                     self_args, nonself_args)
             } else {
-                method_def.expand_enum_method_body(cx, trait_span,
+                method_def.expand_enum_method_body(self,
                                                    enum_def,
                                                    type_ident,
                                                    self_args, nonself_args)
             };
 
-            method_def.create_method(cx, trait_span,
+            method_def.create_method(self,
                                      type_ident, generics,
                                      explicit_self, tys,
                                      body)
         });
 
-        self.create_derived_impl(cx, trait_span, type_ident, generics, methods)
+        self.create_derived_impl(type_ident, generics, methods)
     }
 }
 
 impl<'self> MethodDef<'self> {
     fn call_substructure_method(&self,
-                                cx: @ExtCtxt,
-                                trait_span: Span,
+                                trait_: &TraitDef,
                                 type_ident: Ident,
                                 self_args: &[@Expr],
                                 nonself_args: &[@Expr],
@@ -474,25 +477,25 @@ impl<'self> MethodDef<'self> {
         -> @Expr {
         let substructure = Substructure {
             type_ident: type_ident,
-            method_ident: cx.ident_of(self.name),
+            method_ident: trait_.cx.ident_of(self.name),
             self_args: self_args,
             nonself_args: nonself_args,
             fields: fields
         };
-        (self.combine_substructure)(cx, trait_span,
+        (self.combine_substructure)(trait_.cx, trait_.span,
                                     &substructure)
     }
 
-    fn get_ret_ty(&self, cx: @ExtCtxt, trait_span: Span,
+    fn get_ret_ty(&self, trait_: &TraitDef,
                   generics: &Generics, type_ident: Ident) -> P<ast::Ty> {
-        self.ret_ty.to_ty(cx, trait_span, type_ident, generics)
+        self.ret_ty.to_ty(trait_.cx, trait_.span, type_ident, generics)
     }
 
     fn is_static(&self) -> bool {
         self.explicit_self.is_none()
     }
 
-    fn split_self_nonself_args(&self, cx: @ExtCtxt, trait_span: Span,
+    fn split_self_nonself_args(&self, trait_: &TraitDef,
                                type_ident: Ident, generics: &Generics)
         -> (ast::explicit_self, ~[@Expr], ~[@Expr], ~[(Ident, P<ast::Ty>)]) {
 
@@ -503,22 +506,23 @@ impl<'self> MethodDef<'self> {
 
         let ast_explicit_self = match self.explicit_self {
             Some(ref self_ptr) => {
-                let (self_expr, explicit_self) = ty::get_explicit_self(cx, trait_span, self_ptr);
+                let (self_expr, explicit_self) =
+                    ty::get_explicit_self(trait_.cx, trait_.span, self_ptr);
 
                 self_args.push(self_expr);
                 nonstatic = true;
 
                 explicit_self
             }
-            None => respan(trait_span, ast::sty_static),
+            None => codemap::respan(trait_.span, ast::sty_static),
         };
 
         for (i, ty) in self.args.iter().enumerate() {
-            let ast_ty = ty.to_ty(cx, trait_span, type_ident, generics);
-            let ident = cx.ident_of(format!("__arg_{}", i));
+            let ast_ty = ty.to_ty(trait_.cx, trait_.span, type_ident, generics);
+            let ident = trait_.cx.ident_of(format!("__arg_{}", i));
             arg_tys.push((ident, ast_ty));
 
-            let arg_expr = cx.expr_ident(trait_span, ident);
+            let arg_expr = trait_.cx.expr_ident(trait_.span, ident);
 
             match *ty {
                 // for static methods, just treat any Self
@@ -527,7 +531,7 @@ impl<'self> MethodDef<'self> {
                     self_args.push(arg_expr);
                 }
                 Ptr(~Self, _) if nonstatic => {
-                    self_args.push(cx.expr_deref(trait_span, arg_expr))
+                    self_args.push(trait_.cx.expr_deref(trait_.span, arg_expr))
                 }
                 _ => {
                     nonself_args.push(arg_expr);
@@ -538,27 +542,27 @@ impl<'self> MethodDef<'self> {
         (ast_explicit_self, self_args, nonself_args, arg_tys)
     }
 
-    fn create_method(&self, cx: @ExtCtxt, trait_span: Span,
+    fn create_method(&self, trait_: &TraitDef,
                      type_ident: Ident,
                      generics: &Generics,
                      explicit_self: ast::explicit_self,
                      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);
+        let fn_generics = self.generics.to_generics(trait_.cx, trait_.span, type_ident, generics);
 
         let args = arg_types.move_iter().map(|(name, ty)| {
-            cx.arg(trait_span, name, ty)
+            trait_.cx.arg(trait_.span, name, ty)
         }).collect();
 
-        let ret_type = self.get_ret_ty(cx, trait_span, generics, type_ident);
+        let ret_type = self.get_ret_ty(trait_, generics, type_ident);
 
-        let method_ident = cx.ident_of(self.name);
-        let fn_decl = cx.fn_decl(args, ret_type);
-        let body_block = cx.block_expr(body);
+        let method_ident = trait_.cx.ident_of(self.name);
+        let fn_decl = trait_.cx.fn_decl(args, ret_type);
+        let body_block = trait_.cx.block_expr(body);
 
         let attrs = if self.inline {
-            ~[cx.attribute(trait_span, cx.meta_word(trait_span, @"inline"))]
+            ~[trait_.cx.attribute(trait_.span, trait_.cx.meta_word(trait_.span, @"inline"))]
         } else {
             ~[]
         };
@@ -573,7 +577,7 @@ impl<'self> MethodDef<'self> {
             decl: fn_decl,
             body: body_block,
             id: ast::DUMMY_NODE_ID,
-            span: trait_span,
+            span: trait_.span,
             self_id: ast::DUMMY_NODE_ID,
             vis: ast::inherited,
         }
@@ -601,8 +605,7 @@ impl<'self> MethodDef<'self> {
    ~~~
     */
     fn expand_struct_method_body(&self,
-                                 cx: @ExtCtxt,
-                                 trait_span: Span,
+                                 trait_: &TraitDef,
                                  struct_def: &struct_def,
                                  type_ident: Ident,
                                  self_args: &[@Expr],
@@ -613,10 +616,9 @@ impl<'self> MethodDef<'self> {
                                  // [fields of next Self arg], [etc]]
         let mut patterns = ~[];
         for i in range(0u, self_args.len()) {
-            let (pat, ident_expr) = create_struct_pattern(cx, trait_span,
-                                                          type_ident, struct_def,
-                                                          format!("__self_{}", i),
-                                                          ast::MutImmutable);
+            let (pat, ident_expr) = trait_.create_struct_pattern(type_ident, struct_def,
+                                                                 format!("__self_{}", i),
+                                                                 ast::MutImmutable);
             patterns.push(pat);
             raw_fields.push(ident_expr);
         }
@@ -638,13 +640,14 @@ impl<'self> MethodDef<'self> {
                     }
                 }).collect()
             }
-            [] => { cx.span_bug(trait_span, "No self arguments to non-static \
-                                       method in generic `deriving`") }
+            [] => { trait_.cx.span_bug(trait_.span,
+                                       "No self arguments to non-static method \
+                                       in generic `deriving`") }
         };
 
         // body of the inner most destructuring match
         let mut body = self.call_substructure_method(
-            cx, trait_span,
+            trait_,
             type_ident,
             self_args,
             nonself_args,
@@ -654,23 +657,22 @@ impl<'self> MethodDef<'self> {
         // structs. This is actually right-to-left, but it shoudn't
         // matter.
         for (&arg_expr, &pat) in self_args.iter().zip(patterns.iter()) {
-            body = cx.expr_match(trait_span, arg_expr,
-                                 ~[ cx.arm(trait_span, ~[pat], body) ])
+            body = trait_.cx.expr_match(trait_.span, arg_expr,
+                                        ~[ trait_.cx.arm(trait_.span, ~[pat], body) ])
         }
         body
     }
 
     fn expand_static_struct_method_body(&self,
-                                        cx: @ExtCtxt,
-                                        trait_span: Span,
+                                        trait_: &TraitDef,
                                         struct_def: &struct_def,
                                         type_ident: Ident,
                                         self_args: &[@Expr],
                                         nonself_args: &[@Expr])
         -> @Expr {
-        let summary = summarise_struct(cx, trait_span, struct_def);
+        let summary = trait_.summarise_struct(struct_def);
 
-        self.call_substructure_method(cx, trait_span,
+        self.call_substructure_method(trait_,
                                       type_ident,
                                       self_args, nonself_args,
                                       &StaticStruct(struct_def, summary))
@@ -703,15 +705,14 @@ impl<'self> MethodDef<'self> {
    ~~~
     */
     fn expand_enum_method_body(&self,
-                               cx: @ExtCtxt,
-                               trait_span: Span,
+                               trait_: &TraitDef,
                                enum_def: &enum_def,
                                type_ident: Ident,
                                self_args: &[@Expr],
                                nonself_args: &[@Expr])
         -> @Expr {
         let mut matches = ~[];
-        self.build_enum_match(cx, trait_span, enum_def, type_ident,
+        self.build_enum_match(trait_, enum_def, type_ident,
                               self_args, nonself_args,
                               None, &mut matches, 0)
     }
@@ -739,7 +740,7 @@ impl<'self> MethodDef<'self> {
     the first call).
     */
     fn build_enum_match(&self,
-                        cx: @ExtCtxt, trait_span: Span,
+                        trait_: &TraitDef,
                         enum_def: &enum_def,
                         type_ident: Ident,
                         self_args: &[@Expr],
@@ -748,12 +749,13 @@ impl<'self> MethodDef<'self> {
                         matches_so_far: &mut ~[(uint, P<ast::variant>,
                                               ~[(Span, Option<Ident>, @Expr)])],
                         match_count: uint) -> @Expr {
+        let cx = trait_.cx;
         if match_count == self_args.len() {
             // we've matched against all arguments, so make the final
             // expression at the bottom of the match tree
             if matches_so_far.len() == 0 {
-                cx.span_bug(trait_span, "no self match on an enum in generic \
-                                   `deriving`");
+                cx.span_bug(trait_.span,
+                            "no self match on an enum in generic `deriving`");
             }
             // we currently have a vec of vecs, where each
             // subvec is the fields of one of the arguments,
@@ -803,7 +805,7 @@ impl<'self> MethodDef<'self> {
                     substructure = EnumNonMatching(*matches_so_far);
                 }
             }
-            self.call_substructure_method(cx, trait_span, type_ident,
+            self.call_substructure_method(trait_, type_ident,
                                           self_args, nonself_args,
                                           &substructure)
 
@@ -822,20 +824,19 @@ impl<'self> MethodDef<'self> {
                 // make a matching-variant match, and a _ match.
                 let index = match matching {
                     Some(i) => i,
-                    None => cx.span_bug(trait_span,
+                    None => cx.span_bug(trait_.span,
                                         "Non-matching variants when required to \
                                         be matching in generic `deriving`")
                 };
 
                 // matching-variant match
                 let variant = enum_def.variants[index];
-                let (pattern, idents) = create_enum_variant_pattern(cx,
-                                                                    variant,
-                                                                    current_match_str,
-                                                                    ast::MutImmutable);
+                let (pattern, idents) = trait_.create_enum_variant_pattern(variant,
+                                                                           current_match_str,
+                                                                           ast::MutImmutable);
 
                 matches_so_far.push((index, variant, idents));
-                let arm_expr = self.build_enum_match(cx, trait_span,
+                let arm_expr = self.build_enum_match(trait_,
                                                      enum_def,
                                                      type_ident,
                                                      self_args, nonself_args,
@@ -843,25 +844,24 @@ impl<'self> MethodDef<'self> {
                                                      matches_so_far,
                                                      match_count + 1);
                 matches_so_far.pop();
-                arms.push(cx.arm(trait_span, ~[ pattern ], arm_expr));
+                arms.push(cx.arm(trait_.span, ~[ pattern ], arm_expr));
 
                 if enum_def.variants.len() > 1 {
                     let e = &EnumNonMatching(&[]);
-                    let wild_expr = self.call_substructure_method(cx, trait_span, type_ident,
+                    let wild_expr = self.call_substructure_method(trait_, type_ident,
                                                                   self_args, nonself_args,
                                                                   e);
-                    let wild_arm = cx.arm(trait_span,
-                                          ~[ cx.pat_wild(trait_span) ],
+                    let wild_arm = cx.arm(trait_.span,
+                                          ~[ cx.pat_wild(trait_.span) ],
                                           wild_expr);
                     arms.push(wild_arm);
                 }
             } else {
                 // create an arm matching on each variant
                 for (index, &variant) in enum_def.variants.iter().enumerate() {
-                    let (pattern, idents) = create_enum_variant_pattern(cx,
-                                                                        variant,
-                                                                        current_match_str,
-                                                                        ast::MutImmutable);
+                    let (pattern, idents) = trait_.create_enum_variant_pattern(variant,
+                                                                               current_match_str,
+                                                                               ast::MutImmutable);
 
                     matches_so_far.push((index, variant, idents));
                     let new_matching =
@@ -870,7 +870,7 @@ impl<'self> MethodDef<'self> {
                             Some(i) if index == i => Some(i),
                             _ => None
                         };
-                    let arm_expr = self.build_enum_match(cx, trait_span,
+                    let arm_expr = self.build_enum_match(trait_,
                                                          enum_def,
                                                          type_ident,
                                                          self_args, nonself_args,
@@ -879,19 +879,18 @@ impl<'self> MethodDef<'self> {
                                                          match_count + 1);
                     matches_so_far.pop();
 
-                    let arm = cx.arm(trait_span, ~[ pattern ], arm_expr);
+                    let arm = cx.arm(trait_.span, ~[ pattern ], arm_expr);
                     arms.push(arm);
                 }
             }
 
             // match foo { arm, arm, arm, ... }
-            cx.expr_match(trait_span, self_args[match_count], arms)
+            cx.expr_match(trait_.span, self_args[match_count], arms)
         }
     }
 
     fn expand_static_enum_method_body(&self,
-                                      cx: @ExtCtxt,
-                                      trait_span: Span,
+                                      trait_: &TraitDef,
                                       enum_def: &enum_def,
                                       type_ident: Ident,
                                       self_args: &[@Expr],
@@ -902,158 +901,156 @@ impl<'self> MethodDef<'self> {
             let summary = match v.node.kind {
                 ast::tuple_variant_kind(ref args) => Unnamed(args.map(|va| va.ty.span)),
                 ast::struct_variant_kind(struct_def) => {
-                    summarise_struct(cx, trait_span, struct_def)
+                    trait_.summarise_struct(struct_def)
                 }
             };
             (ident, summary)
         });
-        self.call_substructure_method(cx,
-                                      trait_span, type_ident,
+        self.call_substructure_method(trait_, type_ident,
                                       self_args, nonself_args,
                                       &StaticEnum(enum_def, summary))
     }
 }
 
-fn summarise_struct(cx: @ExtCtxt, trait_span: Span,
-                    struct_def: &struct_def) -> StaticFields {
-    let mut named_idents = ~[];
-    let mut just_spans = ~[];
-    for field in struct_def.fields.iter() {
-        match field.node.kind {
-            ast::named_field(ident, _) => named_idents.push((ident, field.span)),
-            ast::unnamed_field => just_spans.push(field.span),
+#[deriving(Eq)] // dogfooding!
+enum StructType {
+    Unknown, Record, Tuple
+}
+
+// general helper methods.
+impl<'a> TraitDef<'a> {
+    fn summarise_struct(&self, struct_def: &struct_def) -> StaticFields {
+        let mut named_idents = ~[];
+        let mut just_spans = ~[];
+        for field in struct_def.fields.iter(){
+            let sp = field.span;
+            match field.node.kind {
+                ast::named_field(ident, _) => named_idents.push((ident, sp)),
+                ast::unnamed_field => just_spans.push(sp),
+            }
         }
-    }
 
-    match (just_spans.is_empty(), named_idents.is_empty()) {
-        (false, false) => cx.span_bug(trait_span,
-                                      "A struct with named and unnamed \
-                                      fields in generic `deriving`"),
-        // named fields
-        (_, false) => Named(named_idents),
-        // tuple structs (includes empty structs)
-        (_, _)     => Unnamed(just_spans)
+        match (just_spans.is_empty(), named_idents.is_empty()) {
+            (false, false) => self.cx.span_bug(self.span,
+                                               "A struct with named and unnamed \
+                                               fields in generic `deriving`"),
+            // named fields
+            (_, false) => Named(named_idents),
+            // tuple structs (includes empty structs)
+            (_, _)     => Unnamed(just_spans)
+        }
     }
-}
 
-pub fn create_subpatterns(cx: @ExtCtxt,
+    fn create_subpatterns(&self,
                           field_paths: ~[ast::Path],
                           mutbl: ast::Mutability)
-                   -> ~[@ast::Pat] {
-    field_paths.map(|path| {
-        cx.pat(path.span,
-               ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
-    })
-}
+                          -> ~[@ast::Pat] {
+        field_paths.map(|path| {
+            self.cx.pat(path.span,
+                        ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
+            })
+    }
 
-#[deriving(Eq)] // dogfooding!
-enum StructType {
-    Unknown, Record, Tuple
-}
+    fn create_struct_pattern(&self,
+                             struct_ident: Ident,
+                             struct_def: &struct_def,
+                             prefix: &str,
+                             mutbl: ast::Mutability)
+        -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) {
+        let cx = self.cx;
+
+        if struct_def.fields.is_empty() {
+            return (
+                cx.pat_ident_binding_mode(
+                    self.span, struct_ident, ast::BindByValue(ast::MutImmutable)),
+                ~[]);
+        }
 
-fn create_struct_pattern(cx: @ExtCtxt,
-                         trait_span: Span,
-                         struct_ident: Ident,
-                         struct_def: &struct_def,
-                         prefix: &str,
-                         mutbl: ast::Mutability)
-    -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) {
-    if struct_def.fields.is_empty() {
-        return (
-            cx.pat_ident_binding_mode(
-                trait_span, struct_ident, ast::BindByValue(ast::MutImmutable)),
-            ~[]);
-    }
+        let matching_path = cx.path(self.span, ~[ struct_ident ]);
 
-    let matching_path = cx.path(trait_span, ~[ struct_ident ]);
+        let mut paths = ~[];
+        let mut ident_expr = ~[];
+        let mut struct_type = Unknown;
 
-    let mut paths = ~[];
-    let mut ident_expr = ~[];
-    let mut struct_type = Unknown;
+        for (i, struct_field) in struct_def.fields.iter().enumerate() {
+            let sp = struct_field.span;
+            let opt_id = match struct_field.node.kind {
+                ast::named_field(ident, _) if (struct_type == Unknown ||
+                                               struct_type == Record) => {
+                    struct_type = Record;
+                    Some(ident)
+                }
+                ast::unnamed_field if (struct_type == Unknown ||
+                                       struct_type == Tuple) => {
+                    struct_type = Tuple;
+                    None
+                }
+                _ => {
+                    cx.span_bug(sp, "A struct with named and unnamed fields in `deriving`");
+                }
+            };
+            let path = cx.path_ident(sp, cx.ident_of(format!("{}_{}", prefix, i)));
+            paths.push(path.clone());
+            ident_expr.push((sp, opt_id, cx.expr_path(path)));
+        }
 
-    for (i, struct_field) in struct_def.fields.iter().enumerate() {
-        let opt_id = match struct_field.node.kind {
-            ast::named_field(ident, _) if (struct_type == Unknown ||
-                                           struct_type == Record) => {
-                struct_type = Record;
-                Some(ident)
-            }
-            ast::unnamed_field if (struct_type == Unknown ||
-                                   struct_type == Tuple) => {
-                struct_type = Tuple;
-                None
-            }
-            _ => {
-                cx.span_bug(struct_field.span,
-                            "A struct with named and unnamed fields in `deriving`");
-            }
+        let subpats = self.create_subpatterns(paths, mutbl);
+
+        // 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, _))| {
+                // id is guaranteed to be Some
+                ast::FieldPat { ident: id.unwrap(), pat: pat }
+            }).collect();
+            cx.pat_struct(self.span, matching_path, field_pats)
+        } else {
+            cx.pat_enum(self.span, matching_path, subpats)
         };
-        let path = cx.path_ident(struct_field.span,
-                                 cx.ident_of(format!("{}_{}", prefix, i)));
-        paths.push(path.clone());
-        ident_expr.push((struct_field.span, opt_id, cx.expr_path(path)));
-    }
 
-    let subpats = create_subpatterns(cx, paths, mutbl);
+        (pattern, ident_expr)
+    }
 
-    // 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, _))| {
-            // id is guaranteed to be Some
-            ast::FieldPat { ident: id.unwrap(), pat: pat }
-        }).collect();
-        cx.pat_struct(trait_span, matching_path, field_pats)
-    } else {
-        cx.pat_enum(trait_span, matching_path, subpats)
-    };
+    fn create_enum_variant_pattern(&self,
+                                   variant: &ast::variant,
+                                   prefix: &str,
+                                   mutbl: ast::Mutability)
+        -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) {
+        let cx = self.cx;
+        let variant_ident = variant.node.name;
+        match variant.node.kind {
+            ast::tuple_variant_kind(ref variant_args) => {
+                if variant_args.is_empty() {
+                    return (cx.pat_ident_binding_mode(variant.span, variant_ident,
+                                                      ast::BindByValue(ast::MutImmutable)),
+                            ~[]);
+                }
 
-    (pattern, ident_expr)
-}
+                let matching_path = cx.path_ident(variant.span, variant_ident);
 
-fn create_enum_variant_pattern(cx: @ExtCtxt,
-                               variant: &ast::variant,
-                               prefix: &str,
-                               mutbl: ast::Mutability)
-    -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) {
-
-    let variant_ident = variant.node.name;
-    match variant.node.kind {
-        ast::tuple_variant_kind(ref variant_args) => {
-            if variant_args.is_empty() {
-                return (cx.pat_ident_binding_mode(variant.span, variant_ident,
-                                                  ast::BindByValue(ast::MutImmutable)),
-                        ~[]);
-            }
+                let mut paths = ~[];
+                let mut ident_expr = ~[];
+                for (i, va) in variant_args.iter().enumerate() {
+                    let sp = va.ty.span;
+                    let path = cx.path_ident(sp, cx.ident_of(format!("{}_{}", prefix, i)));
 
-            let matching_path = cx.path_ident(variant.span, variant_ident);
+                    paths.push(path.clone());
+                    ident_expr.push((sp, None, cx.expr_path(path)));
+                }
 
-            let mut paths = ~[];
-            let mut ident_expr = ~[];
-            for (i, va) in variant_args.iter().enumerate() {
-                let path = cx.path_ident(va.ty.span,
-                                         cx.ident_of(format!("{}_{}", prefix, i)));
+                let subpats = self.create_subpatterns(paths, mutbl);
 
-                paths.push(path.clone());
-                ident_expr.push((va.ty.span, None, cx.expr_path(path)));
+                (cx.pat_enum(variant.span, matching_path, subpats),
+                 ident_expr)
+            }
+            ast::struct_variant_kind(struct_def) => {
+                self.create_struct_pattern(variant_ident, struct_def,
+                                           prefix, mutbl)
             }
-
-            let subpats = create_subpatterns(cx, paths, mutbl);
-
-            (cx.pat_enum(variant.span, matching_path, subpats),
-             ident_expr)
-        }
-        ast::struct_variant_kind(struct_def) => {
-            create_struct_pattern(cx, variant.span,
-                                  variant_ident, struct_def,
-                                  prefix,
-                                  mutbl)
         }
     }
 }
 
-
-
 /* helpful premade recipes */
 
 /**
diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs
index f291d2b751d..837b8bd59ec 100644
--- a/src/libsyntax/ext/deriving/iter_bytes.rs
+++ b/src/libsyntax/ext/deriving/iter_bytes.rs
@@ -20,6 +20,8 @@ pub fn expand_deriving_iter_bytes(cx: @ExtCtxt,
                                   mitem: @MetaItem,
                                   in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "to_bytes", "IterBytes"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -40,7 +42,7 @@ pub fn expand_deriving_iter_bytes(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn iter_bytes_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index b26a3a09f04..73ea627ff54 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -20,6 +20,8 @@ pub fn expand_deriving_from_primitive(cx: @ExtCtxt,
                                       mitem: @MetaItem,
                                       in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "num", "FromPrimitive"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -59,7 +61,7 @@ pub fn expand_deriving_from_primitive(cx: @ExtCtxt,
         ]
     };
 
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn cs_from(name: &str, cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index 40fdee481ed..91ed60324cf 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -22,6 +22,8 @@ pub fn expand_deriving_rand(cx: @ExtCtxt,
                             in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "rand", "Rand"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -45,7 +47,7 @@ pub fn expand_deriving_rand(cx: @ExtCtxt,
             }
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn rand_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs
index 193dc4965fc..fd8c21f4f98 100644
--- a/src/libsyntax/ext/deriving/to_str.rs
+++ b/src/libsyntax/ext/deriving/to_str.rs
@@ -21,6 +21,8 @@ pub fn expand_deriving_to_str(cx: @ExtCtxt,
                               in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "to_str", "ToStr"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -37,7 +39,7 @@ pub fn expand_deriving_to_str(cx: @ExtCtxt,
             }
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 // It used to be the case that this deriving implementation invoked
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
index 1fdb4131689..67f14a8d486 100644
--- a/src/libsyntax/ext/deriving/zero.rs
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -20,6 +20,8 @@ pub fn expand_deriving_zero(cx: @ExtCtxt,
                             in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
+        cx: cx, span: span,
+
         path: Path::new(~["std", "num", "Zero"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
@@ -52,7 +54,7 @@ pub fn expand_deriving_zero(cx: @ExtCtxt,
             }
         ]
     };
-    trait_def.expand(cx, span, mitem, in_items)
+    trait_def.expand(mitem, in_items)
 }
 
 fn zero_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {