]> git.lizzy.rs Git - rust.git/commitdiff
syntax: split deriving module into submodules for each trait
authorAndrew Paseltiner <apaseltiner@gmail.com>
Tue, 19 Mar 2013 12:52:10 +0000 (08:52 -0400)
committerAndrew Paseltiner <apaseltiner@gmail.com>
Tue, 19 Mar 2013 22:44:41 +0000 (18:44 -0400)
src/libsyntax/ext/base.rs
src/libsyntax/ext/deriving/clone.rs [new file with mode: 0644]
src/libsyntax/ext/deriving/eq.rs [new file with mode: 0644]
src/libsyntax/ext/deriving/iter_bytes.rs [new file with mode: 0644]
src/libsyntax/ext/deriving/mod.rs

index 652bc541a1f2e31f2cd059aa3ad2394086a78c7f..447ca71dc6b9fa77bd1622c0150cfe0df0aee9c3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -153,13 +153,13 @@ fn builtin_item_tt(f: SyntaxExpanderTTItemFun) -> @Transformer {
                                 ext::deriving::expand_meta_deriving)));
     syntax_expanders.insert(@~"deriving_eq",
                             @SE(ItemDecorator(
-                                ext::deriving::expand_deriving_eq)));
+                                ext::deriving::eq::expand_deriving_eq)));
     syntax_expanders.insert(@~"deriving_iter_bytes",
                             @SE(ItemDecorator(
-                                ext::deriving::expand_deriving_iter_bytes)));
+                                ext::deriving::iter_bytes::expand_deriving_iter_bytes)));
     syntax_expanders.insert(@~"deriving_clone",
                             @SE(ItemDecorator(
-                                ext::deriving::expand_deriving_clone)));
+                                ext::deriving::clone::expand_deriving_clone)));
 
     // Quasi-quoting expanders
     syntax_expanders.insert(@~"quote_tokens",
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
new file mode 100644 (file)
index 0000000..072cd0f
--- /dev/null
@@ -0,0 +1,289 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::prelude::*;
+
+use ast;
+use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
+use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_};
+use ast::{item_enum, item_impl, item_struct, Generics};
+use ast::{m_imm, meta_item, method};
+use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
+use ast::{stmt, struct_def, struct_variant_kind};
+use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam};
+use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
+use ext::base::ext_ctxt;
+use ext::build;
+use ext::deriving::*;
+use codemap::{span, spanned};
+use ast_util;
+
+use core::uint;
+
+pub fn expand_deriving_clone(cx: @ext_ctxt,
+                             span: span,
+                             _: @meta_item,
+                             in_items: ~[@item])
+                          -> ~[@item] {
+    expand_deriving(cx,
+                    span,
+                    in_items,
+                    expand_deriving_clone_struct_def,
+                    expand_deriving_clone_enum_def)
+}
+
+fn create_derived_clone_impl(cx: @ext_ctxt,
+                             span: span,
+                             type_ident: ident,
+                             generics: &Generics,
+                             method: @method)
+                          -> @item {
+    let methods = [ method ];
+    let trait_path = [
+        cx.ident_of(~"core"),
+        cx.ident_of(~"clone"),
+        cx.ident_of(~"Clone"),
+    ];
+    create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
+}
+// Creates a method from the given expression conforming to the signature of
+// the `clone` method.
+fn create_clone_method(cx: @ext_ctxt,
+                       span: span,
+                       +type_ident: ast::ident,
+                       generics: &Generics,
+                       expr: @ast::expr)
+                    -> @method {
+    // Create the type parameters of the return value.
+    let mut output_ty_params = ~[];
+    for generics.ty_params.each |ty_param| {
+        let path = build::mk_ty_path(cx, span, ~[ ty_param.ident ]);
+        output_ty_params.push(path);
+    }
+
+    // Create the type of the return value.
+    let output_type_path = build::mk_raw_path_(span,
+                                               ~[ type_ident ],
+                                               output_ty_params);
+    let output_type = ast::ty_path(output_type_path, cx.next_id());
+    let output_type = @ast::Ty {
+        id: cx.next_id(),
+        node: output_type,
+        span: span
+    };
+
+    // Create the function declaration.
+    let fn_decl = build::mk_fn_decl(~[], output_type);
+
+    // Create the body block.
+    let body_block = build::mk_simple_block(cx, span, expr);
+
+    // Create the self type and method identifier.
+    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
+    let method_ident = cx.ident_of(~"clone");
+
+    // Create the method.
+    @ast::method {
+        ident: method_ident,
+        attrs: ~[],
+        generics: ast_util::empty_generics(),
+        self_ty: self_ty,
+        purity: impure_fn,
+        decl: fn_decl,
+        body: body_block,
+        id: cx.next_id(),
+        span: span,
+        self_id: cx.next_id(),
+        vis: public,
+    }
+}
+
+fn call_substructure_clone_method(cx: @ext_ctxt,
+                                  span: span,
+                                  self_field: @expr)
+                               -> @expr {
+    // Call the substructure method.
+    let clone_ident = cx.ident_of(~"clone");
+    let self_method = build::mk_access_(cx, span, self_field, clone_ident);
+    build::mk_call_(cx, span, self_method, ~[])
+}
+
+fn expand_deriving_clone_struct_def(cx: @ext_ctxt,
+                                    span: span,
+                                    struct_def: &struct_def,
+                                    type_ident: ident,
+                                    generics: &Generics)
+                                 -> @item {
+    // Create the method.
+    let method = if !is_struct_tuple(struct_def) {
+        expand_deriving_clone_struct_method(cx,
+                                            span,
+                                            struct_def,
+                                            type_ident,
+                                            generics)
+    } else {
+        expand_deriving_clone_tuple_struct_method(cx,
+                                                  span,
+                                                  struct_def,
+                                                  type_ident,
+                                                  generics)
+    };
+
+    // Create the implementation.
+    create_derived_clone_impl(cx, span, type_ident, generics, method)
+}
+
+fn expand_deriving_clone_enum_def(cx: @ext_ctxt,
+                                  span: span,
+                                  enum_definition: &enum_def,
+                                  type_ident: ident,
+                                  generics: &Generics)
+                               -> @item {
+    // Create the method.
+    let method = expand_deriving_clone_enum_method(cx,
+                                                   span,
+                                                   enum_definition,
+                                                   type_ident,
+                                                   generics);
+
+    // Create the implementation.
+    create_derived_clone_impl(cx, span, type_ident, generics, method)
+}
+
+fn expand_deriving_clone_struct_method(cx: @ext_ctxt,
+                                       span: span,
+                                       struct_def: &struct_def,
+                                       type_ident: ident,
+                                       generics: &Generics)
+                                    -> @method {
+    let self_ident = cx.ident_of(~"self");
+
+    // Create the new fields.
+    let mut fields = ~[];
+    for struct_def.fields.each |struct_field| {
+        match struct_field.node.kind {
+            named_field(ident, _, _) => {
+                // Create the accessor for this field.
+                let self_field = build::mk_access(cx,
+                                                  span,
+                                                  ~[ self_ident ],
+                                                  ident);
+
+                // Call the substructure method.
+                let call = call_substructure_clone_method(cx,
+                                                          span,
+                                                          self_field);
+
+                let field = build::Field { ident: ident, ex: call };
+                fields.push(field);
+            }
+            unnamed_field => {
+                cx.span_bug(span,
+                            ~"unnamed fields in \
+                              expand_deriving_clone_struct_method");
+            }
+        }
+    }
+
+    // Create the struct literal.
+    let struct_literal = build::mk_struct_e(cx,
+                                            span,
+                                            ~[ type_ident ],
+                                            fields);
+    create_clone_method(cx, span, type_ident, generics, struct_literal)
+}
+
+fn expand_deriving_clone_tuple_struct_method(cx: @ext_ctxt,
+                                             span: span,
+                                             struct_def: &struct_def,
+                                             type_ident: ident,
+                                             generics: &Generics)
+                                          -> @method {
+    // Create the pattern for the match.
+    let matching_path = build::mk_raw_path(span, ~[ type_ident ]);
+    let field_count = struct_def.fields.len();
+    let subpats = create_subpatterns(cx, span, ~"__self", field_count);
+    let pat = build::mk_pat_enum(cx, span, matching_path, subpats);
+
+    // Create the new fields.
+    let mut subcalls = ~[];
+    for uint::range(0, struct_def.fields.len()) |i| {
+        // Create the expression for this field.
+        let field_ident = cx.ident_of(~"__self" + i.to_str());
+        let field = build::mk_path(cx, span, ~[ field_ident ]);
+
+        // Call the substructure method.
+        let subcall = call_substructure_clone_method(cx, span, field);
+        subcalls.push(subcall);
+    }
+
+    // Create the call to the struct constructor.
+    let call = build::mk_call(cx, span, ~[ type_ident ], subcalls);
+
+    // Create the pattern body.
+    let match_body_block = build::mk_simple_block(cx, span, call);
+
+    // Create the arm.
+    let arm = ast::arm {
+        pats: ~[ pat ],
+        guard: None,
+        body: match_body_block
+    };
+
+    // Create the method body.
+    let self_match_expr = expand_enum_or_struct_match(cx, span, ~[ arm ]);
+
+    // Create the method.
+    create_clone_method(cx, span, type_ident, generics, self_match_expr)
+}
+
+fn expand_deriving_clone_enum_method(cx: @ext_ctxt,
+                                     span: span,
+                                     enum_definition: &enum_def,
+                                     type_ident: ident,
+                                     generics: &Generics)
+                                  -> @method {
+    // Create the arms of the match in the method body.
+    let arms = do enum_definition.variants.map |variant| {
+        // Create the matching pattern.
+        let pat = create_enum_variant_pattern(cx, span, variant, ~"__self");
+
+        // Iterate over the variant arguments, creating the subcalls.
+        let mut subcalls = ~[];
+        for uint::range(0, variant_arg_count(cx, span, variant)) |j| {
+            // Create the expression for this field.
+            let field_ident = cx.ident_of(~"__self" + j.to_str());
+            let field = build::mk_path(cx, span, ~[ field_ident ]);
+
+            // Call the substructure method.
+            let subcall = call_substructure_clone_method(cx, span, field);
+            subcalls.push(subcall);
+        }
+
+        // Create the call to the enum variant (if necessary).
+        let call = if subcalls.len() > 0 {
+            build::mk_call(cx, span, ~[ variant.node.name ], subcalls)
+        } else {
+            build::mk_path(cx, span, ~[ variant.node.name ])
+        };
+
+        // Create the pattern body.
+        let match_body_block = build::mk_simple_block(cx, span, call);
+
+        // Create the arm.
+        ast::arm { pats: ~[ pat ], guard: None, body: match_body_block }
+    };
+
+    // Create the method body.
+    let self_match_expr = expand_enum_or_struct_match(cx, span, arms);
+
+    // Create the method.
+    create_clone_method(cx, span, type_ident, generics, self_match_expr)
+}
diff --git a/src/libsyntax/ext/deriving/eq.rs b/src/libsyntax/ext/deriving/eq.rs
new file mode 100644 (file)
index 0000000..6213eec
--- /dev/null
@@ -0,0 +1,498 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::prelude::*;
+
+use ast;
+use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
+use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_};
+use ast::{item_enum, item_impl, item_struct, Generics};
+use ast::{m_imm, meta_item, method};
+use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
+use ast::{stmt, struct_def, struct_variant_kind};
+use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam};
+use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
+use ext::base::ext_ctxt;
+use ext::build;
+use ext::deriving::*;
+use codemap::{span, spanned};
+use ast_util;
+
+use core::uint;
+
+enum Junction {
+    Conjunction,
+    Disjunction,
+}
+
+pub impl Junction {
+    fn to_binop(self) -> binop {
+        match self {
+            Conjunction => and,
+            Disjunction => or,
+        }
+    }
+}
+
+pub fn expand_deriving_eq(cx: @ext_ctxt,
+                          span: span,
+                          _mitem: @meta_item,
+                          in_items: ~[@item])
+                       -> ~[@item] {
+    expand_deriving(cx,
+                    span,
+                    in_items,
+                    expand_deriving_eq_struct_def,
+                    expand_deriving_eq_enum_def)
+}
+
+/// Creates a method from the given expression, the signature of which
+/// conforms to the `eq` or `ne` method.
+fn create_eq_method(cx: @ext_ctxt,
+                    span: span,
+                    method_ident: ident,
+                    type_ident: ident,
+                    generics: &Generics,
+                    body: @expr)
+                 -> @method {
+    // Create the type of the `other` parameter.
+    let arg_path_type = create_self_type_with_params(cx,
+                                                     span,
+                                                     type_ident,
+                                                     generics);
+    let arg_type = ty_rptr(
+        None,
+        ast::mt { ty: arg_path_type, mutbl: m_imm }
+    );
+    let arg_type = @ast::Ty {
+        id: cx.next_id(),
+        node: arg_type,
+        span: span,
+    };
+
+    // Create the `other` parameter.
+    let other_ident = cx.ident_of(~"__other");
+    let arg = build::mk_arg(cx, span, other_ident, arg_type);
+
+    // Create the type of the return value.
+    let bool_ident = cx.ident_of(~"bool");
+    let output_type = build::mk_raw_path(span, ~[ bool_ident ]);
+    let output_type = ty_path(output_type, cx.next_id());
+    let output_type = @ast::Ty {
+        id: cx.next_id(),
+        node: output_type,
+        span: span,
+    };
+
+    // Create the function declaration.
+    let fn_decl = build::mk_fn_decl(~[ arg ], output_type);
+
+    // Create the body block.
+    let body_block = build::mk_simple_block(cx, span, body);
+
+    // Create the method.
+    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
+    @ast::method {
+        ident: method_ident,
+        attrs: ~[],
+        generics: ast_util::empty_generics(),
+        self_ty: self_ty,
+        purity: impure_fn,
+        decl: fn_decl,
+        body: body_block,
+        id: cx.next_id(),
+        span: span,
+        self_id: cx.next_id(),
+        vis: public
+    }
+}
+
+fn create_derived_eq_impl(cx: @ext_ctxt,
+                          span: span,
+                          type_ident: ident,
+                          generics: &Generics,
+                          eq_method: @method,
+                          ne_method: @method)
+                       -> @item {
+    let methods = [ eq_method, ne_method ];
+    let trait_path = [
+        cx.ident_of(~"core"),
+        cx.ident_of(~"cmp"),
+        cx.ident_of(~"Eq")
+    ];
+    create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
+}
+
+fn call_substructure_eq_method(cx: @ext_ctxt,
+                               span: span,
+                               self_field: @expr,
+                               other_field_ref: @expr,
+                               method_ident: ident,
+                               junction: Junction,
+                               chain_expr: &mut Option<@expr>) {
+    // Call the substructure method.
+    let self_method = build::mk_access_(cx, span, self_field, method_ident);
+    let self_call = build::mk_call_(cx,
+                                    span,
+                                    self_method,
+                                    ~[ other_field_ref ]);
+
+    // Connect to the outer expression if necessary.
+    *chain_expr = match *chain_expr {
+        None => Some(self_call),
+        Some(copy old_outer_expr) => {
+            let binop = junction.to_binop();
+            let chain_expr = build::mk_binary(cx,
+                                              span,
+                                              binop,
+                                              old_outer_expr,
+                                              self_call);
+            Some(chain_expr)
+        }
+    };
+}
+
+fn finish_eq_chain_expr(cx: @ext_ctxt,
+                        span: span,
+                        chain_expr: Option<@expr>,
+                        junction: Junction)
+                     -> @expr {
+    match chain_expr {
+        None => {
+            match junction {
+                Conjunction => build::mk_bool(cx, span, true),
+                Disjunction => build::mk_bool(cx, span, false),
+            }
+        }
+        Some(ref outer_expr) => *outer_expr,
+    }
+}
+
+fn expand_deriving_eq_struct_def(cx: @ext_ctxt,
+                                 span: span,
+                                 struct_def: &struct_def,
+                                 type_ident: ident,
+                                 generics: &Generics)
+                              -> @item {
+    // Create the methods.
+    let eq_ident = cx.ident_of(~"eq");
+    let ne_ident = cx.ident_of(~"ne");
+
+    let derive_struct_fn = if is_struct_tuple(struct_def) {
+        expand_deriving_eq_struct_tuple_method
+    } else {
+        expand_deriving_eq_struct_method
+    };
+
+    let eq_method = derive_struct_fn(cx,
+                                     span,
+                                     struct_def,
+                                     eq_ident,
+                                     type_ident,
+                                     generics,
+                                     Conjunction);
+    let ne_method = derive_struct_fn(cx,
+                                     span,
+                                     struct_def,
+                                     ne_ident,
+                                     type_ident,
+                                     generics,
+                                     Disjunction);
+
+    // Create the implementation.
+    return create_derived_eq_impl(cx,
+                                  span,
+                                  type_ident,
+                                  generics,
+                                  eq_method,
+                                  ne_method);
+}
+
+fn expand_deriving_eq_enum_def(cx: @ext_ctxt,
+                               span: span,
+                               enum_definition: &enum_def,
+                               type_ident: ident,
+                               generics: &Generics)
+                            -> @item {
+    // Create the methods.
+    let eq_ident = cx.ident_of(~"eq");
+    let ne_ident = cx.ident_of(~"ne");
+    let eq_method = expand_deriving_eq_enum_method(cx,
+                                                   span,
+                                                   enum_definition,
+                                                   eq_ident,
+                                                   type_ident,
+                                                   generics,
+                                                   Conjunction);
+    let ne_method = expand_deriving_eq_enum_method(cx,
+                                                   span,
+                                                   enum_definition,
+                                                   ne_ident,
+                                                   type_ident,
+                                                   generics,
+                                                   Disjunction);
+
+    // Create the implementation.
+    return create_derived_eq_impl(cx,
+                                  span,
+                                  type_ident,
+                                  generics,
+                                  eq_method,
+                                  ne_method);
+}
+
+fn expand_deriving_eq_struct_method(cx: @ext_ctxt,
+                                    span: span,
+                                    struct_def: &struct_def,
+                                    method_ident: ident,
+                                    type_ident: ident,
+                                    generics: &Generics,
+                                    junction: Junction)
+                                 -> @method {
+    let self_ident = cx.ident_of(~"self");
+    let other_ident = cx.ident_of(~"__other");
+
+    // Create the body of the method.
+    let mut outer_expr = None;
+    for struct_def.fields.each |struct_field| {
+        match struct_field.node.kind {
+            named_field(ident, _, _) => {
+                // Create the accessor for the other field.
+                let other_field = build::mk_access(cx,
+                                                   span,
+                                                   ~[ other_ident ],
+                                                   ident);
+                let other_field_ref = build::mk_addr_of(cx,
+                                                        span,
+                                                        other_field);
+
+                // Create the accessor for this field.
+                let self_field = build::mk_access(cx,
+                                                  span,
+                                                  ~[ self_ident ],
+                                                  ident);
+
+                // Call the substructure method.
+                call_substructure_eq_method(cx,
+                                            span,
+                                            self_field,
+                                            other_field_ref,
+                                            method_ident,
+                                            junction,
+                                            &mut outer_expr);
+            }
+            unnamed_field => {
+                cx.span_unimpl(span, ~"unnamed fields with `deriving_eq`");
+            }
+        }
+    }
+
+    // Create the method itself.
+    let body = finish_eq_chain_expr(cx, span, outer_expr, junction);
+    return create_eq_method(cx,
+                            span,
+                            method_ident,
+                            type_ident,
+                            generics,
+                            body);
+}
+
+fn expand_deriving_eq_enum_method(cx: @ext_ctxt,
+                                  span: span,
+                                  enum_definition: &enum_def,
+                                  method_ident: ident,
+                                  type_ident: ident,
+                                  generics: &Generics,
+                                  junction: Junction)
+                               -> @method {
+    let self_ident = cx.ident_of(~"self");
+    let other_ident = cx.ident_of(~"__other");
+
+    let is_eq;
+    match junction {
+        Conjunction => is_eq = true,
+        Disjunction => is_eq = false,
+    }
+
+    // Create the arms of the self match in the method body.
+    let mut self_arms = ~[];
+    for enum_definition.variants.each |self_variant| {
+        let mut other_arms = ~[];
+
+        // Create the matching pattern.
+        let matching_pat = create_enum_variant_pattern(cx,
+                                                       span,
+                                                       self_variant,
+                                                       ~"__other");
+
+        // Create the matching pattern body.
+        let mut matching_body_expr = None;
+        for uint::range(0, variant_arg_count(cx, span, self_variant)) |i| {
+            // Create the expression for the other field.
+            let other_field_ident = cx.ident_of(~"__other" + i.to_str());
+            let other_field = build::mk_path(cx,
+                                             span,
+                                             ~[ other_field_ident ]);
+
+            // Create the expression for this field.
+            let self_field_ident = cx.ident_of(~"__self" + i.to_str());
+            let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
+
+            // Call the substructure method.
+            call_substructure_eq_method(cx,
+                                        span,
+                                        self_field,
+                                        other_field,
+                                        method_ident,
+                                        junction,
+                                        &mut matching_body_expr);
+        }
+
+        let matching_body_expr = finish_eq_chain_expr(cx,
+                                                      span,
+                                                      matching_body_expr,
+                                                      junction);
+        let matching_body_block = build::mk_simple_block(cx,
+                                                         span,
+                                                         matching_body_expr);
+
+        // Create the matching arm.
+        let matching_arm = ast::arm {
+            pats: ~[ matching_pat ],
+            guard: None,
+            body: matching_body_block
+        };
+        other_arms.push(matching_arm);
+
+        // Maybe generate a non-matching case. If there is only one
+        // variant then there will always be a match.
+        if enum_definition.variants.len() > 1 {
+            // Create the nonmatching pattern.
+            let nonmatching_pat = @ast::pat {
+                id: cx.next_id(),
+                node: pat_wild,
+                span: span
+            };
+
+            // Create the nonmatching pattern body.
+            let nonmatching_expr = build::mk_bool(cx, span, !is_eq);
+            let nonmatching_body_block =
+                build::mk_simple_block(cx,
+                                       span,
+                                       nonmatching_expr);
+
+            // Create the nonmatching arm.
+            let nonmatching_arm = ast::arm {
+                pats: ~[ nonmatching_pat ],
+                guard: None,
+                body: nonmatching_body_block,
+            };
+            other_arms.push(nonmatching_arm);
+        }
+
+        // Create the self pattern.
+        let self_pat = create_enum_variant_pattern(cx,
+                                                   span,
+                                                   self_variant,
+                                                   ~"__self");
+
+        // Create the self pattern body.
+        let other_expr = build::mk_path(cx, span, ~[ other_ident ]);
+        let other_expr = build::mk_unary(cx, span, deref, other_expr);
+        let other_match_expr = expr_match(other_expr, other_arms);
+        let other_match_expr = build::mk_expr(cx,
+                                              span,
+                                              other_match_expr);
+        let other_match_body_block = build::mk_simple_block(cx,
+                                                            span,
+                                                            other_match_expr);
+
+        // Create the self arm.
+        let self_arm = ast::arm {
+            pats: ~[ self_pat ],
+            guard: None,
+            body: other_match_body_block,
+        };
+        self_arms.push(self_arm);
+    }
+
+    // Create the method body.
+    let self_expr = build::mk_path(cx, span, ~[ self_ident ]);
+    let self_expr = build::mk_unary(cx, span, deref, self_expr);
+    let self_match_expr = expr_match(self_expr, self_arms);
+    let self_match_expr = build::mk_expr(cx, span, self_match_expr);
+
+    // Create the method.
+    return create_eq_method(cx,
+                            span,
+                            method_ident,
+                            type_ident,
+                            generics,
+                            self_match_expr);
+}
+
+fn expand_deriving_eq_struct_tuple_method(cx: @ext_ctxt,
+                                          span: span,
+                                          struct_def: &struct_def,
+                                          method_ident: ident,
+                                          type_ident: ident,
+                                          generics: &Generics,
+                                          junction: Junction)
+                                        -> @method {
+    let self_str = ~"self";
+    let other_str = ~"__other";
+    let type_path = build::mk_raw_path(span, ~[type_ident]);
+    let fields = copy struct_def.fields;
+
+    // Create comparison expression, comparing each of the fields
+    let mut match_body = None;
+    for fields.eachi |i, _| {
+        let other_field_ident = cx.ident_of(other_str + i.to_str());
+        let other_field = build::mk_path(cx, span, ~[ other_field_ident ]);
+
+        let self_field_ident = cx.ident_of(self_str + i.to_str());
+        let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
+
+        call_substructure_eq_method(cx, span, self_field, other_field,
+            method_ident, junction, &mut match_body);
+    }
+    let match_body = finish_eq_chain_expr(cx, span, match_body, junction);
+
+    // Create arm for the '__other' match, containing the comparison expr
+    let other_subpats = create_subpatterns(cx, span, other_str, fields.len());
+    let other_arm = ast::arm {
+        pats: ~[ build::mk_pat_enum(cx, span, type_path, other_subpats) ],
+        guard: None,
+        body: build::mk_simple_block(cx, span, match_body),
+    };
+
+    // Create the match on '__other'
+    let other_expr = build::mk_path(cx, span, ~[ cx.ident_of(other_str) ]);
+    let other_expr = build::mk_unary(cx, span, deref, other_expr);
+    let other_match_expr = expr_match(other_expr, ~[other_arm]);
+    let other_match_expr = build::mk_expr(cx, span, other_match_expr);
+
+    // Create arm for the 'self' match, which contains the '__other' match
+    let self_subpats = create_subpatterns(cx, span, self_str, fields.len());
+    let self_arm = ast::arm {
+        pats: ~[build::mk_pat_enum(cx, span, type_path, self_subpats)],
+        guard: None,
+        body: build::mk_simple_block(cx, span, other_match_expr),
+    };
+
+    // Create the match on 'self'
+    let self_expr = build::mk_path(cx, span, ~[ cx.ident_of(self_str) ]);
+    let self_expr = build::mk_unary(cx, span, deref, self_expr);
+    let self_match_expr = expr_match(self_expr, ~[self_arm]);
+    let self_match_expr = build::mk_expr(cx, span, self_match_expr);
+
+    create_eq_method(cx, span, method_ident,
+        type_ident, generics, self_match_expr)
+}
diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs
new file mode 100644 (file)
index 0000000..613e9c2
--- /dev/null
@@ -0,0 +1,256 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core::prelude::*;
+
+use ast;
+use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
+use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_};
+use ast::{item_enum, item_impl, item_struct, Generics};
+use ast::{m_imm, meta_item, method};
+use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
+use ast::{stmt, struct_def, struct_variant_kind};
+use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam};
+use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
+use ext::base::ext_ctxt;
+use ext::build;
+use ext::deriving::*;
+use codemap::{span, spanned};
+use ast_util;
+
+use core::uint;
+
+pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
+                                  span: span,
+                                  _mitem: @meta_item,
+                                  in_items: ~[@item])
+                               -> ~[@item] {
+    expand_deriving(cx,
+                    span,
+                    in_items,
+                    expand_deriving_iter_bytes_struct_def,
+                    expand_deriving_iter_bytes_enum_def)
+}
+
+fn create_derived_iter_bytes_impl(cx: @ext_ctxt,
+                                  span: span,
+                                  type_ident: ident,
+                                  generics: &Generics,
+                                  method: @method)
+                               -> @item {
+    let methods = [ method ];
+    let trait_path = [
+        cx.ident_of(~"core"),
+        cx.ident_of(~"to_bytes"),
+        cx.ident_of(~"IterBytes")
+    ];
+    create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
+}
+
+// Creates a method from the given set of statements conforming to the
+// signature of the `iter_bytes` method.
+fn create_iter_bytes_method(cx: @ext_ctxt,
+                            span: span,
+                            +statements: ~[@stmt])
+                         -> @method {
+    // Create the `lsb0` parameter.
+    let bool_ident = cx.ident_of(~"bool");
+    let lsb0_arg_type = build::mk_simple_ty_path(cx, span, bool_ident);
+    let lsb0_ident = cx.ident_of(~"__lsb0");
+    let lsb0_arg = build::mk_arg(cx, span, lsb0_ident, lsb0_arg_type);
+
+    // Create the `f` parameter.
+    let core_ident = cx.ident_of(~"core");
+    let to_bytes_ident = cx.ident_of(~"to_bytes");
+    let cb_ident = cx.ident_of(~"Cb");
+    let core_to_bytes_cb_ident = ~[ core_ident, to_bytes_ident, cb_ident ];
+    let f_arg_type = build::mk_ty_path(cx, span, core_to_bytes_cb_ident);
+    let f_ident = cx.ident_of(~"__f");
+    let f_arg = build::mk_arg(cx, span, f_ident, f_arg_type);
+
+    // Create the type of the return value.
+    let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
+
+    // Create the function declaration.
+    let inputs = ~[ lsb0_arg, f_arg ];
+    let fn_decl = build::mk_fn_decl(inputs, output_type);
+
+    // Create the body block.
+    let body_block = build::mk_block_(cx, span, statements);
+
+    // Create the method.
+    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
+    let method_ident = cx.ident_of(~"iter_bytes");
+    @ast::method {
+        ident: method_ident,
+        attrs: ~[],
+        generics: ast_util::empty_generics(),
+        self_ty: self_ty,
+        purity: impure_fn,
+        decl: fn_decl,
+        body: body_block,
+        id: cx.next_id(),
+        span: span,
+        self_id: cx.next_id(),
+        vis: public
+    }
+}
+
+fn call_substructure_iter_bytes_method(cx: @ext_ctxt,
+                                       span: span,
+                                       self_field: @expr)
+                                    -> @stmt {
+    // Gather up the parameters we want to chain along.
+    let lsb0_ident = cx.ident_of(~"__lsb0");
+    let f_ident = cx.ident_of(~"__f");
+    let lsb0_expr = build::mk_path(cx, span, ~[ lsb0_ident ]);
+    let f_expr = build::mk_path(cx, span, ~[ f_ident ]);
+
+    // Call the substructure method.
+    let iter_bytes_ident = cx.ident_of(~"iter_bytes");
+    let self_method = build::mk_access_(cx,
+                                        span,
+                                        self_field,
+                                        iter_bytes_ident);
+    let self_call = build::mk_call_(cx,
+                                    span,
+                                    self_method,
+                                    ~[ lsb0_expr, f_expr ]);
+
+    // Create a statement out of this expression.
+    build::mk_stmt(cx, span, self_call)
+}
+
+fn expand_deriving_iter_bytes_struct_def(cx: @ext_ctxt,
+                                         span: span,
+                                         struct_def: &struct_def,
+                                         type_ident: ident,
+                                         generics: &Generics)
+                                      -> @item {
+    // Create the method.
+    let method = expand_deriving_iter_bytes_struct_method(cx,
+                                                          span,
+                                                          struct_def);
+
+    // Create the implementation.
+    return create_derived_iter_bytes_impl(cx,
+                                          span,
+                                          type_ident,
+                                          generics,
+                                          method);
+}
+
+fn expand_deriving_iter_bytes_enum_def(cx: @ext_ctxt,
+                                       span: span,
+                                       enum_definition: &enum_def,
+                                       type_ident: ident,
+                                       generics: &Generics)
+                                    -> @item {
+    // Create the method.
+    let method = expand_deriving_iter_bytes_enum_method(cx,
+                                                        span,
+                                                        enum_definition);
+
+    // Create the implementation.
+    return create_derived_iter_bytes_impl(cx,
+                                          span,
+                                          type_ident,
+                                          generics,
+                                          method);
+}
+
+fn expand_deriving_iter_bytes_struct_method(cx: @ext_ctxt,
+                                            span: span,
+                                            struct_def: &struct_def)
+                                         -> @method {
+    let self_ident = cx.ident_of(~"self");
+
+    // Create the body of the method.
+    let mut statements = ~[];
+    for struct_def.fields.each |struct_field| {
+        match struct_field.node.kind {
+            named_field(ident, _, _) => {
+                // Create the accessor for this field.
+                let self_field = build::mk_access(cx,
+                                                  span,
+                                                  ~[ self_ident ],
+                                                  ident);
+
+                // Call the substructure method.
+                let stmt = call_substructure_iter_bytes_method(cx,
+                                                               span,
+                                                               self_field);
+                statements.push(stmt);
+            }
+            unnamed_field => {
+                cx.span_unimpl(span,
+                               ~"unnamed fields with `deriving_iter_bytes`");
+            }
+        }
+    }
+
+    // Create the method itself.
+    return create_iter_bytes_method(cx, span, statements);
+}
+
+fn expand_deriving_iter_bytes_enum_method(cx: @ext_ctxt,
+                                          span: span,
+                                          enum_definition: &enum_def)
+                                       -> @method {
+    // Create the arms of the match in the method body.
+    let arms = do enum_definition.variants.mapi |i, variant| {
+        // Create the matching pattern.
+        let pat = create_enum_variant_pattern(cx, span, variant, ~"__self");
+
+        // Determine the discriminant. We will feed this value to the byte
+        // iteration function.
+        let discriminant;
+        match variant.node.disr_expr {
+            Some(copy disr_expr) => discriminant = disr_expr,
+            None => discriminant = build::mk_uint(cx, span, i),
+        }
+
+        // Feed the discriminant to the byte iteration function.
+        let mut stmts = ~[];
+        let discrim_stmt = call_substructure_iter_bytes_method(cx,
+                                                               span,
+                                                               discriminant);
+        stmts.push(discrim_stmt);
+
+        // Feed each argument in this variant to the byte iteration function
+        // as well.
+        for uint::range(0, variant_arg_count(cx, span, variant)) |j| {
+            // Create the expression for this field.
+            let field_ident = cx.ident_of(~"__self" + j.to_str());
+            let field = build::mk_path(cx, span, ~[ field_ident ]);
+
+            // Call the substructure method.
+            let stmt = call_substructure_iter_bytes_method(cx, span, field);
+            stmts.push(stmt);
+        }
+
+        // Create the pattern body.
+        let match_body_block = build::mk_block_(cx, span, stmts);
+
+        // Create the arm.
+        ast::arm {
+            pats: ~[ pat ],
+            guard: None,
+            body: match_body_block,
+        }
+    };
+
+    // Create the method body.
+    let self_match_expr = expand_enum_or_struct_match(cx, span, arms);
+    let self_match_stmt = build::mk_stmt(cx, span, self_match_expr);
+
+    // Create the method.
+    create_iter_bytes_method(cx, span, ~[ self_match_stmt ])
+}
index a6165e50c854585eda567ee3c7699650fe26dd53..63bb4389999696101b98c551a7c3051aa247edb4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 use ext::build;
 use codemap::{span, spanned};
 use parse::token::special_idents::clownshoes_extensions;
