about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-05-16 08:55:57 +1000
committerHuon Wilson <dbau.pp+github@gmail.com>2013-05-16 08:55:57 +1000
commit5dc5efefd47527067ab5b7862d89a99da4824f49 (patch)
treecc012135abd498773efbdb299163035af2e7d989
parent6a9c3bd86e0271f26dc63bd12e0d54a35b704dff (diff)
downloadrust-5dc5efefd47527067ab5b7862d89a99da4824f49.tar.gz
rust-5dc5efefd47527067ab5b7862d89a99da4824f49.zip
syntax: deprecate #[auto_{en,de}code] in favour of #[deriving({En,De}codable)].
Replace all instances of #[auto_*code] with the appropriate #[deriving] attribute
and remove the majority of the actual code, leaving stubs to refer the user to
the new syntax.
-rw-r--r--src/librustc/middle/freevars.rs3
-rw-r--r--src/librustc/middle/moves.rs6
-rw-r--r--src/librustc/middle/ty.rs44
-rw-r--r--src/librustc/middle/typeck/mod.rs6
-rw-r--r--src/libstd/json.rs12
-rw-r--r--src/libstd/time.rs8
-rw-r--r--src/libstd/workcache.rs4
-rw-r--r--src/libsyntax/abi.rs4
-rw-r--r--src/libsyntax/ast.rs312
-rw-r--r--src/libsyntax/ast_util.rs3
-rw-r--r--src/libsyntax/codemap.rs4
-rw-r--r--src/libsyntax/ext/auto_encode.rs1486
-rw-r--r--src/libsyntax/ext/build.rs298
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs5
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs312
-rw-r--r--src/libsyntax/ext/deriving/mod.rs13
-rw-r--r--src/libsyntax/opt_vec.rs3
-rw-r--r--src/libsyntax/parse/token.rs12
-rw-r--r--src/test/compile-fail/deprecated-auto-code.rs15
19 files changed, 752 insertions, 1798 deletions
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
index 41e29132155..872ad83b739 100644
--- a/src/librustc/middle/freevars.rs
+++ b/src/librustc/middle/freevars.rs
@@ -20,8 +20,7 @@ use syntax::{ast, ast_util, visit};
 
 // A vector of defs representing the free variables referred to in a function.
 // (The def_upvar will already have been stripped).
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub struct freevar_entry {
     def: ast::def, //< The variable being accessed free.
     span: span     //< First span where it is accessed (there can be multiple)
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index 3a2fb654006..e81a9d6b78f 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -221,16 +221,14 @@ use syntax::visit::vt;
 use syntax::print::pprust;
 use syntax::codemap::span;
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub enum CaptureMode {
     CapCopy, // Copy the value into the closure.
     CapMove, // Move the value into the closure.
     CapRef,  // Reference directly from parent stack frame (used by `&fn()`).
 }
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub struct CaptureVar {
     def: def,         // Variable being accessed free
     span: span,       // Location of an access to this variable
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 4ee2c5b0100..e85c7d00c58 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -96,9 +96,7 @@ pub struct mt {
     mutbl: ast::mutability,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum vstore {
     vstore_fixed(uint),
     vstore_uniq,
@@ -106,9 +104,7 @@ pub enum vstore {
     vstore_slice(Region)
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq, IterBytes)]
+#[deriving(Eq, IterBytes, Encodable, Decodable)]
 pub enum TraitStore {
     BoxTraitStore,              // @Trait
     UniqTraitStore,             // ~Trait
@@ -117,9 +113,7 @@ pub enum TraitStore {
 
 // XXX: This should probably go away at some point. Maybe after destructors
 // do?
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum SelfMode {
     ByCopy,
     ByRef,
@@ -197,27 +191,22 @@ pub enum ast_ty_to_ty_cache_entry {
 
 pub type opt_region_variance = Option<region_variance>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Decodable, Encodable)]
 pub enum region_variance { rv_covariant, rv_invariant, rv_contravariant }
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Decodable, Encodable)]
 pub enum AutoAdjustment {
     AutoAddEnv(ty::Region, ast::Sigil),
     AutoDerefRef(AutoDerefRef)
 }
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Decodable, Encodable)]
 pub struct AutoDerefRef {
     autoderefs: uint,
     autoref: Option<AutoRef>
 }
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Decodable, Encodable)]
 pub enum AutoRef {
     /// Convert from T to &T
     AutoPtr(Region, ast::mutability),
@@ -453,9 +442,7 @@ pub struct param_ty {
 }
 
 /// Representation of regions:
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq, IterBytes)]
+#[deriving(Eq, IterBytes, Encodable, Decodable)]
 pub enum Region {
     /// Bound regions are found (primarily) in function types.  They indicate
     /// region parameters that have yet to be replaced with actual regions
@@ -501,17 +488,13 @@ pub impl Region {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq, IterBytes)]
+#[deriving(Eq, IterBytes, Encodable, Decodable)]
 pub struct FreeRegion {
     scope_id: node_id,
     bound_region: bound_region
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq, IterBytes)]
+#[deriving(Eq, IterBytes, Encodable, Decodable)]
 pub enum bound_region {
     /// The self region for structs, impls (&T in a type defn or &'self T)
     br_self,
@@ -742,9 +725,7 @@ pub struct IntVid(uint);
 #[deriving(Eq)]
 pub struct FloatVid(uint);
 
-#[deriving(Eq)]
-#[auto_encode]
-#[auto_decode]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct RegionVid {
     id: uint
 }
@@ -777,8 +758,7 @@ impl to_bytes::IterBytes for InferTy {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub enum InferRegion {
     ReVar(RegionVid),
     ReSkolemized(uint, bound_region)
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 0dec0fc937b..dd313c54efb 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -73,8 +73,7 @@ pub mod infer;
 pub mod collect;
 pub mod coherence;
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub enum method_origin {
     // supertrait method invoked on "self" inside a default method
     // first field is supertrait ID;
@@ -98,8 +97,7 @@ pub enum method_origin {
 
 // details for a method invoked with a receiver whose type is a type parameter
 // with a bounded trait.
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub struct method_param {
     // the trait containing the method to be invoked
     trait_id: ast::def_id,
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 7702b46ddcb..270cf675c87 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -1331,26 +1331,20 @@ mod tests {
 
     use std::serialize::Decodable;
 
-    #[auto_encode]
-    #[auto_decode]
-    #[deriving(Eq)]
+    #[deriving(Eq, Encodable, Decodable)]
     enum Animal {
         Dog,
         Frog(~str, int)
     }
 
-    #[auto_encode]
-    #[auto_decode]
-    #[deriving(Eq)]
+    #[deriving(Eq, Encodable, Decodable)]
     struct Inner {
         a: (),
         b: uint,
         c: ~[~str],
     }
 
-    #[auto_encode]
-    #[auto_decode]
-    #[deriving(Eq)]
+    #[deriving(Eq, Encodable, Decodable)]
     struct Outer {
         inner: ~[Inner],
     }
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index e731f679221..202b96f9797 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -29,9 +29,7 @@ pub mod rustrt {
 }
 
 /// A record specifying a time value in seconds and nanoseconds.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct Timespec { sec: i64, nsec: i32 }
 
 /*
@@ -100,9 +98,7 @@ pub fn tzset() {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct Tm {
     tm_sec: i32, // seconds after the minute ~[0-60]
     tm_min: i32, // minutes after the hour ~[0-59]
diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs
index a9e4ec50c7c..f173df60df8 100644
--- a/src/libstd/workcache.rs
+++ b/src/libstd/workcache.rs
@@ -92,9 +92,7 @@ use core::util::replace;
 *
 */
 
-#[deriving(Eq)]
-#[auto_encode]
-#[auto_decode]
+#[deriving(Eq, Encodable, Decodable)]
 struct WorkKey {
     kind: ~str,
     name: ~str
diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs
index ee62bb270b8..1b166dcf366 100644
--- a/src/libsyntax/abi.rs
+++ b/src/libsyntax/abi.rs
@@ -58,9 +58,7 @@ enum AbiArchitecture {
     Archs(u32)  // Multiple architectures (bitset)
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct AbiSet {
     priv bits: u32   // each bit represents one of the abis below
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f77d00ce9b1..4a3ae7d94ad 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -47,9 +47,7 @@ pub type SyntaxContext = uint;
 pub type SCTable = ~[SyntaxContext_];
 pub static empty_ctxt : uint = 0;
 
-#[deriving(Eq)]
-#[auto_encode]
-#[auto_decode]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum SyntaxContext_ {
     EmptyCtxt,
     Mark (Mrk,SyntaxContext),
@@ -115,9 +113,7 @@ impl to_bytes::IterBytes for ident {
 // Functions may or may not have names.
 pub type fn_ident = Option<ident>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct Lifetime {
     id: node_id,
     span: span,
@@ -142,9 +138,7 @@ impl to_bytes::IterBytes for Lifetime {
 // for instance: core::cmp::Eq  .  It's represented
 // as a sequence of identifiers, along with a bunch
 // of supporting information.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct Path {
     span: span,
     global: bool,
@@ -157,9 +151,7 @@ pub type crate_num = int;
 
 pub type node_id = int;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct def_id {
     crate: crate_num,
     node: node_id,
@@ -168,9 +160,7 @@ pub struct def_id {
 pub static local_crate: crate_num = 0;
 pub static crate_node_id: node_id = 0;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 // The AST represents all type param bounds as types.
 // typeck::collect::compute_bounds matches these against
 // the "special" built-in traits (see middle::lang_items) and
@@ -180,18 +170,14 @@ pub enum TyParamBound {
     RegionTyParamBound
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct TyParam {
     ident: ident,
     id: node_id,
     bounds: @OptVec<TyParamBound>
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct Generics {
     lifetimes: OptVec<Lifetime>,
     ty_params: OptVec<TyParam>
@@ -209,9 +195,7 @@ pub impl Generics {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum def {
     def_fn(def_id, purity),
     def_static_method(/* method */ def_id,
@@ -248,9 +232,7 @@ pub type crate_cfg = ~[@meta_item];
 
 pub type crate = spanned<crate_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct crate_ {
     module: _mod,
     attrs: ~[attribute],
@@ -259,9 +241,7 @@ pub struct crate_ {
 
 pub type meta_item = spanned<meta_item_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum meta_item_ {
     meta_word(@~str),
     meta_list(@~str, ~[@meta_item]),
@@ -270,9 +250,7 @@ pub enum meta_item_ {
 
 pub type blk = spanned<blk_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct blk_ {
     view_items: ~[@view_item],
     stmts: ~[@stmt],
@@ -281,26 +259,20 @@ pub struct blk_ {
     rules: blk_check_mode,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct pat {
     id: node_id,
     node: pat_,
     span: span,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct field_pat {
     ident: ident,
     pat: @pat,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum binding_mode {
     bind_by_copy,
     bind_by_ref(mutability),
@@ -334,9 +306,7 @@ impl to_bytes::IterBytes for binding_mode {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum pat_ {
     pat_wild,
     // A pat_ident may either be a new bound variable,
@@ -361,9 +331,7 @@ pub enum pat_ {
     pat_vec(~[@pat], Option<@pat>, ~[@pat])
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum mutability { m_mutbl, m_imm, m_const, }
 
 #[cfg(stage0)]
@@ -379,9 +347,7 @@ impl to_bytes::IterBytes for mutability {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum Sigil {
     BorrowedSigil,
     OwnedSigil,
@@ -411,9 +377,7 @@ impl ToStr for Sigil {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum vstore {
     // FIXME (#3469): Change uint to @expr (actually only constant exprs)
     vstore_fixed(Option<uint>),     // [1,2,3,4]
@@ -422,9 +386,7 @@ pub enum vstore {
     vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4]
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum expr_vstore {
     expr_vstore_uniq,                  // ~[1,2,3,4]
     expr_vstore_box,                   // @[1,2,3,4]
@@ -433,9 +395,7 @@ pub enum expr_vstore {
     expr_vstore_mut_slice,             // &mut [1,2,3,4]
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum binop {
     add,
     subtract,
@@ -457,9 +417,7 @@ pub enum binop {
     gt,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum unop {
     box(mutability),
     uniq(mutability),
@@ -470,9 +428,7 @@ pub enum unop {
 
 pub type stmt = spanned<stmt_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum stmt_ {
     stmt_decl(@decl, node_id),
 
@@ -488,9 +444,7 @@ pub enum stmt_ {
 
 // FIXME (pending discussion of #1697, #2178...): local should really be
 // a refinement on pat.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct local_ {
     is_mutbl: bool,
     ty: @Ty,
@@ -503,23 +457,17 @@ pub type local = spanned<local_>;
 
 pub type decl = spanned<decl_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum decl_ { decl_local(~[@local]), decl_item(@item), }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct arm {
     pats: ~[@pat],
     guard: Option<@expr>,
     body: blk,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct field_ {
     mutbl: mutability,
     ident: ident,
@@ -528,14 +476,10 @@ pub struct field_ {
 
 pub type field = spanned<field_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum blk_check_mode { default_blk, unsafe_blk, }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct expr {
     id: node_id,
     // Extra node ID is only used for index, assign_op, unary, binary, method
@@ -545,18 +489,14 @@ pub struct expr {
     span: span,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum CallSugar {
     NoSugar,
     DoSugar,
     ForSugar
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum expr_ {
     expr_vstore(@expr, expr_vstore),
     expr_vec(~[@expr], mutability),
@@ -627,9 +567,7 @@ pub enum expr_ {
 // else knows what to do with them, so you'll probably get a syntax
 // error.
 //
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 #[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum token_tree {
     // a single token
@@ -702,9 +640,7 @@ pub enum token_tree {
 //
 pub type matcher = spanned<matcher_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum matcher_ {
     // match one token
     match_tok(::parse::token::Token),
@@ -717,18 +653,14 @@ pub enum matcher_ {
 
 pub type mac = spanned<mac_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum mac_ {
     mac_invoc_tt(@Path,~[token_tree]),   // new macro-invocation
 }
 
 pub type lit = spanned<lit_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum lit_ {
     lit_str(@~str),
     lit_int(i64, int_ty),
@@ -742,17 +674,13 @@ pub enum lit_ {
 
 // NB: If you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct mt {
     ty: @Ty,
     mutbl: mutability,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct ty_field_ {
     ident: ident,
     mt: mt,
@@ -760,9 +688,7 @@ pub struct ty_field_ {
 
 pub type ty_field = spanned<ty_field_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct ty_method {
     ident: ident,
     attrs: ~[attribute],
@@ -774,9 +700,7 @@ pub struct ty_method {
     span: span,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 // A trait method is either required (meaning it doesn't have an
 // implementation, just a signature) or provided (meaning it has a default
 // implementation).
@@ -785,9 +709,7 @@ pub enum trait_method {
     provided(@method),
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
 
 impl ToStr for int_ty {
@@ -809,9 +731,7 @@ impl to_bytes::IterBytes for int_ty {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
 
 impl ToStr for uint_ty {
@@ -833,9 +753,7 @@ impl to_bytes::IterBytes for uint_ty {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum float_ty { ty_f, ty_f32, ty_f64, }
 
 impl ToStr for float_ty {
@@ -858,9 +776,7 @@ impl to_bytes::IterBytes for float_ty {
 }
 
 // NB Eq method appears below.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct Ty {
     id: node_id,
     node: ty_,
@@ -868,9 +784,7 @@ pub struct Ty {
 }
 
 // Not represented directly in the AST, referred to by name through a ty_path.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum prim_ty {
     ty_int(int_ty),
     ty_uint(uint_ty),
@@ -879,9 +793,7 @@ pub enum prim_ty {
     ty_bool,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum Onceness {
     Once,
     Many
@@ -909,9 +821,7 @@ impl to_bytes::IterBytes for Onceness {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct TyClosure {
     sigil: Sigil,
     region: Option<@Lifetime>,
@@ -921,9 +831,7 @@ pub struct TyClosure {
     decl: fn_decl
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct TyBareFn {
     purity: purity,
     abis: AbiSet,
@@ -931,9 +839,7 @@ pub struct TyBareFn {
     decl: fn_decl
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum ty_ {
     ty_nil,
     ty_bot, /* bottom type */
@@ -967,17 +873,13 @@ impl to_bytes::IterBytes for Ty {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum asm_dialect {
     asm_att,
     asm_intel
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct inline_asm {
     asm: @~str,
     clobbers: @~str,
@@ -988,9 +890,7 @@ pub struct inline_asm {
     dialect: asm_dialect
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct arg {
     is_mutbl: bool,
     ty: @Ty,
@@ -998,18 +898,14 @@ pub struct arg {
     id: node_id,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct fn_decl {
     inputs: ~[arg],
     output: @Ty,
     cf: ret_style,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum purity {
     pure_fn, // declared with "pure fn"
     unsafe_fn, // declared with "unsafe fn"
@@ -1041,9 +937,7 @@ impl to_bytes::IterBytes for purity {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum ret_style {
     noreturn, // functions with return type _|_ that always
               // raise an error or exit (i.e. never return to the caller)
@@ -1063,9 +957,7 @@ impl to_bytes::IterBytes for ret_style {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum explicit_self_ {
     sty_static,                                // no self
     sty_value,                                 // `self`
@@ -1102,9 +994,7 @@ impl to_bytes::IterBytes for explicit_self_ {
 
 pub type explicit_self = spanned<explicit_self_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct method {
     ident: ident,
     attrs: ~[attribute],
@@ -1119,23 +1009,17 @@ pub struct method {
     vis: visibility,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct _mod {
     view_items: ~[@view_item],
     items: ~[@item],
 }
 
 // Foreign mods can be named or anonymous
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum foreign_mod_sort { named, anonymous }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct foreign_mod {
     sort: foreign_mod_sort,
     abis: AbiSet,
@@ -1143,32 +1027,24 @@ pub struct foreign_mod {
     items: ~[@foreign_item],
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct variant_arg {
     ty: @Ty,
     id: node_id,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum variant_kind {
     tuple_variant_kind(~[variant_arg]),
     struct_variant_kind(@struct_def),
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct enum_def {
     variants: ~[variant],
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct variant_ {
     name: ident,
     attrs: ~[attribute],
@@ -1180,9 +1056,7 @@ pub struct variant_ {
 
 pub type variant = spanned<variant_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct path_list_ident_ {
     name: ident,
     id: node_id,
@@ -1192,9 +1066,7 @@ pub type path_list_ident = spanned<path_list_ident_>;
 
 pub type view_path = spanned<view_path_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum view_path_ {
 
     // quux = foo::bar::baz
@@ -1211,9 +1083,7 @@ pub enum view_path_ {
     view_path_list(@Path, ~[path_list_ident], node_id)
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct view_item {
     node: view_item_,
     attrs: ~[attribute],
@@ -1221,9 +1091,7 @@ pub struct view_item {
     span: span,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum view_item_ {
     view_item_extern_mod(ident, ~[@meta_item], node_id),
     view_item_use(~[@view_path]),
@@ -1235,15 +1103,11 @@ pub type attribute = spanned<attribute_>;
 // Distinguishes between attributes that decorate items and attributes that
 // are contained as statements within items. These two cases need to be
 // distinguished for pretty-printing.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum attr_style { attr_outer, attr_inner, }
 
 // doc-comments are promoted to attributes that have is_sugared_doc = true
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct attribute_ {
     style: attr_style,
     value: @meta_item,
@@ -1257,17 +1121,13 @@ pub struct attribute_ {
   If this impl is an item_impl, the impl_id is redundant (it could be the
   same as the impl's node id).
  */
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct trait_ref {
     path: @Path,
     ref_id: node_id,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum visibility { public, private, inherited }
 
 impl visibility {
@@ -1279,9 +1139,7 @@ impl visibility {
     }
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct struct_field_ {
     kind: struct_field_kind,
     id: node_id,
@@ -1291,17 +1149,13 @@ pub struct struct_field_ {
 
 pub type struct_field = spanned<struct_field_>;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum struct_field_kind {
     named_field(ident, visibility),
     unnamed_field   // element of a tuple-like struct
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct struct_def {
     fields: ~[@struct_field], /* fields, not including ctor */
     /* ID of the constructor. This is only used for tuple- or enum-like
@@ -1313,9 +1167,7 @@ pub struct struct_def {
   FIXME (#3300): Should allow items to be anonymous. Right now
   we just use dummy names for anon items.
  */
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct item {
     ident: ident,
     attrs: ~[attribute],
@@ -1325,9 +1177,7 @@ pub struct item {
     span: span,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum item_ {
     item_const(@Ty, @expr),
     item_fn(fn_decl, purity, AbiSet, Generics, blk),
@@ -1345,9 +1195,7 @@ pub enum item_ {
     item_mac(mac),
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct foreign_item {
     ident: ident,
     attrs: ~[attribute],
@@ -1357,9 +1205,7 @@ pub struct foreign_item {
     vis: visibility,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum foreign_item_ {
     foreign_item_fn(fn_decl, purity, Generics),
     foreign_item_const(@Ty)
@@ -1368,9 +1214,7 @@ pub enum foreign_item_ {
 // The data we save and restore about an inlined item or method.  This is not
 // part of the AST that we parse from a file, but it becomes part of the tree
 // that we trans.
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub enum inlined_item {
     ii_item(@item),
     ii_method(def_id /* impl id */, @method),
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index a98e3002dcf..aa1ee7cd27e 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -370,8 +370,7 @@ pub fn empty_generics() -> Generics {
 // ______________________________________________________________________
 // Enumerating the IDs which appear in an AST
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub struct id_range {
     min: node_id,
     max: node_id,
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index cd0b29f2a1e..44a368738fd 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -127,9 +127,7 @@ pub struct span {
     expn_info: Option<@ExpnInfo>
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Eq, Encodable, Decodable)]
 pub struct spanned<T> { node: T, span: span }
 
 impl cmp::Eq for span {
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 5c306aefc6a..6bb3ac5eba4 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -8,102 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*!
-
-The compiler code necessary to implement the #[auto_encode] and
-#[auto_decode] extension.  The idea here is that type-defining items may
-be tagged with #[auto_encode] and #[auto_decode], which will cause
-us to generate a little companion module with the same name as the item.
-
-For example, a type like:
-
-    #[auto_encode]
-    #[auto_decode]
-    struct Node {id: uint}
-
-would generate two implementations like:
-
-impl<S:std::serialize::Encoder> Encodable<S> for Node {
-    fn encode(&self, s: &S) {
-        do s.emit_struct("Node", 1) {
-            s.emit_field("id", 0, || s.emit_uint(self.id))
-        }
-    }
-}
-
-impl<D:Decoder> Decodable for node_id {
-    fn decode(d: &D) -> Node {
-        do d.read_struct("Node", 1) {
-            Node {
-                id: d.read_field(~"x", 0, || decode(d))
-            }
-        }
-    }
-}
-
-Other interesting scenarios are whe the item has type parameters or
-references other non-built-in types.  A type definition like:
-
-    #[auto_encode]
-    #[auto_decode]
-    struct spanned<T> {node: T, span: span}
-
-would yield functions like:
-
-    impl<
-        S: Encoder,
-        T: Encodable<S>
-    > spanned<T>: Encodable<S> {
-        fn encode<S:Encoder>(s: &S) {
-            do s.emit_rec {
-                s.emit_field("node", 0, || self.node.encode(s));
-                s.emit_field("span", 1, || self.span.encode(s));
-            }
-        }
-    }
-
-    impl<
-        D: Decoder,
-        T: Decodable<D>
-    > spanned<T>: Decodable<D> {
-        fn decode(d: &D) -> spanned<T> {
-            do d.read_rec {
-                {
-                    node: d.read_field(~"node", 0, || decode(d)),
-                    span: d.read_field(~"span", 1, || decode(d)),
-                }
-            }
-        }
-    }
-
-FIXME (#2810)--Hygiene. Search for "__" strings.  We also assume "std" is the
-standard library.
-
-Misc notes:
------------
-
-I use move mode arguments for ast nodes that will get inserted as is
-into the tree.  This is intended to prevent us from inserting the same
-node twice.
-
-*/
+/// Deprecated #[auto_encode] and #[auto_decode] syntax extensions
 
 use ast;
-use ast_util;
-use attr;
-use codemap;
 use codemap::span;
 use ext::base::*;
-use parse;
-use opt_vec;
-use opt_vec::OptVec;
-use ext::build;
-
-// Transitional reexports so qquote can find the paths it is looking for
-mod syntax {
-    pub use ext;
-    pub use parse;
-}
 
 pub fn expand_auto_encode(
     cx: @ext_ctxt,
@@ -111,53 +20,8 @@ pub fn expand_auto_encode(
     _mitem: @ast::meta_item,
     in_items: ~[@ast::item]
 ) -> ~[@ast::item] {
-    fn is_auto_encode(a: &ast::attribute) -> bool {
-        *attr::get_attr_name(a) == ~"auto_encode"
-    }
-
-    fn filter_attrs(item: @ast::item) -> @ast::item {
-        @ast::item {
-            attrs: item.attrs.filtered(|a| !is_auto_encode(a)),
-            .. copy *item
-        }
-    }
-
-    do vec::flat_map(in_items) |item| {
-        if item.attrs.any(is_auto_encode) {
-            match item.node {
-                ast::item_struct(ref struct_def, ref generics) => {
-                    let ser_impl = mk_struct_ser_impl(
-                        cx,
-                        item.span,
-                        item.ident,
-                        struct_def.fields,
-                        generics
-                    );
-
-                    ~[filter_attrs(*item), ser_impl]
-                },
-                ast::item_enum(ref enum_def, ref generics) => {
-                    let ser_impl = mk_enum_ser_impl(
-                        cx,
-                        item.span,
-                        item.ident,
-                        copy *enum_def,
-                        generics
-                    );
-
-                    ~[filter_attrs(*item), ser_impl]
-                },
-                _ => {
-                    cx.span_err(span, ~"#[auto_encode] can only be \
-                                        applied to structs, record types, \
-                                        and enum definitions");
-                    ~[*item]
-                }
-            }
-        } else {
-            ~[*item]
-        }
-    }
+    cx.span_err(span, "`#[auto_encode]` is deprecated, use `#[deriving(Encodable)]` instead");
+    in_items
 }
 
 pub fn expand_auto_decode(
@@ -166,1346 +30,6 @@ pub fn expand_auto_decode(
     _mitem: @ast::meta_item,
     in_items: ~[@ast::item]
 ) -> ~[@ast::item] {
-    fn is_auto_decode(a: &ast::attribute) -> bool {
-        *attr::get_attr_name(a) == ~"auto_decode"
-    }
-
-    fn filter_attrs(item: @ast::item) -> @ast::item {
-        @ast::item {
-            attrs: item.attrs.filtered(|a| !is_auto_decode(a)),
-            .. copy *item
-        }
-    }
-
-    do vec::flat_map(in_items) |item| {
-        if item.attrs.any(is_auto_decode) {
-            match item.node {
-                ast::item_struct(ref struct_def, ref generics) => {
-                    let deser_impl = mk_struct_deser_impl(
-                        cx,
-                        item.span,
-                        item.ident,
-                        struct_def.fields,
-                        generics
-                    );
-
-                    ~[filter_attrs(*item), deser_impl]
-                },
-                ast::item_enum(ref enum_def, ref generics) => {
-                    let deser_impl = mk_enum_deser_impl(
-                        cx,
-                        item.span,
-                        item.ident,
-                        copy *enum_def,
-                        generics
-                    );
-
-                    ~[filter_attrs(*item), deser_impl]
-                },
-                _ => {
-                    cx.span_err(span, ~"#[auto_decode] can only be \
-                                        applied to structs, record types, \
-                                        and enum definitions");
-                    ~[*item]
-                }
-            }
-        } else {
-            ~[*item]
-        }
-    }
-}
-
-trait ExtCtxtMethods {
-    fn bind_path(&self,
-                 span: span,
-                 ident: ast::ident,
-                 path: @ast::Path,
-                 bounds: @OptVec<ast::TyParamBound>)
-                 -> ast::TyParam;
-    fn expr(&self, span: span, node: ast::expr_) -> @ast::expr;
-    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
-    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
-    fn path_tps(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty])
-                -> @ast::Path;
-    fn path_tps_global(&self,
-                       span: span,
-                       strs: ~[ast::ident],
-                       tps: ~[@ast::Ty])
-                       -> @ast::Path;
-    fn ty_path(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty])
-               -> @ast::Ty;
-    fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat;
-    fn stmt(&self, expr: @ast::expr) -> @ast::stmt;
-    fn lit_str(&self, span: span, s: @~str) -> @ast::expr;
-    fn lit_uint(&self, span: span, i: uint) -> @ast::expr;
-    fn lambda0(&self, blk: ast::blk) -> @ast::expr;
-    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr;
-    fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk;
-    fn expr_blk(&self, expr: @ast::expr) -> ast::blk;
-    fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
-    fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
-    fn expr_var(&self, span: span, var: &str) -> @ast::expr;
-    fn expr_self(&self, span: span) -> @ast::expr;
-    fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident)
-                  -> @ast::expr;
-    fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr])
-                 -> @ast::expr;
-    fn expr_method_call(&self,
-                        span: span,
-                        expr: @ast::expr,
-                        ident: ast::ident,
-                        args: ~[@ast::expr])
-                        -> @ast::expr;
-    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr;
-    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
-                    -> @ast::expr;
-    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr;
-    fn lambda_stmts_1(&self,
-                      span: span,
-                      stmts: ~[@ast::stmt],
-                      ident: ast::ident)
-                      -> @ast::expr;
-}
-
-impl ExtCtxtMethods for @ext_ctxt {
-    fn bind_path(
-        &self,
-        _span: span,
-        ident: ast::ident,
-        path: @ast::Path,
-        bounds: @OptVec<ast::TyParamBound>
-    ) -> ast::TyParam {
-        let bound = ast::TraitTyParamBound(@ast::trait_ref {
-            ref_id: self.next_id(),
-            path: path
-        });
-
-        ast::TyParam {
-            ident: ident,
-            id: self.next_id(),
-            bounds: @bounds.prepend(bound)
-        }
-    }
-
-    fn expr(&self, span: span, node: ast::expr_) -> @ast::expr {
-        @ast::expr {
-            id: self.next_id(),
-            callee_id: self.next_id(),
-            node: node,
-            span: span,
-        }
-    }
-
-    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: false,
-            idents: strs,
-            rp: None,
-            types: ~[]
-        }
-    }
-
-    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: true,
-            idents: strs,
-            rp: None,
-            types: ~[]
-        }
-    }
-
-    fn path_tps(
-        &self,
-        span: span,
-        strs: ~[ast::ident],
-        tps: ~[@ast::Ty]
-    ) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: false,
-            idents: strs,
-            rp: None,
-            types: tps
-        }
-    }
-
-    fn path_tps_global(
-        &self,
-        span: span,
-        strs: ~[ast::ident],
-        tps: ~[@ast::Ty]
-    ) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: true,
-            idents: strs,
-            rp: None,
-            types: tps
-        }
-    }
-
-    fn ty_path(
-        &self,
-        span: span,
-        strs: ~[ast::ident],
-        tps: ~[@ast::Ty]
-    ) -> @ast::Ty {
-        @ast::Ty {
-            id: self.next_id(),
-            node: ast::ty_path(
-                self.path_tps(span, strs, tps),
-                self.next_id()),
-            span: span,
-        }
-    }
-
-    fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat {
-        @ast::pat {
-            id: self.next_id(),
-            node: ast::pat_ident(
-                ast::bind_by_ref(ast::m_imm),
-                self.path(span, ~[nm]),
-                None),
-            span: span,
-        }
-    }
-
-    fn stmt(&self, expr: @ast::expr) -> @ast::stmt {
-        @codemap::spanned { node: ast::stmt_semi(expr, self.next_id()),
-                       span: expr.span }
-    }
-
-    fn lit_str(&self, span: span, s: @~str) -> @ast::expr {
-        self.expr(
-            span,
-            ast::expr_vstore(
-                self.expr(
-                    span,
-                    ast::expr_lit(
-                        @codemap::spanned { node: ast::lit_str(s),
-                                        span: span})),
-                ast::expr_vstore_uniq))
-    }
-
-    fn lit_uint(&self, span: span, i: uint) -> @ast::expr {
-        self.expr(
-            span,
-            ast::expr_lit(
-                @codemap::spanned { node: ast::lit_uint(i as u64, ast::ty_u),
-                                span: span}))
-    }
-
-    fn lambda0(&self, blk: ast::blk) -> @ast::expr {
-        let ext_cx = *self;
-        let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
-        quote_expr!( || $blk_e )
-    }
-
-    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr {
-        let ext_cx = *self;
-        let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
-        quote_expr!( |$ident| $blk_e )
-    }
-
-    fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk {
-        codemap::spanned {
-            node: ast::blk_ {
-                view_items: ~[],
-                stmts: stmts,
-                expr: None,
-                id: self.next_id(),
-                rules: ast::default_blk,
-            },
-            span: span,
-        }
-    }
-
-    fn expr_blk(&self, expr: @ast::expr) -> ast::blk {
-        codemap::spanned {
-            node: ast::blk_ {
-                view_items: ~[],
-                stmts: ~[],
-                expr: Some(expr),
-                id: self.next_id(),
-                rules: ast::default_blk,
-            },
-            span: expr.span,
-        }
-    }
-
-    fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path(span, strs)))
-    }
-
-    fn expr_path_global(
-        &self,
-        span: span,
-        strs: ~[ast::ident]
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path_global(span, strs)))
-    }
-
-    fn expr_var(&self, span: span, var: &str) -> @ast::expr {
-        self.expr_path(span, ~[self.ident_of(var)])
-    }
-
-    fn expr_self(&self, span: span) -> @ast::expr {
-        self.expr(span, ast::expr_self)
-    }
-
-    fn expr_field(
-        &self,
-        span: span,
-        expr: @ast::expr,
-        ident: ast::ident
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_field(expr, ident, ~[]))
-    }
-
-    fn expr_call(
-        &self,
-        span: span,
-        expr: @ast::expr,
-        args: ~[@ast::expr]
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_call(expr, args, ast::NoSugar))
-    }
-
-    fn expr_method_call(
-        &self,
-        span: span,
-        expr: @ast::expr,
-        ident: ast::ident,
-        args: ~[@ast::expr]
-    ) -> @ast::expr {
-        self.expr(span,
-                  ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar))
-    }
-
-    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr {
-        self.lambda0(self.expr_blk(expr))
-    }
-
-    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
-                    -> @ast::expr {
-        self.lambda1(self.expr_blk(expr), ident)
-    }
-
-    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
-        self.lambda0(self.blk(span, stmts))
-    }
-
-    fn lambda_stmts_1(&self,
-                      span: span,
-                      stmts: ~[@ast::stmt],
-                      ident: ast::ident)
-                      -> @ast::expr {
-        self.lambda1(self.blk(span, stmts), ident)
-    }
-}
-
-fn mk_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    ty_param: ast::TyParam,
-    path: @ast::Path,
-    generics: &ast::Generics,
-    f: &fn(@ast::Ty) -> @ast::method
-) -> @ast::item {
-    /*!
-     *
-     * Given that we are deriving auto-encode a type `T<'a, ...,
-     * 'z, A, ..., Z>`, creates an impl like:
-     *
-     *      impl<'a, ..., 'z, A:Tr, ..., Z:Tr> Tr for T<A, ..., Z> { ... }
-     *
-     * where Tr is either Serializable and Deserialize.
-     *
-     * FIXME(#5090): Remove code duplication between this and the code
-     * in deriving.rs
-     */
-
-
-    // Copy the lifetimes
-    let impl_lifetimes = generics.lifetimes.map(|l| {
-        build::mk_lifetime(cx, l.span, l.ident)
-    });
-
-    // All the type parameters need to bound to the trait.
-    let mut impl_tps = opt_vec::with(ty_param);
-    for generics.ty_params.each |tp| {
-        let t_bound = ast::TraitTyParamBound(@ast::trait_ref {
-            path: path,
-            ref_id: cx.next_id(),
-        });
-
-        impl_tps.push(ast::TyParam {
-            ident: tp.ident,
-            id: cx.next_id(),
-            bounds: @tp.bounds.prepend(t_bound)
-        })
-    }
-
-    let opt_trait = Some(@ast::trait_ref {
-        path: path,
-        ref_id: cx.next_id(),
-    });
-
-    let ty = cx.ty_path(
-        span,
-        ~[ident],
-        opt_vec::take_vec(generics.ty_params.map(
-            |tp| cx.ty_path(span, ~[tp.ident], ~[])))
-    );
-
-    let generics = ast::Generics {
-        lifetimes: impl_lifetimes,
-        ty_params: impl_tps
-    };
-
-    @ast::item {
-        // This is a new-style impl declaration.
-        // XXX: clownshoes
-        ident: parse::token::special_idents::clownshoes_extensions,
-        attrs: ~[],
-        id: cx.next_id(),
-        node: ast::item_impl(generics, opt_trait, ty, ~[f(ty)]),
-        vis: ast::public,
-        span: span,
-    }
-}
-
-fn mk_ser_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    generics: &ast::Generics,
-    body: @ast::expr
-) -> @ast::item {
-    // Make a path to the std::serialize::Encodable typaram.
-    let ty_param = cx.bind_path(
-        span,
-        cx.ident_of("__S"),
-        cx.path_global(
-            span,
-            ~[
-                cx.ident_of("std"),
-                cx.ident_of("serialize"),
-                cx.ident_of("Encoder"),
-            ]
-        ),
-        @opt_vec::Empty
-    );
-
-    // Make a path to the std::serialize::Encodable trait.
-    let path = cx.path_tps_global(
-        span,
-        ~[
-            cx.ident_of("std"),
-            cx.ident_of("serialize"),
-            cx.ident_of("Encodable"),
-        ],
-        ~[cx.ty_path(span, ~[cx.ident_of("__S")], ~[])]
-    );
-
-    mk_impl(
-        cx,
-        span,
-        ident,
-        ty_param,
-        path,
-        generics,
-        |_ty| mk_ser_method(cx, span, cx.expr_blk(body))
-    )
-}
-
-fn mk_deser_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    generics: &ast::Generics,
-    body: @ast::expr
-) -> @ast::item {
-    // Make a path to the std::serialize::Decodable typaram.
-    let ty_param = cx.bind_path(
-        span,
-        cx.ident_of("__D"),
-        cx.path_global(
-            span,
-            ~[
-                cx.ident_of("std"),
-                cx.ident_of("serialize"),
-                cx.ident_of("Decoder"),
-            ]
-        ),
-        @opt_vec::Empty
-    );
-
-    // Make a path to the std::serialize::Decodable trait.
-    let path = cx.path_tps_global(
-        span,
-        ~[
-            cx.ident_of("std"),
-            cx.ident_of("serialize"),
-            cx.ident_of("Decodable"),
-        ],
-        ~[cx.ty_path(span, ~[cx.ident_of("__D")], ~[])]
-    );
-
-    mk_impl(
-        cx,
-        span,
-        ident,
-        ty_param,
-        path,
-        generics,
-        |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body))
-    )
-}
-
-fn mk_ser_method(
-    cx: @ext_ctxt,
-    span: span,
-    ser_body: ast::blk
-) -> @ast::method {
-    let ty_s = @ast::Ty {
-        id: cx.next_id(),
-        node: ast::ty_rptr(
-            None,
-            ast::mt {
-                ty: cx.ty_path(span, ~[cx.ident_of("__S")], ~[]),
-                mutbl: ast::m_mutbl
-            }
-        ),
-        span: span,
-    };
-
-    let ser_inputs = ~[ast::arg {
-        is_mutbl: false,
-        ty: ty_s,
-        pat: @ast::pat {
-            id: cx.next_id(),
-            node: ast::pat_ident(
-                ast::bind_by_copy,
-                ast_util::ident_to_path(span, cx.ident_of("__s")),
-                None),
-            span: span,
-        },
-        id: cx.next_id(),
-    }];
-
-    let ser_output = @ast::Ty {
-        id: cx.next_id(),
-        node: ast::ty_nil,
-        span: span,
-    };
-
-    let ser_decl = ast::fn_decl {
-        inputs: ser_inputs,
-        output: ser_output,
-        cf: ast::return_val,
-    };
-
-    @ast::method {
-        ident: cx.ident_of("encode"),
-        attrs: ~[],
-        generics: ast_util::empty_generics(),
-        explicit_self: codemap::spanned {
-            node: ast::sty_region(None, ast::m_imm),
-            span: span
-        },
-        purity: ast::impure_fn,
-        decl: ser_decl,
-        body: ser_body,
-        id: cx.next_id(),
-        span: span,
-        self_id: cx.next_id(),
-        vis: ast::public,
-    }
-}
-
-fn mk_deser_method(
-    cx: @ext_ctxt,
-    span: span,
-    ty: @ast::Ty,
-    deser_body: ast::blk
-) -> @ast::method {
-    let ty_d = @ast::Ty {
-        id: cx.next_id(),
-        node: ast::ty_rptr(
-            None,
-            ast::mt {
-                ty: cx.ty_path(span, ~[cx.ident_of("__D")], ~[]),
-                mutbl: ast::m_mutbl
-            }
-        ),
-        span: span,
-    };
-
-    let deser_inputs = ~[
-        ast::arg {
-            is_mutbl: false,
-            ty: ty_d,
-            pat: @ast::pat {
-                id: cx.next_id(),
-                node: ast::pat_ident(ast::bind_by_copy,
-                                     ast_util::ident_to_path(span,
-                                                             cx.ident_of(
-                                                                "__d")),
-                                     None),
-                span: span,
-            },
-            id: cx.next_id(),
-        }
-    ];
-
-    let deser_decl = ast::fn_decl {
-        inputs: deser_inputs,
-        output: ty,
-        cf: ast::return_val,
-    };
-
-    @ast::method {
-        ident: cx.ident_of("decode"),
-        attrs: ~[],
-        generics: ast_util::empty_generics(),
-        explicit_self: codemap::spanned { node: ast::sty_static, span: span },
-        purity: ast::impure_fn,
-        decl: deser_decl,
-        body: deser_body,
-        id: cx.next_id(),
-        span: span,
-        self_id: cx.next_id(),
-        vis: ast::public,
-    }
-}
-
-fn mk_struct_ser_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    fields: &[@ast::struct_field],
-    generics: &ast::Generics
-) -> @ast::item {
-    let fields = do mk_struct_fields(fields).mapi |idx, field| {
-        // ast for `|__s| self.$(name).encode(__s)`
-        let expr_lambda = cx.lambda_expr_1(
-            cx.expr_method_call(
-                span,
-                cx.expr_field(span, cx.expr_self(span), field.ident),
-                cx.ident_of(~"encode"),
-                ~[cx.expr_var(span, "__s")]
-            ),
-            cx.ident_of("__s")
-        );
-
-        // ast for `__s.emit_struct_field($(name), $(idx), $(expr_lambda))`
-        cx.stmt(
-            cx.expr_method_call(
-                span,
-                cx.expr_var(span, "__s"),
-                cx.ident_of("emit_struct_field"),
-                ~[
-                    cx.lit_str(span, @cx.str_of(field.ident)),
-                    cx.lit_uint(span, idx),
-                    expr_lambda,
-                ]
-            )
-        )
-    };
-
-    // ast for `__s.emit_struct($(name), |__s| $(fields))`
-    let ser_body = cx.expr_method_call(
-        span,
-        cx.expr_var(span, "__s"),
-        cx.ident_of("emit_struct"),
-        ~[
-            cx.lit_str(span, @cx.str_of(ident)),
-            cx.lit_uint(span, fields.len()),
-            cx.lambda_stmts_1(span, fields, cx.ident_of("__s")),
-        ]
-    );
-
-    mk_ser_impl(cx, span, ident, generics, ser_body)
-}
-
-fn mk_struct_deser_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    fields: &[@ast::struct_field],
-    generics: &ast::Generics
-) -> @ast::item {
-    let fields = do mk_struct_fields(fields).mapi |idx, field| {
-        // ast for `|__d| std::serialize::decode(__d)`
-        let expr_lambda = cx.lambda1(
-            cx.expr_blk(
-                cx.expr_call(
-                    span,
-                    cx.expr_path_global(span, ~[
-                        cx.ident_of("std"),
-                        cx.ident_of("serialize"),
-                        cx.ident_of("Decodable"),
-                        cx.ident_of("decode"),
-                    ]),
-                    ~[cx.expr_var(span, "__d")]
-                )
-            ),
-            cx.ident_of("__d")
-        );
-
-        // ast for `__d.read_struct_field($(name), $(idx), $(expr_lambda))`
-        let expr: @ast::expr = cx.expr_method_call(
-            span,
-            cx.expr_var(span, "__d"),
-            cx.ident_of("read_struct_field"),
-            ~[
-                cx.lit_str(span, @cx.str_of(field.ident)),
-                cx.lit_uint(span, idx),
-                expr_lambda,
-            ]
-        );
-
-        codemap::spanned {
-            node: ast::field_ {
-                mutbl: field.mutbl,
-                ident: field.ident,
-                expr: expr,
-            },
-            span: span,
-        }
-    };
-
-    // ast for `read_struct($(name), |__d| $(fields))`
-    let body = cx.expr_method_call(
-        span,
-        cx.expr_var(span, "__d"),
-        cx.ident_of("read_struct"),
-        ~[
-            cx.lit_str(span, @cx.str_of(ident)),
-            cx.lit_uint(span, fields.len()),
-            cx.lambda_expr_1(
-                cx.expr(
-                    span,
-                    ast::expr_struct(
-                        cx.path(span, ~[ident]),
-                        fields,
-                        None
-                    )
-                ),
-                cx.ident_of("__d")
-            ),
-        ]
-    );
-
-    mk_deser_impl(cx, span, ident, generics, body)
-}
-
-// Records and structs don't have the same fields types, but they share enough
-// that if we extract the right subfields out we can share the code
-// generator code.
-struct field {
-    span: span,
-    ident: ast::ident,
-    mutbl: ast::mutability,
-}
-
-fn mk_struct_fields(fields: &[@ast::struct_field]) -> ~[field] {
-    do fields.map |field| {
-        let ident = match field.node.kind {
-            ast::named_field(ident, _) => ident,
-            _ => fail!("[auto_encode] does not support unnamed fields")
-        };
-
-        field {
-            span: field.span,
-            ident: ident,
-            mutbl: ast::m_imm,
-        }
-    }
-}
-
-fn mk_enum_ser_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    enum_def: ast::enum_def,
-    generics: &ast::Generics
-) -> @ast::item {
-    let body = mk_enum_ser_body(
-        cx,
-        span,
-        ident,
-        copy enum_def.variants
-    );
-
-    mk_ser_impl(cx, span, ident, generics, body)
-}
-
-fn mk_enum_deser_impl(
-    cx: @ext_ctxt,
-    span: span,
-    ident: ast::ident,
-    enum_def: ast::enum_def,
-    generics: &ast::Generics
-) -> @ast::item {
-    let body = mk_enum_deser_body(
-        cx,
-        span,
-        ident,
-        enum_def.variants
-    );
-
-    mk_deser_impl(cx, span, ident, generics, body)
-}
-
-fn ser_variant(
-    cx: @ext_ctxt,
-    span: span,
-    v_name: ast::ident,
-    v_idx: uint,
-    args: ~[ast::variant_arg]
-) -> ast::arm {
-    // Name the variant arguments.
-    let names = args.mapi(|i, _arg| cx.ident_of(fmt!("__v%u", i)));
-
-    // Bind the names to the variant argument type.
-    let pats = args.mapi(|i, arg| cx.binder_pat(arg.ty.span, names[i]));
-
-    let pat_node = if pats.is_empty() {
-        ast::pat_ident(
-            ast::bind_infer,
-            cx.path(span, ~[v_name]),
-            None
-        )
-    } else {
-        ast::pat_enum(
-            cx.path(span, ~[v_name]),
-            Some(pats)
-        )
-    };
-
-    let pat = @ast::pat {
-        id: cx.next_id(),
-        node: pat_node,
-        span: span,
-    };
-
-    let stmts = do args.mapi |a_idx, _arg| {
-        // ast for `__s.emit_enum_variant_arg`
-        let expr_emit = cx.expr_field(
-            span,
-            cx.expr_var(span, "__s"),
-            cx.ident_of("emit_enum_variant_arg")
-        );
-
-        // ast for `|__s| $(v).encode(__s)`
-        let expr_encode = cx.lambda_expr_1(
-            cx.expr_method_call(
-                span,
-                 cx.expr_path(span, ~[names[a_idx]]),
-                 cx.ident_of("encode"),
-                ~[cx.expr_var(span, "__s")]
-            ),
-            cx.ident_of("__s")
-        );
-
-        // ast for `$(expr_emit)($(a_idx), $(expr_encode))`
-        cx.stmt(
-            cx.expr_call(
-                span,
-                expr_emit,
-                ~[cx.lit_uint(span, a_idx), expr_encode]
-            )
-        )
-    };
-
-    // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))`
-    let body = cx.expr_method_call(
-        span,
-        cx.expr_var(span, "__s"),
-        cx.ident_of("emit_enum_variant"),
-        ~[
-            cx.lit_str(span, @cx.str_of(v_name)),
-            cx.lit_uint(span, v_idx),
-            cx.lit_uint(span, stmts.len()),
-            cx.lambda_stmts_1(span, stmts, cx.ident_of("__s")),
-        ]
-    );
-
-    ast::arm { pats: ~[pat], guard: None, body: cx.expr_blk(body) }
-}
-
-fn mk_enum_ser_body(
-    cx: @ext_ctxt,
-    span: span,
-    name: ast::ident,
-    variants: ~[ast::variant]
-) -> @ast::expr {
-    let arms = do variants.mapi |v_idx, variant| {
-        match variant.node.kind {
-            ast::tuple_variant_kind(ref args) =>
-                ser_variant(
-                    cx,
-                    span,
-                    variant.node.name,
-                    v_idx,
-                    /*bad*/ copy *args
-                ),
-            ast::struct_variant_kind(*) =>
-                fail!("struct variants unimplemented"),
-        }
-    };
-
-    // ast for `match *self { $(arms) }`
-    let match_expr = cx.expr(
-        span,
-        ast::expr_match(cx.expr(span,
-                                ast::expr_unary(ast::deref,
-                                                cx.expr_self(span))),
-                        arms)
-    );
-
-    // ast for `__s.emit_enum($(name), || $(match_expr))`
-    cx.expr_method_call(
-        span,
-        cx.expr_var(span, "__s"),
-        cx.ident_of("emit_enum"),
-        ~[
-            cx.lit_str(span, @cx.str_of(name)),
-            cx.lambda_expr_1(match_expr, cx.ident_of("__s")),
-        ]
-    )
-}
-
-fn mk_enum_deser_variant_nary(
-    cx: @ext_ctxt,
-    span: span,
-    name: ast::ident,
-    args: ~[ast::variant_arg]
-) -> @ast::expr {
-    let args = do args.mapi |idx, _arg| {
-        // ast for `|__s| std::serialize::decode(__d)`
-        let expr_lambda = cx.lambda_expr_1(
-            cx.expr_call(
-                span,
-                cx.expr_path_global(span, ~[
-                    cx.ident_of("std"),
-                    cx.ident_of("serialize"),
-                    cx.ident_of("Decodable"),
-                    cx.ident_of("decode"),
-                ]),
-                ~[cx.expr_var(span, "__d")]
-            ),
-            cx.ident_of("__d")
-        );
-
-        // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))`
-        cx.expr_method_call(
-            span,
-            cx.expr_var(span, "__d"),
-            cx.ident_of("read_enum_variant_arg"),
-            ~[cx.lit_uint(span, idx), expr_lambda]
-        )
-    };
-
-    // ast for `$(name)($(args))`
-    cx.expr_call(span, cx.expr_path(span, ~[name]), args)
-}
-
-fn mk_enum_deser_body(
-    ext_cx: @ext_ctxt,
-    span: span,
-    name: ast::ident,
-    variants: &[ast::variant]
-) -> @ast::expr {
-    let expr_arm_names = build::mk_base_vec_e(
-        ext_cx,
-        span,
-         do variants.map |variant| {
-            build::mk_base_str(
-                ext_cx,
-                span,
-                ext_cx.str_of(variant.node.name)
-            )
-        }
-    );
-
-    let mut arms = do variants.mapi |v_idx, variant| {
-        let body = match variant.node.kind {
-            ast::tuple_variant_kind(ref args) => {
-                if args.is_empty() {
-                    // for a nullary variant v, do "v"
-                    ext_cx.expr_path(span, ~[variant.node.name])
-                } else {
-                    // for an n-ary variant v, do "v(a_1, ..., a_n)"
-                    mk_enum_deser_variant_nary(
-                        ext_cx,
-                        span,
-                        variant.node.name,
-                        copy *args
-                    )
-                }
-            },
-            ast::struct_variant_kind(*) =>
-                fail!("struct variants unimplemented"),
-        };
-
-        let pat = @ast::pat {
-            id: ext_cx.next_id(),
-            node: ast::pat_lit(ext_cx.lit_uint(span, v_idx)),
-            span: span,
-        };
-
-        ast::arm {
-            pats: ~[pat],
-            guard: None,
-            body: ext_cx.expr_blk(body),
-        }
-    };
-
-    let quoted_expr = copy quote_expr!(
-      ::core::sys::FailWithCause::fail_with("explicit failure", "empty", 1);
-    ).node;
-
-    let impossible_case = ast::arm {
-        pats: ~[@ast::pat {
-            id: ext_cx.next_id(),
-            node: ast::pat_wild,
-            span: span,
-        }],
-        guard: None,
-
-        // FIXME(#3198): proper error message
-        body: ext_cx.expr_blk(ext_cx.expr(span, quoted_expr)),
-    };
-
-    arms.push(impossible_case);
-
-    // ast for `|i| { match i { $(arms) } }`
-    let expr_lambda = ext_cx.expr(
-        span,
-        ast::expr_fn_block(
-            ast::fn_decl {
-                inputs: ~[
-                    ast::arg {
-                        is_mutbl: false,
-                        ty: @ast::Ty {
-                            id: ext_cx.next_id(),
-                            node: ast::ty_infer,
-                            span: span
-                        },
-                        pat: @ast::pat {
-                            id: ext_cx.next_id(),
-                            node: ast::pat_ident(
-                                ast::bind_by_copy,
-                                ast_util::ident_to_path(span,
-                                    ext_cx.ident_of("__d")),
-                                None),
-                            span: span,
-                        },
-                        id: ext_cx.next_id(),
-                    },
-                    ast::arg {
-                        is_mutbl: false,
-                        ty: @ast::Ty {
-                            id: ext_cx.next_id(),
-                            node: ast::ty_infer,
-                            span: span
-                        },
-                        pat: @ast::pat {
-                            id: ext_cx.next_id(),
-                            node: ast::pat_ident(
-                                ast::bind_by_copy,
-                                ast_util::ident_to_path(span,
-                                    ext_cx.ident_of("i")),
-                                None),
-                            span: span,
-                        },
-                        id: ext_cx.next_id(),
-                    }
-                ],
-                output: @ast::Ty {
-                    id: ext_cx.next_id(),
-                    node: ast::ty_infer,
-                    span: span,
-                },
-                cf: ast::return_val,
-            },
-            ext_cx.expr_blk(
-                ext_cx.expr(
-                    span,
-                    ast::expr_match(ext_cx.expr_var(span, "i"), arms)
-                )
-            )
-        )
-    );
-
-    // ast for `__d.read_enum_variant($expr_arm_names, $(expr_lambda))`
-    let expr_lambda = ext_cx.lambda_expr_1(
-        ext_cx.expr_method_call(
-            span,
-            ext_cx.expr_var(span, "__d"),
-            ext_cx.ident_of("read_enum_variant"),
-            ~[expr_arm_names, expr_lambda]
-        ),
-        ext_cx.ident_of("__d")
-    );
-
-    // ast for `__d.read_enum($(e_name), $(expr_lambda))`
-    ext_cx.expr_method_call(
-        span,
-        ext_cx.expr_var(span, "__d"),
-        ext_cx.ident_of("read_enum"),
-        ~[
-            ext_cx.lit_str(span, @ext_cx.str_of(name)),
-            expr_lambda
-        ]
-    )
-}
-
-#[cfg(test)]
-mod test {
-    use core::option::{None, Some};
-    use std::serialize::Encodable;
-    use std::serialize::Encoder;
-
-    // just adding the ones I want to test, for now:
-    #[deriving(Eq)]
-    pub enum call {
-        CallToEmitEnum(~str),
-        CallToEmitEnumVariant(~str, uint, uint),
-        CallToEmitEnumVariantArg(uint),
-        CallToEmitUint(uint),
-        CallToEmitNil,
-        CallToEmitStruct(~str,uint),
-        CallToEmitField(~str,uint),
-        CallToEmitOption,
-        CallToEmitOptionNone,
-        CallToEmitOptionSome,
-        // all of the ones I was too lazy to handle:
-        CallToOther
-    }
-    // using `@mut` rather than changing the
-    // type of self in every method of every encoder everywhere.
-    pub struct TestEncoder {call_log : @mut ~[call]}
-
-    pub impl TestEncoder {
-        // these self's should be &mut self's, as well....
-        fn add_to_log (&self, c : call) {
-            self.call_log.push(copy c);
-        }
-        fn add_unknown_to_log (&self) {
-            self.add_to_log (CallToOther)
-        }
-    }
-
-    impl Encoder for TestEncoder {
-        fn emit_nil(&mut self) { self.add_to_log(CallToEmitNil) }
-
-        fn emit_uint(&mut self, v: uint) {
-            self.add_to_log(CallToEmitUint(v));
-        }
-        fn emit_u64(&mut self, _v: u64) { self.add_unknown_to_log(); }
-        fn emit_u32(&mut self, _v: u32) { self.add_unknown_to_log(); }
-        fn emit_u16(&mut self, _v: u16) { self.add_unknown_to_log(); }
-        fn emit_u8(&mut self, _v: u8)   { self.add_unknown_to_log(); }
-
-        fn emit_int(&mut self, _v: int) { self.add_unknown_to_log(); }
-        fn emit_i64(&mut self, _v: i64) { self.add_unknown_to_log(); }
-        fn emit_i32(&mut self, _v: i32) { self.add_unknown_to_log(); }
-        fn emit_i16(&mut self, _v: i16) { self.add_unknown_to_log(); }
-        fn emit_i8(&mut self, _v: i8)   { self.add_unknown_to_log(); }
-
-        fn emit_bool(&mut self, _v: bool) { self.add_unknown_to_log(); }
-
-        fn emit_f64(&mut self, _v: f64) { self.add_unknown_to_log(); }
-        fn emit_f32(&mut self, _v: f32) { self.add_unknown_to_log(); }
-        fn emit_float(&mut self, _v: float) { self.add_unknown_to_log(); }
-
-        fn emit_char(&mut self, _v: char) { self.add_unknown_to_log(); }
-        fn emit_str(&mut self, _v: &str) { self.add_unknown_to_log(); }
-
-        fn emit_enum(&mut self, name: &str, f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitEnum(name.to_str()));
-            f(self);
-        }
-
-        fn emit_enum_variant(&mut self,
-                             name: &str,
-                             id: uint,
-                             cnt: uint,
-                             f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitEnumVariant(name.to_str(), id, cnt));
-            f(self);
-        }
-
-        fn emit_enum_variant_arg(&mut self,
-                                 idx: uint,
-                                 f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitEnumVariantArg(idx));
-            f(self);
-        }
-
-        fn emit_enum_struct_variant(&mut self,
-                                    name: &str,
-                                    id: uint,
-                                    cnt: uint,
-                                    f: &fn(&mut TestEncoder)) {
-            self.emit_enum_variant(name, id, cnt, f)
-        }
-
-        fn emit_enum_struct_variant_field(&mut self,
-                                          _name: &str,
-                                          idx: uint,
-                                          f: &fn(&mut TestEncoder)) {
-            self.emit_enum_variant_arg(idx, f)
-        }
-
-        fn emit_struct(&mut self,
-                       name: &str,
-                       len: uint,
-                       f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitStruct (name.to_str(),len));
-            f(self);
-        }
-        fn emit_struct_field(&mut self,
-                             name: &str,
-                             idx: uint,
-                             f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitField (name.to_str(),idx));
-            f(self);
-        }
-
-        fn emit_tuple(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-        fn emit_tuple_arg(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-
-        fn emit_tuple_struct(&mut self,
-                             _name: &str,
-                             _len: uint,
-                             f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-
-        fn emit_tuple_struct_arg(&mut self,
-                                 _idx: uint,
-                                 f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-
-        fn emit_option(&mut self, f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitOption);
-            f(self);
-        }
-        fn emit_option_none(&mut self) {
-            self.add_to_log(CallToEmitOptionNone);
-        }
-        fn emit_option_some(&mut self, f: &fn(&mut TestEncoder)) {
-            self.add_to_log(CallToEmitOptionSome);
-            f(self);
-        }
-
-        fn emit_seq(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-        fn emit_seq_elt(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-
-        fn emit_map(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-        fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-        fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
-            self.add_unknown_to_log();
-            f(self);
-        }
-    }
-
-
-    fn to_call_log<E:Encodable<TestEncoder>>(val: E) -> ~[call] {
-        let mut te = TestEncoder {
-            call_log: @mut ~[]
-        };
-        val.encode(&mut te);
-        copy *te.call_log
-    }
-
-    #[auto_encode]
-    enum Written {
-        Book(uint,uint),
-        Magazine(~str)
-    }
-
-    #[test]
-    fn test_encode_enum() {
-        assert_eq!(
-            to_call_log(Book(34,44)),
-            ~[
-                CallToEmitEnum(~"Written"),
-                CallToEmitEnumVariant(~"Book",0,2),
-                CallToEmitEnumVariantArg(0),
-                CallToEmitUint(34),
-                CallToEmitEnumVariantArg(1),
-                CallToEmitUint(44),
-            ]
-        );
-    }
-
-    pub struct BPos(uint);
-
-    #[auto_encode]
-    pub struct HasPos { pos : BPos }
-
-    #[test]
-    fn test_encode_newtype() {
-        assert_eq!(
-            to_call_log(HasPos { pos:BPos(48) }),
-            ~[
-                CallToEmitStruct(~"HasPos",1),
-                CallToEmitField(~"pos",0),
-                CallToEmitUint(48),
-            ]
-        );
-    }
-
-    #[test]
-    fn test_encode_option() {
-        let mut v = None;
-
-        assert_eq!(
-            to_call_log(v),
-            ~[
-                CallToEmitOption,
-                CallToEmitOptionNone,
-            ]
-        );
-
-        v = Some(54u);
-        assert_eq!(
-            to_call_log(v),
-            ~[
-                CallToEmitOption,
-                CallToEmitOptionSome,
-                CallToEmitUint(54)
-            ]
-        );
-    }
+    cx.span_err(span, "`#[auto_decode]` is deprecated, use `#[deriving(Decodable)]` instead");
+    in_items
 }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 605ba65b51a..01b37a1196c 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -538,3 +538,301 @@ pub fn duplicate_expr(cx: @ext_ctxt, expr: @ast::expr) -> @ast::expr {
     folder.fold_expr(expr)
 }
 
+
+
+// Transitional reexports so qquote can find the paths it is looking for
+mod syntax {
+    pub use ext;
+    pub use parse;
+}
+
+trait ExtCtxtMethods {
+    fn bind_path(&self,
+                 span: span,
+                 ident: ast::ident,
+                 path: @ast::Path,
+                 bounds: @OptVec<ast::TyParamBound>)
+                 -> ast::TyParam;
+    fn expr(&self, span: span, node: ast::expr_) -> @ast::expr;
+    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
+    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
+    fn path_tps(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty])
+                -> @ast::Path;
+    fn path_tps_global(&self,
+                       span: span,
+                       strs: ~[ast::ident],
+                       tps: ~[@ast::Ty])
+                       -> @ast::Path;
+    fn ty_path(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty])
+               -> @ast::Ty;
+    fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat;
+    fn stmt(&self, expr: @ast::expr) -> @ast::stmt;
+    fn lit_str(&self, span: span, s: @~str) -> @ast::expr;
+    fn lit_uint(&self, span: span, i: uint) -> @ast::expr;
+    fn lambda0(&self, blk: ast::blk) -> @ast::expr;
+    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr;
+    fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk;
+    fn expr_blk(&self, expr: @ast::expr) -> ast::blk;
+    fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
+    fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
+    fn expr_var(&self, span: span, var: &str) -> @ast::expr;
+    fn expr_self(&self, span: span) -> @ast::expr;
+    fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident)
+                  -> @ast::expr;
+    fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr])
+                 -> @ast::expr;
+    fn expr_method_call(&self,
+                        span: span,
+                        expr: @ast::expr,
+                        ident: ast::ident,
+                        args: ~[@ast::expr])
+                        -> @ast::expr;
+    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr;
+    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
+                    -> @ast::expr;
+    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr;
+    fn lambda_stmts_1(&self,
+                      span: span,
+                      stmts: ~[@ast::stmt],
+                      ident: ast::ident)
+                      -> @ast::expr;
+}
+
+impl ExtCtxtMethods for @ext_ctxt {
+    fn bind_path(
+        &self,
+        _span: span,
+        ident: ast::ident,
+        path: @ast::Path,
+        bounds: @OptVec<ast::TyParamBound>
+    ) -> ast::TyParam {
+        let bound = ast::TraitTyParamBound(@ast::trait_ref {
+            ref_id: self.next_id(),
+            path: path
+        });
+
+        ast::TyParam {
+            ident: ident,
+            id: self.next_id(),
+            bounds: @bounds.prepend(bound)
+        }
+    }
+
+    fn expr(&self, span: span, node: ast::expr_) -> @ast::expr {
+        @ast::expr {
+            id: self.next_id(),
+            callee_id: self.next_id(),
+            node: node,
+            span: span,
+        }
+    }
+
+    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
+        @ast::Path {
+            span: span,
+            global: false,
+            idents: strs,
+            rp: None,
+            types: ~[]
+        }
+    }
+
+    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
+        @ast::Path {
+            span: span,
+            global: true,
+            idents: strs,
+            rp: None,
+            types: ~[]
+        }
+    }
+
+    fn path_tps(
+        &self,
+        span: span,
+        strs: ~[ast::ident],
+        tps: ~[@ast::Ty]
+    ) -> @ast::Path {
+        @ast::Path {
+            span: span,
+            global: false,
+            idents: strs,
+            rp: None,
+            types: tps
+        }
+    }
+
+    fn path_tps_global(
+        &self,
+        span: span,
+        strs: ~[ast::ident],
+        tps: ~[@ast::Ty]
+    ) -> @ast::Path {
+        @ast::Path {
+            span: span,
+            global: true,
+            idents: strs,
+            rp: None,
+            types: tps
+        }
+    }
+
+    fn ty_path(
+        &self,
+        span: span,
+        strs: ~[ast::ident],
+        tps: ~[@ast::Ty]
+    ) -> @ast::Ty {
+        @ast::Ty {
+            id: self.next_id(),
+            node: ast::ty_path(
+                self.path_tps(span, strs, tps),
+                self.next_id()),
+            span: span,
+        }
+    }
+
+    fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat {
+        @ast::pat {
+            id: self.next_id(),
+            node: ast::pat_ident(
+                ast::bind_by_ref(ast::m_imm),
+                self.path(span, ~[nm]),
+                None),
+            span: span,
+        }
+    }
+
+    fn stmt(&self, expr: @ast::expr) -> @ast::stmt {
+        @codemap::spanned { node: ast::stmt_semi(expr, self.next_id()),
+                       span: expr.span }
+    }
+
+    fn lit_str(&self, span: span, s: @~str) -> @ast::expr {
+        self.expr(
+            span,
+            ast::expr_vstore(
+                self.expr(
+                    span,
+                    ast::expr_lit(
+                        @codemap::spanned { node: ast::lit_str(s),
+                                        span: span})),
+                ast::expr_vstore_uniq))
+    }
+
+    fn lit_uint(&self, span: span, i: uint) -> @ast::expr {
+        self.expr(
+            span,
+            ast::expr_lit(
+                @codemap::spanned { node: ast::lit_uint(i as u64, ast::ty_u),
+                                span: span}))
+    }
+
+    fn lambda0(&self, blk: ast::blk) -> @ast::expr {
+        let ext_cx = *self;
+        let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
+        quote_expr!( || $blk_e )
+    }
+
+    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr {
+        let ext_cx = *self;
+        let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
+        quote_expr!( |$ident| $blk_e )
+    }
+
+    fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk {
+        codemap::spanned {
+            node: ast::blk_ {
+                view_items: ~[],
+                stmts: stmts,
+                expr: None,
+                id: self.next_id(),
+                rules: ast::default_blk,
+            },
+            span: span,
+        }
+    }
+
+    fn expr_blk(&self, expr: @ast::expr) -> ast::blk {
+        codemap::spanned {
+            node: ast::blk_ {
+                view_items: ~[],
+                stmts: ~[],
+                expr: Some(expr),
+                id: self.next_id(),
+                rules: ast::default_blk,
+            },
+            span: expr.span,
+        }
+    }
+
+    fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr {
+        self.expr(span, ast::expr_path(self.path(span, strs)))
+    }
+
+    fn expr_path_global(
+        &self,
+        span: span,
+        strs: ~[ast::ident]
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_path(self.path_global(span, strs)))
+    }
+
+    fn expr_var(&self, span: span, var: &str) -> @ast::expr {
+        self.expr_path(span, ~[self.ident_of(var)])
+    }
+
+    fn expr_self(&self, span: span) -> @ast::expr {
+        self.expr(span, ast::expr_self)
+    }
+
+    fn expr_field(
+        &self,
+        span: span,
+        expr: @ast::expr,
+        ident: ast::ident
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_field(expr, ident, ~[]))
+    }
+
+    fn expr_call(
+        &self,
+        span: span,
+        expr: @ast::expr,
+        args: ~[@ast::expr]
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_call(expr, args, ast::NoSugar))
+    }
+
+    fn expr_method_call(
+        &self,
+        span: span,
+        expr: @ast::expr,
+        ident: ast::ident,
+        args: ~[@ast::expr]
+    ) -> @ast::expr {
+        self.expr(span,
+                  ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar))
+    }
+
+    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr {
+        self.lambda0(self.expr_blk(expr))
+    }
+
+    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
+                    -> @ast::expr {
+        self.lambda1(self.expr_blk(expr), ident)
+    }
+
+    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
+        self.lambda0(self.blk(span, stmts))
+    }
+
+    fn lambda_stmts_1(&self,
+                      span: span,
+                      stmts: ~[@ast::stmt],
+                      ident: ast::ident)
+                      -> @ast::expr {
+        self.lambda1(self.blk(span, stmts), ident)
+    }
+}
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 3be65ecd8db..2e2f382a768 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/*!
+The compiler code necessary for #[deriving(Decodable)]. See
+encodable.rs for more.
+*/
+
 use ast;
 use ast::*;
 use ext::base::ext_ctxt;
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 2078ec9d45c..8a1c3933f51 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -8,6 +8,74 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+/*!
+
+The compiler code necessary to implement the #[deriving(Encodable)]
+(and Decodable, in decodable.rs) extension.  The idea here is that
+type-defining items may be tagged with #[deriving(Encodable,
+Decodable)].
+
+For example, a type like:
+
+    #[deriving(Encodable, Decodable)]
+    struct Node {id: uint}
+
+would generate two implementations like:
+
+impl<S:std::serialize::Encoder> Encodable<S> for Node {
+    fn encode(&self, s: &S) {
+        do s.emit_struct("Node", 1) {
+            s.emit_field("id", 0, || s.emit_uint(self.id))
+        }
+    }
+}
+
+impl<D:Decoder> Decodable for node_id {
+    fn decode(d: &D) -> Node {
+        do d.read_struct("Node", 1) {
+            Node {
+                id: d.read_field(~"x", 0, || decode(d))
+            }
+        }
+    }
+}
+
+Other interesting scenarios are whe the item has type parameters or
+references other non-built-in types.  A type definition like:
+
+    #[deriving(Encodable, Decodable)]
+    struct spanned<T> {node: T, span: span}
+
+would yield functions like:
+
+    impl<
+        S: Encoder,
+        T: Encodable<S>
+    > spanned<T>: Encodable<S> {
+        fn encode<S:Encoder>(s: &S) {
+            do s.emit_rec {
+                s.emit_field("node", 0, || self.node.encode(s));
+                s.emit_field("span", 1, || self.span.encode(s));
+            }
+        }
+    }
+
+    impl<
+        D: Decoder,
+        T: Decodable<D>
+    > spanned<T>: Decodable<D> {
+        fn decode(d: &D) -> spanned<T> {
+            do d.read_rec {
+                {
+                    node: d.read_field(~"node", 0, || decode(d)),
+                    span: d.read_field(~"span", 1, || decode(d)),
+                }
+            }
+        }
+    }
+*/
+
+
 use ast;
 use ast::*;
 use ext::base::ext_ctxt;
@@ -403,3 +471,247 @@ fn expand_deriving_encodable_enum_method(
     // Create the method.
     create_encode_method(cx, span, ~[stmt])
 }
+
+#[cfg(test)]
+mod test {
+    extern mod std;
+    use core::option::{None, Some};
+    use std::serialize::Encodable;
+    use std::serialize::Encoder;
+
+    // just adding the ones I want to test, for now:
+    #[deriving(Eq)]
+    pub enum call {
+        CallToEmitEnum(~str),
+        CallToEmitEnumVariant(~str, uint, uint),
+        CallToEmitEnumVariantArg(uint),
+        CallToEmitUint(uint),
+        CallToEmitNil,
+        CallToEmitStruct(~str,uint),
+        CallToEmitField(~str,uint),
+        CallToEmitOption,
+        CallToEmitOptionNone,
+        CallToEmitOptionSome,
+        // all of the ones I was too lazy to handle:
+        CallToOther
+    }
+    // using `@mut` rather than changing the
+    // type of self in every method of every encoder everywhere.
+    pub struct TestEncoder {call_log : @mut ~[call]}
+
+    pub impl TestEncoder {
+        // these self's should be &mut self's, as well....
+        fn add_to_log (&self, c : call) {
+            self.call_log.push(copy c);
+        }
+        fn add_unknown_to_log (&self) {
+            self.add_to_log (CallToOther)
+        }
+    }
+
+    impl Encoder for TestEncoder {
+        fn emit_nil(&mut self) { self.add_to_log(CallToEmitNil) }
+
+        fn emit_uint(&mut self, v: uint) {
+            self.add_to_log(CallToEmitUint(v));
+        }
+        fn emit_u64(&mut self, _v: u64) { self.add_unknown_to_log(); }
+        fn emit_u32(&mut self, _v: u32) { self.add_unknown_to_log(); }
+        fn emit_u16(&mut self, _v: u16) { self.add_unknown_to_log(); }
+        fn emit_u8(&mut self, _v: u8)   { self.add_unknown_to_log(); }
+
+        fn emit_int(&mut self, _v: int) { self.add_unknown_to_log(); }
+        fn emit_i64(&mut self, _v: i64) { self.add_unknown_to_log(); }
+        fn emit_i32(&mut self, _v: i32) { self.add_unknown_to_log(); }
+        fn emit_i16(&mut self, _v: i16) { self.add_unknown_to_log(); }
+        fn emit_i8(&mut self, _v: i8)   { self.add_unknown_to_log(); }
+
+        fn emit_bool(&mut self, _v: bool) { self.add_unknown_to_log(); }
+
+        fn emit_f64(&mut self, _v: f64) { self.add_unknown_to_log(); }
+        fn emit_f32(&mut self, _v: f32) { self.add_unknown_to_log(); }
+        fn emit_float(&mut self, _v: float) { self.add_unknown_to_log(); }
+
+        fn emit_char(&mut self, _v: char) { self.add_unknown_to_log(); }
+        fn emit_str(&mut self, _v: &str) { self.add_unknown_to_log(); }
+
+        fn emit_enum(&mut self, name: &str, f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitEnum(name.to_str()));
+            f(self);
+        }
+
+        fn emit_enum_variant(&mut self,
+                             name: &str,
+                             id: uint,
+                             cnt: uint,
+                             f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitEnumVariant(name.to_str(), id, cnt));
+            f(self);
+        }
+
+        fn emit_enum_variant_arg(&mut self,
+                                 idx: uint,
+                                 f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitEnumVariantArg(idx));
+            f(self);
+        }
+
+        fn emit_enum_struct_variant(&mut self,
+                                    name: &str,
+                                    id: uint,
+                                    cnt: uint,
+                                    f: &fn(&mut TestEncoder)) {
+            self.emit_enum_variant(name, id, cnt, f)
+        }
+
+        fn emit_enum_struct_variant_field(&mut self,
+                                          _name: &str,
+                                          idx: uint,
+                                          f: &fn(&mut TestEncoder)) {
+            self.emit_enum_variant_arg(idx, f)
+        }
+
+        fn emit_struct(&mut self,
+                       name: &str,
+                       len: uint,
+                       f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitStruct (name.to_str(),len));
+            f(self);
+        }
+        fn emit_struct_field(&mut self,
+                             name: &str,
+                             idx: uint,
+                             f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitField (name.to_str(),idx));
+            f(self);
+        }
+
+        fn emit_tuple(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+        fn emit_tuple_arg(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+
+        fn emit_tuple_struct(&mut self,
+                             _name: &str,
+                             _len: uint,
+                             f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+
+        fn emit_tuple_struct_arg(&mut self,
+                                 _idx: uint,
+                                 f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+
+        fn emit_option(&mut self, f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitOption);
+            f(self);
+        }
+        fn emit_option_none(&mut self) {
+            self.add_to_log(CallToEmitOptionNone);
+        }
+        fn emit_option_some(&mut self, f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitOptionSome);
+            f(self);
+        }
+
+        fn emit_seq(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+        fn emit_seq_elt(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+
+        fn emit_map(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+        fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+        fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
+        }
+    }
+
+
+    fn to_call_log<E:Encodable<TestEncoder>>(val: E) -> ~[call] {
+        let mut te = TestEncoder {
+            call_log: @mut ~[]
+        };
+        val.encode(&mut te);
+        copy *te.call_log
+    }
+
+    #[deriving(Encodable)]
+    enum Written {
+        Book(uint,uint),
+        Magazine(~str)
+    }
+
+    #[test]
+    fn test_encode_enum() {
+        assert_eq!(
+            to_call_log(Book(34,44)),
+            ~[
+                CallToEmitEnum(~"Written"),
+                CallToEmitEnumVariant(~"Book",0,2),
+                CallToEmitEnumVariantArg(0),
+                CallToEmitUint(34),
+                CallToEmitEnumVariantArg(1),
+                CallToEmitUint(44),
+            ]
+        );
+    }
+
+    pub struct BPos(uint);
+
+    #[deriving(Encodable)]
+    pub struct HasPos { pos : BPos }
+
+    #[test]
+    fn test_encode_newtype() {
+        assert_eq!(
+            to_call_log(HasPos { pos:BPos(48) }),
+            ~[
+                CallToEmitStruct(~"HasPos",1),
+                CallToEmitField(~"pos",0),
+                CallToEmitUint(48),
+            ]
+        );
+    }
+
+    #[test]
+    fn test_encode_option() {
+        let mut v = None;
+
+        assert_eq!(
+            to_call_log(v),
+            ~[
+                CallToEmitOption,
+                CallToEmitOptionNone,
+            ]
+        );
+
+        v = Some(54u);
+        assert_eq!(
+            to_call_log(v),
+            ~[
+                CallToEmitOption,
+                CallToEmitOptionSome,
+                CallToEmitUint(54)
+            ]
+        );
+    }
+}
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index ba1f4e3ebb2..99785d55761 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -8,8 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/// The compiler code necessary to implement the #[deriving(Eq)] and
-/// #[deriving(IterBytes)] extensions.
+/*!
+The compiler code necessary to implement the #[deriving] extensions.
+
+
+FIXME (#2810)--Hygiene. Search for "__" strings (in other files too).
+We also assume "std" is the standard library, and "core" is the core
+library.
+
+*/
 
 use ast;
 use ast::{Ty, enum_def, expr, ident, item, Generics, meta_item, struct_def};
@@ -203,8 +210,6 @@ pub fn create_derived_impl(cx: @ext_ctxt,
      *
      * where B1, B2, ... are the bounds given by `bounds_paths`.
      *
-     * FIXME(#5090): Remove code duplication between this and the
-     * code in auto_encode.rs
      */
 
     // Copy the lifetimes
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index a98e93eec84..fb3622396c9 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -20,8 +20,7 @@ use core::prelude::*;
 use core::old_iter;
 use core::old_iter::BaseIter;
 
-#[auto_encode]
-#[auto_decode]
+#[deriving(Encodable, Decodable)]
 pub enum OptVec<T> {
     Empty,
     Vec(~[T])
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index fe479ab81f7..36f241b6427 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -18,9 +18,7 @@ use core::cmp::Equiv;
 use core::hashmap::HashSet;
 use core::to_bytes;
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Encodable, Decodable, Eq)]
 pub enum binop {
     PLUS,
     MINUS,
@@ -34,9 +32,7 @@ pub enum binop {
     SHR,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Encodable, Decodable, Eq)]
 pub enum Token {
     /* Expression-operator symbols. */
     EQ,
@@ -97,9 +93,7 @@ pub enum Token {
     EOF,
 }
 
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
+#[deriving(Encodable, Decodable, Eq)]
 /// For interpolation during macro expansion.
 pub enum nonterminal {
     nt_item(@ast::item),
diff --git a/src/test/compile-fail/deprecated-auto-code.rs b/src/test/compile-fail/deprecated-auto-code.rs
new file mode 100644
index 00000000000..1f7cbfe9807
--- /dev/null
+++ b/src/test/compile-fail/deprecated-auto-code.rs
@@ -0,0 +1,15 @@
+// Copyright 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.
+
+#[auto_encode] //~ ERROR: `#[auto_encode]` is deprecated
+#[auto_decode] //~ ERROR: `#[auto_decode]` is deprecated
+struct A;
+
+fn main() {}
\ No newline at end of file