-use ast_util;
 use opt_vec;
 
 use core::uint;
 
-enum Junction {
-    Conjunction,
-    Disjunction,
-}
-
-pub impl Junction {
-    fn to_binop(self) -> binop {
-        match self {
-            Conjunction => and,
-            Disjunction => or,
-        }
-    }
-}
+pub mod clone;
+pub mod eq;
+pub mod iter_bytes;
 
 type ExpandDerivingStructDefFn = &'self fn(@ext_ctxt,
                                           span,
@@ -79,11 +68,11 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
                     meta_list(tname, _) |
                     meta_word(tname) => {
                         match *tname {
-                            ~"Clone" => expand_deriving_clone(cx,
+                            ~"Clone" => clone::expand_deriving_clone(cx,
                                 titem.span, titem, in_items),
-                            ~"Eq" => expand_deriving_eq(cx, titem.span,
+                            ~"Eq" => eq::expand_deriving_eq(cx, titem.span,
                                 titem, in_items),
-                            ~"IterBytes" => expand_deriving_iter_bytes(cx,
+                            ~"IterBytes" => iter_bytes::expand_deriving_iter_bytes(cx,
                                 titem.span, titem, in_items),
                             tname => {
                                 cx.span_err(titem.span, fmt!("unknown \
@@ -98,43 +87,7 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
     }
 }
 
-pub fn expand_deriving_eq(cx: @ext_ctxt,
-                          span: span,
-                          _mitem: @meta_item,
-                          in_items: ~[@item])
-                       -> ~[@item] {
-    expand_deriving(cx,
-                    span,
-                    in_items,
-                    expand_deriving_eq_struct_def,
-                    expand_deriving_eq_enum_def)
-}
-
-pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
-                                  span: span,
-                                  _mitem: @meta_item,
-                                  in_items: ~[@item])
-                               -> ~[@item] {
-    expand_deriving(cx,
-                    span,
-                    in_items,
-                    expand_deriving_iter_bytes_struct_def,
-                    expand_deriving_iter_bytes_enum_def)
-}
-
-pub fn expand_deriving_clone(cx: @ext_ctxt,
-                             span: span,
-                             _: @meta_item,
-                             in_items: ~[@item])
-                          -> ~[@item] {
-    expand_deriving(cx,
-                    span,
-                    in_items,
-                    expand_deriving_clone_struct_def,
-                    expand_deriving_clone_enum_def)
-}
-
-fn expand_deriving(cx: @ext_ctxt,
+pub fn expand_deriving(cx: @ext_ctxt,
                    span: span,
                    in_items: ~[@item],
                    expand_deriving_struct_def: ExpandDerivingStructDefFn,
@@ -175,68 +128,7 @@ fn create_impl_item(cx: @ext_ctxt, span: span, +item: item_) -> @item {
     }
 }
 
-/// Creates a method from the given expression, the signature of which
-/// conforms to the `eq` or `ne` method.
-fn create_eq_method(cx: @ext_ctxt,
-                    span: span,
-                    method_ident: ident,
-                    type_ident: ident,
-                    generics: &Generics,
-                    body: @expr)
-                 -> @method {
-    // Create the type of the `other` parameter.
-    let arg_path_type = create_self_type_with_params(cx,
-                                                     span,
-                                                     type_ident,
-                                                     generics);
-    let arg_type = ty_rptr(
-        None,
-        ast::mt { ty: arg_path_type, mutbl: m_imm }
-    );
-    let arg_type = @ast::Ty {
-        id: cx.next_id(),
-        node: arg_type,
-        span: span,
-    };
-
-    // Create the `other` parameter.
-    let other_ident = cx.ident_of(~"__other");
-    let arg = build::mk_arg(cx, span, other_ident, arg_type);
-
-    // Create the type of the return value.
-    let bool_ident = cx.ident_of(~"bool");
-    let output_type = build::mk_raw_path(span, ~[ bool_ident ]);
-    let output_type = ty_path(output_type, cx.next_id());
-    let output_type = @ast::Ty {
-        id: cx.next_id(),
-        node: output_type,
-        span: span,
-    };
-
-    // Create the function declaration.
-    let fn_decl = build::mk_fn_decl(~[ arg ], output_type);
-
-    // Create the body block.
-    let body_block = build::mk_simple_block(cx, span, body);
-
-    // Create the method.
-    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
-    @ast::method {
-        ident: method_ident,
-        attrs: ~[],
-        generics: ast_util::empty_generics(),
-        self_ty: self_ty,
-        purity: impure_fn,
-        decl: fn_decl,
-        body: body_block,
-        id: cx.next_id(),
-        span: span,
-        self_id: cx.next_id(),
-        vis: public
-    }
-}
-
-fn create_self_type_with_params(cx: @ext_ctxt,
+pub fn create_self_type_with_params(cx: @ext_ctxt,
                                 span: span,
                                 type_ident: ident,
                                 generics: &Generics)
@@ -258,7 +150,7 @@ fn create_self_type_with_params(cx: @ext_ctxt,
     @ast::Ty { id: cx.next_id(), node: self_type, span: span }
 }
 
-fn create_derived_impl(cx: @ext_ctxt,
+pub fn create_derived_impl(cx: @ext_ctxt,
                        span: span,
                        type_ident: ident,
                        generics: &Generics,
@@ -320,154 +212,7 @@ fn create_derived_impl(cx: @ext_ctxt,
     return create_impl_item(cx, span, impl_item);
 }
 
-fn create_derived_eq_impl(cx: @ext_ctxt,
-                          span: span,
-                          type_ident: ident,
-                          generics: &Generics,
-                          eq_method: @method,
-                          ne_method: @method)
-                       -> @item {
-    let methods = [ eq_method, ne_method ];
-    let trait_path = [
-        cx.ident_of(~"core"),
-        cx.ident_of(~"cmp"),
-        cx.ident_of(~"Eq")
-    ];
-    create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
-}
-
-fn create_derived_iter_bytes_impl(cx: @ext_ctxt,
-                                  span: span,
-                                  type_ident: ident,
-                                  generics: &Generics,
-                                  method: @method)
-                               -> @item {
-    let methods = [ method ];
-    let trait_path = [
-        cx.ident_of(~"core"),
-        cx.ident_of(~"to_bytes"),
-        cx.ident_of(~"IterBytes")
-    ];
-    create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
-}
-
-fn create_derived_clone_impl(cx: @ext_ctxt,
-                             span: span,
-                             type_ident: ident,
-                             generics: &Generics,
-                             method: @method)
-                          -> @item {
-    let methods = [ method ];
-    let trait_path = [
-        cx.ident_of(~"core"),
-        cx.ident_of(~"clone"),
-        cx.ident_of(~"Clone"),
-    ];
-    create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
-}
-
-// Creates a method from the given set of statements conforming to the
-// signature of the `iter_bytes` method.
-fn create_iter_bytes_method(cx: @ext_ctxt,
-                            span: span,
-                            +statements: ~[@stmt])
-                         -> @method {
-    // Create the `lsb0` parameter.
-    let bool_ident = cx.ident_of(~"bool");
-    let lsb0_arg_type = build::mk_simple_ty_path(cx, span, bool_ident);
-    let lsb0_ident = cx.ident_of(~"__lsb0");
-    let lsb0_arg = build::mk_arg(cx, span, lsb0_ident, lsb0_arg_type);
-
-    // Create the `f` parameter.
-    let core_ident = cx.ident_of(~"core");
-    let to_bytes_ident = cx.ident_of(~"to_bytes");
-    let cb_ident = cx.ident_of(~"Cb");
-    let core_to_bytes_cb_ident = ~[ core_ident, to_bytes_ident, cb_ident ];
-    let f_arg_type = build::mk_ty_path(cx, span, core_to_bytes_cb_ident);
-    let f_ident = cx.ident_of(~"__f");
-    let f_arg = build::mk_arg(cx, span, f_ident, f_arg_type);
-
-    // Create the type of the return value.
-    let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
-
-    // Create the function declaration.
-    let inputs = ~[ lsb0_arg, f_arg ];
-    let fn_decl = build::mk_fn_decl(inputs, output_type);
-
-    // Create the body block.
-    let body_block = build::mk_block_(cx, span, statements);
-
-    // Create the method.
-    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
-    let method_ident = cx.ident_of(~"iter_bytes");
-    @ast::method {
-        ident: method_ident,
-        attrs: ~[],
-        generics: ast_util::empty_generics(),
-        self_ty: self_ty,
-        purity: impure_fn,
-        decl: fn_decl,
-        body: body_block,
-        id: cx.next_id(),
-        span: span,
-        self_id: cx.next_id(),
-        vis: public
-    }
-}
-
-// Creates a method from the given expression conforming to the signature of
-// the `clone` method.
-fn create_clone_method(cx: @ext_ctxt,
-                       span: span,
-                       +type_ident: ast::ident,
-                       generics: &Generics,
-                       expr: @ast::expr)
-                    -> @method {
-    // Create the type parameters of the return value.
-    let mut output_ty_params = ~[];
-    for generics.ty_params.each |ty_param| {
-        let path = build::mk_ty_path(cx, span, ~[ ty_param.ident ]);
-        output_ty_params.push(path);
-    }
-
-    // Create the type of the return value.
-    let output_type_path = build::mk_raw_path_(span,
-                                               ~[ type_ident ],
-                                               output_ty_params);
-    let output_type = ast::ty_path(output_type_path, cx.next_id());
-    let output_type = @ast::Ty {
-        id: cx.next_id(),
-        node: output_type,
-        span: span
-    };
-
-    // Create the function declaration.
-    let fn_decl = build::mk_fn_decl(~[], output_type);
-
-    // Create the body block.
-    let body_block = build::mk_simple_block(cx, span, expr);
-
-    // Create the self type and method identifier.
-    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
-    let method_ident = cx.ident_of(~"clone");
-
-    // Create the method.
-    @ast::method {
-        ident: method_ident,
-        attrs: ~[],
-        generics: ast_util::empty_generics(),
-        self_ty: self_ty,
-        purity: impure_fn,
-        decl: fn_decl,
-        body: body_block,
-        id: cx.next_id(),
-        span: span,
-        self_id: cx.next_id(),
-        vis: public,
-    }
-}
-
-fn create_subpatterns(cx: @ext_ctxt,
+pub fn create_subpatterns(cx: @ext_ctxt,
                       span: span,
                       prefix: ~str,
                       n: uint)
@@ -487,7 +232,7 @@ fn create_subpatterns(cx: @ext_ctxt,
     return subpats;
 }
 
-fn is_struct_tuple(struct_def: &struct_def) -> bool {
+pub fn is_struct_tuple(struct_def: &struct_def) -> bool {
     struct_def.fields.len() > 0 && struct_def.fields.all(|f| {
         match f.node.kind {
             named_field(*) => false,
@@ -496,7 +241,7 @@ fn is_struct_tuple(struct_def: &struct_def) -> bool {
     })
 }
 
-fn create_enum_variant_pattern(cx: @ext_ctxt,
+pub fn create_enum_variant_pattern(cx: @ext_ctxt,
                                span: span,
                                variant: &variant,
                                prefix: ~str)
@@ -542,87 +287,7 @@ fn create_enum_variant_pattern(cx: @ext_ctxt,
     }
 }
 
-fn call_substructure_eq_method(cx: @ext_ctxt,
-                               span: span,
-                               self_field: @expr,
-                               other_field_ref: @expr,
-                               method_ident: ident,
-                               junction: Junction,
-                               chain_expr: &mut Option<@expr>) {
-    // Call the substructure method.
-    let self_method = build::mk_access_(cx, span, self_field, method_ident);
-    let self_call = build::mk_call_(cx,
-                                    span,
-                                    self_method,
-                                    ~[ other_field_ref ]);
-
-    // Connect to the outer expression if necessary.
-    *chain_expr = match *chain_expr {
-        None => Some(self_call),
-        Some(copy old_outer_expr) => {
-            let binop = junction.to_binop();
-            let chain_expr = build::mk_binary(cx,
-                                              span,
-                                              binop,
-                                              old_outer_expr,
-                                              self_call);
-            Some(chain_expr)
-        }
-    };
-}
-
-fn finish_eq_chain_expr(cx: @ext_ctxt,
-                        span: span,
-                        chain_expr: Option<@expr>,
-                        junction: Junction)
-                     -> @expr {
-    match chain_expr {
-        None => {
-            match junction {
-                Conjunction => build::mk_bool(cx, span, true),
-                Disjunction => build::mk_bool(cx, span, false),
-            }
-        }
-        Some(ref outer_expr) => *outer_expr,
-    }
-}
-
-fn call_substructure_iter_bytes_method(cx: @ext_ctxt,
-                                       span: span,
-                                       self_field: @expr)
-                                    -> @stmt {
-    // Gather up the parameters we want to chain along.
-    let lsb0_ident = cx.ident_of(~"__lsb0");
-    let f_ident = cx.ident_of(~"__f");
-    let lsb0_expr = build::mk_path(cx, span, ~[ lsb0_ident ]);
-    let f_expr = build::mk_path(cx, span, ~[ f_ident ]);
-
-    // Call the substructure method.
-    let iter_bytes_ident = cx.ident_of(~"iter_bytes");
-    let self_method = build::mk_access_(cx,
-                                        span,
-                                        self_field,
-                                        iter_bytes_ident);
-    let self_call = build::mk_call_(cx,
-                                    span,
-                                    self_method,
-                                    ~[ lsb0_expr, f_expr ]);
-
-    // Create a statement out of this expression.
-    build::mk_stmt(cx, span, self_call)
-}
-
-fn call_substructure_clone_method(cx: @ext_ctxt,
-                                  span: span,
-                                  self_field: @expr)
-                               -> @expr {
-    // Call the substructure method.
-    let clone_ident = cx.ident_of(~"clone");
-    let self_method = build::mk_access_(cx, span, self_field, clone_ident);
-    build::mk_call_(cx, span, self_method, ~[])
-}
-
-fn variant_arg_count(cx: @ext_ctxt, span: span, variant: &variant) -> uint {
+pub fn variant_arg_count(cx: @ext_ctxt, span: span, variant: &variant) -> uint {
     match variant.node.kind {
         tuple_variant_kind(ref args) => args.len(),
         struct_variant_kind(ref struct_def) => struct_def.fields.len(),
@@ -632,530 +297,7 @@ fn variant_arg_count(cx: @ext_ctxt, span: span, variant: &variant) -> uint {
     }
 }
 
-fn expand_deriving_eq_struct_def(cx: @ext_ctxt,
-                                 span: span,
-                                 struct_def: &struct_def,
-                                 type_ident: ident,
-                                 generics: &Generics)
-                              -> @item {
-    // Create the methods.
-    let eq_ident = cx.ident_of(~"eq");
-    let ne_ident = cx.ident_of(~"ne");
-
-    let derive_struct_fn = if is_struct_tuple(struct_def) {
-        expand_deriving_eq_struct_tuple_method
-    } else {
-        expand_deriving_eq_struct_method
-    };
-
-    let eq_method = derive_struct_fn(cx,
-                                     span,
-                                     struct_def,
-                                     eq_ident,
-                                     type_ident,
-                                     generics,
-                                     Conjunction);
-    let ne_method = derive_struct_fn(cx,
-                                     span,
-                                     struct_def,
-                                     ne_ident,
-                                     type_ident,
-                                     generics,
-                                     Disjunction);
-
-    // Create the implementation.
-    return create_derived_eq_impl(cx,
-                                  span,
-                                  type_ident,
-                                  generics,
-                                  eq_method,
-                                  ne_method);
-}
-
-fn expand_deriving_eq_enum_def(cx: @ext_ctxt,
-                               span: span,
-                               enum_definition: &enum_def,
-                               type_ident: ident,
-                               generics: &Generics)
-                            -> @item {
-    // Create the methods.
-    let eq_ident = cx.ident_of(~"eq");
-    let ne_ident = cx.ident_of(~"ne");
-    let eq_method = expand_deriving_eq_enum_method(cx,
-                                                   span,
-                                                   enum_definition,
-                                                   eq_ident,
-                                                   type_ident,
-                                                   generics,
-                                                   Conjunction);
-    let ne_method = expand_deriving_eq_enum_method(cx,
-                                                   span,
-                                                   enum_definition,
-                                                   ne_ident,
-                                                   type_ident,
-                                                   generics,
-                                                   Disjunction);
-
-    // Create the implementation.
-    return create_derived_eq_impl(cx,
-                                  span,
-                                  type_ident,
-                                  generics,
-                                  eq_method,
-                                  ne_method);
-}
-
-fn expand_deriving_iter_bytes_struct_def(cx: @ext_ctxt,
-                                         span: span,
-                                         struct_def: &struct_def,
-                                         type_ident: ident,
-                                         generics: &Generics)
-                                      -> @item {
-    // Create the method.
-    let method = expand_deriving_iter_bytes_struct_method(cx,
-                                                          span,
-                                                          struct_def);
-
-    // Create the implementation.
-    return create_derived_iter_bytes_impl(cx,
-                                          span,
-                                          type_ident,
-                                          generics,
-                                          method);
-}
-
-fn expand_deriving_iter_bytes_enum_def(cx: @ext_ctxt,
-                                       span: span,
-                                       enum_definition: &enum_def,
-                                       type_ident: ident,
-                                       generics: &Generics)
-                                    -> @item {
-    // Create the method.
-    let method = expand_deriving_iter_bytes_enum_method(cx,
-                                                        span,
-                                                        enum_definition);
-
-    // Create the implementation.
-    return create_derived_iter_bytes_impl(cx,
-                                          span,
-                                          type_ident,
-                                          generics,
-                                          method);
-}
-
-fn expand_deriving_clone_struct_def(cx: @ext_ctxt,
-                                    span: span,
-                                    struct_def: &struct_def,
-                                    type_ident: ident,
-                                    generics: &Generics)
-                                 -> @item {
-    // Create the method.
-    let method = if !is_struct_tuple(struct_def) {
-        expand_deriving_clone_struct_method(cx,
-                                            span,
-                                            struct_def,
-                                            type_ident,
-                                            generics)
-    } else {
-        expand_deriving_clone_tuple_struct_method(cx,
-                                                  span,
-                                                  struct_def,
-                                                  type_ident,
-                                                  generics)
-    };
-
-    // Create the implementation.
-    create_derived_clone_impl(cx, span, type_ident, generics, method)
-}
-
-fn expand_deriving_clone_enum_def(cx: @ext_ctxt,
-                                  span: span,
-                                  enum_definition: &enum_def,
-                                  type_ident: ident,
-                                  generics: &Generics)
-                               -> @item {
-    // Create the method.
-    let method = expand_deriving_clone_enum_method(cx,
-                                                   span,
-                                                   enum_definition,
-                                                   type_ident,
-                                                   generics);
-
-    // Create the implementation.
-    create_derived_clone_impl(cx, span, type_ident, generics, method)
-}
-
-fn expand_deriving_eq_struct_method(cx: @ext_ctxt,
-                                    span: span,
-                                    struct_def: &struct_def,
-                                    method_ident: ident,
-                                    type_ident: ident,
-                                    generics: &Generics,
-                                    junction: Junction)
-                                 -> @method {
-    let self_ident = cx.ident_of(~"self");
-    let other_ident = cx.ident_of(~"__other");
-
-    // Create the body of the method.
-    let mut outer_expr = None;
-    for struct_def.fields.each |struct_field| {
-        match struct_field.node.kind {
-            named_field(ident, _, _) => {
-                // Create the accessor for the other field.
-                let other_field = build::mk_access(cx,
-                                                   span,
-                                                   ~[ other_ident ],
-                                                   ident);
-                let other_field_ref = build::mk_addr_of(cx,
-                                                        span,
-                                                        other_field);
-
-                // Create the accessor for this field.
-                let self_field = build::mk_access(cx,
-                                                  span,
-                                                  ~[ self_ident ],
-                                                  ident);
-
-                // Call the substructure method.
-                call_substructure_eq_method(cx,
-                                            span,
-                                            self_field,
-                                            other_field_ref,
-                                            method_ident,
-                                            junction,
-                                            &mut outer_expr);
-            }
-            unnamed_field => {
-                cx.span_unimpl(span, ~"unnamed fields with `deriving_eq`");
-            }
-        }
-    }
-
-    // Create the method itself.
-    let body = finish_eq_chain_expr(cx, span, outer_expr, junction);
-    return create_eq_method(cx,
-                            span,
-                            method_ident,
-                            type_ident,
-                            generics,
-                            body);
-}
-
-fn expand_deriving_iter_bytes_struct_method(cx: @ext_ctxt,
-                                            span: span,
-                                            struct_def: &struct_def)
-                                         -> @method {
-    let self_ident = cx.ident_of(~"self");
-
-    // Create the body of the method.
-    let mut statements = ~[];
-    for struct_def.fields.each |struct_field| {
-        match struct_field.node.kind {
-            named_field(ident, _, _) => {
-                // Create the accessor for this field.
-                let self_field = build::mk_access(cx,
-                                                  span,
-                                                  ~[ self_ident ],
-                                                  ident);
-
-                // Call the substructure method.
-                let stmt = call_substructure_iter_bytes_method(cx,
-                                                               span,
-                                                               self_field);
-                statements.push(stmt);
-            }
-            unnamed_field => {
-                cx.span_unimpl(span,
-                               ~"unnamed fields with `deriving_iter_bytes`");
-            }
-        }
-    }
-
-    // Create the method itself.
-    return create_iter_bytes_method(cx, span, statements);
-}
-
-fn expand_deriving_clone_struct_method(cx: @ext_ctxt,
-                                       span: span,
-                                       struct_def: &struct_def,
-                                       type_ident: ident,
-                                       generics: &Generics)
-                                    -> @method {
-    let self_ident = cx.ident_of(~"self");
-
-    // Create the new fields.
-    let mut fields = ~[];
-    for struct_def.fields.each |struct_field| {
-        match struct_field.node.kind {
-            named_field(ident, _, _) => {
-                // Create the accessor for this field.
-                let self_field = build::mk_access(cx,
-                                                  span,
-                                                  ~[ self_ident ],
-                                                  ident);
-
-                // Call the substructure method.
-                let call = call_substructure_clone_method(cx,
-                                                          span,
-                                                          self_field);
-
-                let field = build::Field { ident: ident, ex: call };
-                fields.push(field);
-            }
-            unnamed_field => {
-                cx.span_bug(span,
-                            ~"unnamed fields in \
-                              expand_deriving_clone_struct_method");
-            }
-        }
-    }
-
-    // Create the struct literal.
-    let struct_literal = build::mk_struct_e(cx,
-                                            span,
-                                            ~[ type_ident ],
-                                            fields);
-    create_clone_method(cx, span, type_ident, generics, struct_literal)
-}
-
-fn expand_deriving_clone_tuple_struct_method(cx: @ext_ctxt,
-                                             span: span,
-                                             struct_def: &struct_def,
-                                             type_ident: ident,
-                                             generics: &Generics)
-                                          -> @method {
-    // Create the pattern for the match.
-    let matching_path = build::mk_raw_path(span, ~[ type_ident ]);
-    let field_count = struct_def.fields.len();
-    let subpats = create_subpatterns(cx, span, ~"__self", field_count);
-    let pat = build::mk_pat_enum(cx, span, matching_path, subpats);
-
-    // Create the new fields.
-    let mut subcalls = ~[];
-    for uint::range(0, struct_def.fields.len()) |i| {
-        // Create the expression for this field.
-        let field_ident = cx.ident_of(~"__self" + i.to_str());
-        let field = build::mk_path(cx, span, ~[ field_ident ]);
-
-        // Call the substructure method.
-        let subcall = call_substructure_clone_method(cx, span, field);
-        subcalls.push(subcall);
-    }
-
-    // Create the call to the struct constructor.
-    let call = build::mk_call(cx, span, ~[ type_ident ], subcalls);
-
-    // Create the pattern body.
-    let match_body_block = build::mk_simple_block(cx, span, call);
-
-    // Create the arm.
-    let arm = ast::arm {
-        pats: ~[ pat ],
-        guard: None,
-        body: match_body_block
-    };
-
-    // Create the method body.
-    let self_match_expr = expand_enum_or_struct_match(cx, span, ~[ arm ]);
-
-    // Create the method.
-    create_clone_method(cx, span, type_ident, generics, self_match_expr)
-}
-
-fn expand_deriving_eq_enum_method(cx: @ext_ctxt,
-                                  span: span,
-                                  enum_definition: &enum_def,
-                                  method_ident: ident,
-                                  type_ident: ident,
-                                  generics: &Generics,
-                                  junction: Junction)
-                               -> @method {
-    let self_ident = cx.ident_of(~"self");
-    let other_ident = cx.ident_of(~"__other");
-
-    let is_eq;
-    match junction {
-        Conjunction => is_eq = true,
-        Disjunction => is_eq = false,
-    }
-
-    // Create the arms of the self match in the method body.
-    let mut self_arms = ~[];
-    for enum_definition.variants.each |self_variant| {
-        let mut other_arms = ~[];
-
-        // Create the matching pattern.
-        let matching_pat = create_enum_variant_pattern(cx,
-                                                       span,
-                                                       self_variant,
-                                                       ~"__other");
-
-        // Create the matching pattern body.
-        let mut matching_body_expr = None;
-        for uint::range(0, variant_arg_count(cx, span, self_variant)) |i| {
-            // Create the expression for the other field.
-            let other_field_ident = cx.ident_of(~"__other" + i.to_str());
-            let other_field = build::mk_path(cx,
-                                             span,
-                                             ~[ other_field_ident ]);
-
-            // Create the expression for this field.
-            let self_field_ident = cx.ident_of(~"__self" + i.to_str());
-            let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
-
-            // Call the substructure method.
-            call_substructure_eq_method(cx,
-                                        span,
-                                        self_field,
-                                        other_field,
-                                        method_ident,
-                                        junction,
-                                        &mut matching_body_expr);
-        }
-
-        let matching_body_expr = finish_eq_chain_expr(cx,
-                                                      span,
-                                                      matching_body_expr,
-                                                      junction);
-        let matching_body_block = build::mk_simple_block(cx,
-                                                         span,
-                                                         matching_body_expr);
-
-        // Create the matching arm.
-        let matching_arm = ast::arm {
-            pats: ~[ matching_pat ],
-            guard: None,
-            body: matching_body_block
-        };
-        other_arms.push(matching_arm);
-
-        // Maybe generate a non-matching case. If there is only one
-        // variant then there will always be a match.
-        if enum_definition.variants.len() > 1 {
-            // Create the nonmatching pattern.
-            let nonmatching_pat = @ast::pat {
-                id: cx.next_id(),
-                node: pat_wild,
-                span: span
-            };
-
-            // Create the nonmatching pattern body.
-            let nonmatching_expr = build::mk_bool(cx, span, !is_eq);
-            let nonmatching_body_block =
-                build::mk_simple_block(cx,
-                                       span,
-                                       nonmatching_expr);
-
-            // Create the nonmatching arm.
-            let nonmatching_arm = ast::arm {
-                pats: ~[ nonmatching_pat ],
-                guard: None,
-                body: nonmatching_body_block,
-            };
-            other_arms.push(nonmatching_arm);
-        }
-
-        // Create the self pattern.
-        let self_pat = create_enum_variant_pattern(cx,
-                                                   span,
-                                                   self_variant,
-                                                   ~"__self");
-
-        // Create the self pattern body.
-        let other_expr = build::mk_path(cx, span, ~[ other_ident ]);
-        let other_expr = build::mk_unary(cx, span, deref, other_expr);
-        let other_match_expr = expr_match(other_expr, other_arms);
-        let other_match_expr = build::mk_expr(cx,
-                                              span,
-                                              other_match_expr);
-        let other_match_body_block = build::mk_simple_block(cx,
-                                                            span,
-                                                            other_match_expr);
-
-        // Create the self arm.
-        let self_arm = ast::arm {
-            pats: ~[ self_pat ],
-            guard: None,
-            body: other_match_body_block,
-        };
-        self_arms.push(self_arm);
-    }
-
-    // Create the method body.
-    let self_expr = build::mk_path(cx, span, ~[ self_ident ]);
-    let self_expr = build::mk_unary(cx, span, deref, self_expr);
-    let self_match_expr = expr_match(self_expr, self_arms);
-    let self_match_expr = build::mk_expr(cx, span, self_match_expr);
-
-    // Create the method.
-    return create_eq_method(cx,
-                            span,
-                            method_ident,
-                            type_ident,
-                            generics,
-                            self_match_expr);
-}
-
-fn expand_deriving_eq_struct_tuple_method(cx: @ext_ctxt,
-                                          span: span,
-                                          struct_def: &struct_def,
-                                          method_ident: ident,
-                                          type_ident: ident,
-                                          generics: &Generics,
-                                          junction: Junction)
-                                        -> @method {
-    let self_str = ~"self";
-    let other_str = ~"__other";
-    let type_path = build::mk_raw_path(span, ~[type_ident]);
-    let fields = copy struct_def.fields;
-
-    // Create comparison expression, comparing each of the fields
-    let mut match_body = None;
-    for fields.eachi |i, _| {
-        let other_field_ident = cx.ident_of(other_str + i.to_str());
-        let other_field = build::mk_path(cx, span, ~[ other_field_ident ]);
-
-        let self_field_ident = cx.ident_of(self_str + i.to_str());
-        let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
-
-        call_substructure_eq_method(cx, span, self_field, other_field,
-            method_ident, junction, &mut match_body);
-    }
-    let match_body = finish_eq_chain_expr(cx, span, match_body, junction);
-
-    // Create arm for the '__other' match, containing the comparison expr
-    let other_subpats = create_subpatterns(cx, span, other_str, fields.len());
-    let other_arm = ast::arm {
-        pats: ~[ build::mk_pat_enum(cx, span, type_path, other_subpats) ],
-        guard: None,
-        body: build::mk_simple_block(cx, span, match_body),
-    };
-
-    // Create the match on '__other'
-    let other_expr = build::mk_path(cx, span, ~[ cx.ident_of(other_str) ]);
-    let other_expr = build::mk_unary(cx, span, deref, other_expr);
-    let other_match_expr = expr_match(other_expr, ~[other_arm]);
-    let other_match_expr = build::mk_expr(cx, span, other_match_expr);
-
-    // Create arm for the 'self' match, which contains the '__other' match
-    let self_subpats = create_subpatterns(cx, span, self_str, fields.len());
-    let self_arm = ast::arm {
-        pats: ~[build::mk_pat_enum(cx, span, type_path, self_subpats)],
-        guard: None,
-        body: build::mk_simple_block(cx, span, other_match_expr),
-    };
-
-    // Create the match on 'self'
-    let self_expr = build::mk_path(cx, span, ~[ cx.ident_of(self_str) ]);
-    let self_expr = build::mk_unary(cx, span, deref, self_expr);
-    let self_match_expr = expr_match(self_expr, ~[self_arm]);
-    let self_match_expr = build::mk_expr(cx, span, self_match_expr);
-
-    create_eq_method(cx, span, method_ident,
-        type_ident, generics, self_match_expr)
-}
-
-fn expand_enum_or_struct_match(cx: @ext_ctxt,
+pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
                                span: span,
                                arms: ~[ ast::arm ])
                             -> @expr {
@@ -1165,103 +307,3 @@ fn expand_enum_or_struct_match(cx: @ext_ctxt,
     let self_match_expr = expr_match(self_expr, arms);
     build::mk_expr(cx, span, self_match_expr)
 }
-
-fn expand_deriving_iter_bytes_enum_method(cx: @ext_ctxt,
-                                          span: span,
-                                          enum_definition: &enum_def)
-                                       -> @method {
-    // Create the arms of the match in the method body.
-    let arms = do enum_definition.variants.mapi |i, variant| {
-        // Create the matching pattern.
-        let pat = create_enum_variant_pattern(cx, span, variant, ~"__self");
-
-        // Determine the discriminant. We will feed this value to the byte
-        // iteration function.
-        let discriminant;
-        match variant.node.disr_expr {
-            Some(copy disr_expr) => discriminant = disr_expr,
-            None => discriminant = build::mk_uint(cx, span, i),
-        }
-
-        // Feed the discriminant to the byte iteration function.
-        let mut stmts = ~[];
-        let discrim_stmt = call_substructure_iter_bytes_method(cx,
-                                                               span,
-                                                               discriminant);
-        stmts.push(discrim_stmt);
-
-        // Feed each argument in this variant to the byte iteration function
-        // as well.
-        for uint::range(0, variant_arg_count(cx, span, variant)) |j| {
-            // Create the expression for this field.
-            let field_ident = cx.ident_of(~"__self" + j.to_str());
-            let field = build::mk_path(cx, span, ~[ field_ident ]);
-
-            // Call the substructure method.
-            let stmt = call_substructure_iter_bytes_method(cx, span, field);
-            stmts.push(stmt);
-        }
-
-        // Create the pattern body.
-        let match_body_block = build::mk_block_(cx, span, stmts);
-
-        // Create the arm.
-        ast::arm {
-            pats: ~[ pat ],
-            guard: None,
-            body: match_body_block,
-        }
-    };
-
-    // Create the method body.
-    let self_match_expr = expand_enum_or_struct_match(cx, span, arms);
-    let self_match_stmt = build::mk_stmt(cx, span, self_match_expr);
-
-    // Create the method.
-    create_iter_bytes_method(cx, span, ~[ self_match_stmt ])
-}
-
-fn expand_deriving_clone_enum_method(cx: @ext_ctxt,
-                                     span: span,
-                                     enum_definition: &enum_def,
-                                     type_ident: ident,
-                                     generics: &Generics)
-                                  -> @method {
-    // Create the arms of the match in the method body.
-    let arms = do enum_definition.variants.map |variant| {
-        // Create the matching pattern.
-        let pat = create_enum_variant_pattern(cx, span, variant, ~"__self");
-
-        // Iterate over the variant arguments, creating the subcalls.
-        let mut subcalls = ~[];
-        for uint::range(0, variant_arg_count(cx, span, variant)) |j| {
-            // Create the expression for this field.
-            let field_ident = cx.ident_of(~"__self" + j.to_str());
-            let field = build::mk_path(cx, span, ~[ field_ident ]);
-
-            // Call the substructure method.
-            let subcall = call_substructure_clone_method(cx, span, field);
-            subcalls.push(subcall);
-        }
-
-        // Create the call to the enum variant (if necessary).
-        let call = if subcalls.len() > 0 {
-            build::mk_call(cx, span, ~[ variant.node.name ], subcalls)
-        } else {
-            build::mk_path(cx, span, ~[ variant.node.name ])
-        };
-
-        // Create the pattern body.
-        let match_body_block = build::mk_simple_block(cx, span, call);
-
-        // Create the arm.
-        ast::arm { pats: ~[ pat ], guard: None, body: match_body_block }
-    };
-
-    // Create the method body.
-    let self_match_expr = expand_enum_or_struct_match(cx, span, arms);
-
-    // Create the method.
-    create_clone_method(cx, span, type_ident, generics, self_match_expr)
-}
-