about summary refs log tree commit diff
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2012-10-07 16:33:20 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2012-10-07 17:20:19 -0700
commiteb626e71199d1d89a0242043f096d89941fa2ec7 (patch)
tree04ca276c78ac129c630c12922985a438e0a8a489
parent91b7a9a529cad2db9503fa469b2e2ce7a86257e6 (diff)
downloadrust-eb626e71199d1d89a0242043f096d89941fa2ec7.tar.gz
rust-eb626e71199d1d89a0242043f096d89941fa2ec7.zip
Remove the old serializers (needs snapshot)
-rw-r--r--src/libstd/ebml.rs394
-rw-r--r--src/libstd/ebml2.rs645
-rw-r--r--src/libstd/json.rs10
-rw-r--r--src/libstd/prettyprint.rs168
-rw-r--r--src/libstd/prettyprint2.rs177
-rw-r--r--src/libstd/serialization.rs614
-rw-r--r--src/libstd/serialization2.rs558
-rw-r--r--src/libsyntax/ast.rs178
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/ext/auto_serialize.rs1685
-rw-r--r--src/libsyntax/ext/auto_serialize2.rs114
-rw-r--r--src/libsyntax/ext/base.rs12
-rw-r--r--src/libsyntax/parse/token.rs6
-rw-r--r--src/libsyntax/syntax.rc2
-rw-r--r--src/rustc/metadata/decoder.rs245
-rw-r--r--src/rustc/metadata/encoder.rs80
-rw-r--r--src/rustc/middle/astencode.rs91
-rw-r--r--src/rustc/middle/freevars.rs2
-rw-r--r--src/rustc/middle/ty.rs16
-rw-r--r--src/rustc/middle/typeck.rs4
-rw-r--r--src/test/run-pass/auto_serialize.rs (renamed from src/test/run-pass/auto_serialize2.rs)42
21 files changed, 2177 insertions, 2868 deletions
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 3df5a70a0c1..79e491e309b 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -1,21 +1,35 @@
 #[forbid(deprecated_mode)];
+use serialization;
+
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
 // cursor model. See the specification here:
 //     http://www.matroska.org/technical/specs/rfc/index.html
-use core::Option;
-use option::{Some, None};
 
-type EbmlTag = {id: uint, size: uint};
+struct EbmlTag {
+    id: uint,
+    size: uint,
+}
 
-type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint};
+struct EbmlState {
+    ebml_tag: EbmlTag,
+    tag_pos: uint,
+    data_pos: uint,
+}
 
 // FIXME (#2739): When we have module renaming, make "reader" and "writer"
 // separate modules within this file.
 
 // ebml reading
-pub type Doc = {data: @~[u8], start: uint, end: uint};
+struct Doc {
+    data: @~[u8],
+    start: uint,
+    end: uint,
+}
 
-type TaggedDoc = {tag: uint, doc: Doc};
+struct TaggedDoc {
+    tag: uint,
+    doc: Doc,
+}
 
 impl Doc: ops::Index<uint,Doc> {
     pure fn index(tag: uint) -> Doc {
@@ -49,15 +63,17 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
 }
 
 pub fn Doc(data: @~[u8]) -> Doc {
-    return {data: data, start: 0u, end: vec::len::<u8>(*data)};
+    Doc { data: data, start: 0u, end: vec::len::<u8>(*data) }
 }
 
 pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
     let elt_tag = vuint_at(*data, start);
     let elt_size = vuint_at(*data, elt_tag.next);
     let end = elt_size.next + elt_size.val;
-    return {tag: elt_tag.val,
-         doc: {data: data, start: elt_size.next, end: end}};
+    TaggedDoc {
+        tag: elt_tag.val,
+        doc: Doc { data: data, start: elt_size.next, end: end }
+    }
 }
 
 pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
@@ -67,19 +83,15 @@ pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
         let elt_size = vuint_at(*d.data, elt_tag.next);
         pos = elt_size.next + elt_size.val;
         if elt_tag.val == tg {
-            return Some::<Doc>({
-                data: d.data,
-                start: elt_size.next,
-                end: pos
-            });
+            return Some(Doc { data: d.data, start: elt_size.next, end: pos });
         }
     }
-    return None::<Doc>;
+    None
 }
 
 pub fn get_doc(d: Doc, tg: uint) -> Doc {
     match maybe_get_doc(d, tg) {
-      Some(d) => return d,
+      Some(d) => d,
       None => {
         error!("failed to find block with tag %u", tg);
         fail;
@@ -93,7 +105,8 @@ pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
         let elt_tag = vuint_at(*d.data, pos);
         let elt_size = vuint_at(*d.data, elt_tag.next);
         pos = elt_size.next + elt_size.val;
-        if !it(elt_tag.val, {data: d.data, start: elt_size.next, end: pos}) {
+        let doc = Doc { data: d.data, start: elt_size.next, end: pos };
+        if !it(elt_tag.val, doc) {
             break;
         }
     }
@@ -106,7 +119,8 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
         let elt_size = vuint_at(*d.data, elt_tag.next);
         pos = elt_size.next + elt_size.val;
         if elt_tag.val == tg {
-            if !it({data: d.data, start: elt_size.next, end: pos}) {
+            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
+            if !it(doc) {
                 break;
             }
         }
@@ -116,29 +130,29 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
 pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
 
 pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
-    return f(vec::view(*d.data, d.start, d.end));
+    f(vec::view(*d.data, d.start, d.end))
 }
 
-pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); }
+pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) }
 
 pub fn doc_as_u8(d: Doc) -> u8 {
     assert d.end == d.start + 1u;
-    return (*d.data)[d.start];
+    (*d.data)[d.start]
 }
 
 pub fn doc_as_u16(d: Doc) -> u16 {
     assert d.end == d.start + 2u;
-    return io::u64_from_be_bytes(*d.data, d.start, 2u) as u16;
+    io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
 }
 
 pub fn doc_as_u32(d: Doc) -> u32 {
     assert d.end == d.start + 4u;
-    return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32;
+    io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
 }
 
 pub fn doc_as_u64(d: Doc) -> u64 {
     assert d.end == d.start + 8u;
-    return io::u64_from_be_bytes(*d.data, d.start, 8u);
+    io::u64_from_be_bytes(*d.data, d.start, 8u)
 }
 
 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
@@ -147,10 +161,9 @@ pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
 
 // ebml writing
-type Writer_ = {writer: io::Writer, mut size_positions: ~[uint]};
-
-pub enum Writer {
-    Writer_(Writer_)
+struct Serializer {
+    writer: io::Writer,
+    priv mut size_positions: ~[uint],
 }
 
 fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
@@ -173,13 +186,13 @@ fn write_vuint(w: io::Writer, n: uint) {
     fail fmt!("vint to write too big: %?", n);
 }
 
-pub fn Writer(w: io::Writer) -> Writer {
+pub fn Serializer(w: io::Writer) -> Serializer {
     let size_positions: ~[uint] = ~[];
-    return Writer_({writer: w, mut size_positions: size_positions});
+    Serializer { writer: w, mut size_positions: size_positions }
 }
 
 // FIXME (#2741): Provide a function to write the standard ebml header.
-impl Writer {
+impl Serializer {
     fn start_tag(tag_id: uint) {
         debug!("Start tag %u", tag_id);
 
@@ -295,12 +308,7 @@ enum EbmlSerializerTag {
     EsLabel // Used only when debugging
 }
 
-trait SerializerPriv {
-    fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint);
-    fn _emit_label(label: &str);
-}
-
-impl ebml::Writer: SerializerPriv {
+priv impl Serializer {
     // used internally to emit things like the vector length and so on
     fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) {
         assert v <= 0xFFFF_FFFF_u;
@@ -318,89 +326,123 @@ impl ebml::Writer: SerializerPriv {
     }
 }
 
-impl ebml::Writer {
-    fn emit_opaque(f: fn()) {
+impl Serializer {
+    fn emit_opaque(&self, f: fn()) {
         do self.wr_tag(EsOpaque as uint) {
             f()
         }
     }
 }
 
-impl ebml::Writer: serialization::Serializer {
-    fn emit_nil() {}
+impl Serializer: serialization::Serializer {
+    fn emit_nil(&self) {}
 
-    fn emit_uint(v: uint) { self.wr_tagged_u64(EsUint as uint, v as u64); }
-    fn emit_u64(v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
-    fn emit_u32(v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
-    fn emit_u16(v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
-    fn emit_u8(v: u8)   { self.wr_tagged_u8 (EsU8  as uint, v); }
+    fn emit_uint(&self, v: uint) {
+        self.wr_tagged_u64(EsUint as uint, v as u64);
+    }
+    fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
+    fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
+    fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
+    fn emit_u8(&self, v: u8)   { self.wr_tagged_u8 (EsU8  as uint, v); }
 
-    fn emit_int(v: int) { self.wr_tagged_i64(EsInt as uint, v as i64); }
-    fn emit_i64(v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
-    fn emit_i32(v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
-    fn emit_i16(v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
-    fn emit_i8(v: i8)   { self.wr_tagged_i8 (EsI8  as uint, v); }
+    fn emit_int(&self, v: int) {
+        self.wr_tagged_i64(EsInt as uint, v as i64);
+    }
+    fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
+    fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
+    fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
+    fn emit_i8(&self, v: i8)   { self.wr_tagged_i8 (EsI8  as uint, v); }
 
-    fn emit_bool(v: bool) { self.wr_tagged_u8(EsBool as uint, v as u8) }
+    fn emit_bool(&self, v: bool) {
+        self.wr_tagged_u8(EsBool as uint, v as u8)
+    }
 
     // FIXME (#2742): implement these
-    fn emit_f64(_v: f64) { fail ~"Unimplemented: serializing an f64"; }
-    fn emit_f32(_v: f32) { fail ~"Unimplemented: serializing an f32"; }
-    fn emit_float(_v: float) { fail ~"Unimplemented: serializing a float"; }
+    fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; }
+    fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; }
+    fn emit_float(&self, _v: float) {
+        fail ~"Unimplemented: serializing a float";
+    }
+
+    fn emit_char(&self, _v: char) {
+        fail ~"Unimplemented: serializing a char";
+    }
 
-    fn emit_str(v: &str) { self.wr_tagged_str(EsStr as uint, v) }
+    fn emit_borrowed_str(&self, v: &str) {
+        self.wr_tagged_str(EsStr as uint, v)
+    }
 
-    fn emit_enum(name: &str, f: fn()) {
+    fn emit_owned_str(&self, v: &str) {
+        self.emit_borrowed_str(v)
+    }
+
+    fn emit_managed_str(&self, v: &str) {
+        self.emit_borrowed_str(v)
+    }
+
+    fn emit_borrowed(&self, f: fn()) { f() }
+    fn emit_owned(&self, f: fn()) { f() }
+    fn emit_managed(&self, f: fn()) { f() }
+
+    fn emit_enum(&self, name: &str, f: fn()) {
         self._emit_label(name);
         self.wr_tag(EsEnum as uint, f)
     }
-    fn emit_enum_variant(_v_name: &str, v_id: uint, _cnt: uint, f: fn()) {
+    fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint,
+                         f: fn()) {
         self._emit_tagged_uint(EsEnumVid, v_id);
         self.wr_tag(EsEnumBody as uint, f)
     }
-    fn emit_enum_variant_arg(_idx: uint, f: fn()) { f() }
+    fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
 
-    fn emit_vec(len: uint, f: fn()) {
+    fn emit_borrowed_vec(&self, len: uint, f: fn()) {
         do self.wr_tag(EsVec as uint) {
             self._emit_tagged_uint(EsVecLen, len);
             f()
         }
     }
 
-    fn emit_vec_elt(_idx: uint, f: fn()) {
+    fn emit_owned_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+
+    fn emit_managed_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+
+    fn emit_vec_elt(&self, _idx: uint, f: fn()) {
         self.wr_tag(EsVecElt as uint, f)
     }
 
-    fn emit_box(f: fn()) { f() }
-    fn emit_uniq(f: fn()) { f() }
-    fn emit_rec(f: fn()) { f() }
-    fn emit_rec_field(f_name: &str, _f_idx: uint, f: fn()) {
-        self._emit_label(f_name);
+    fn emit_rec(&self, f: fn()) { f() }
+    fn emit_struct(&self, _name: &str, f: fn()) { f() }
+    fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
+        self._emit_label(name);
         f()
     }
-    fn emit_tup(_sz: uint, f: fn()) { f() }
-    fn emit_tup_elt(_idx: uint, f: fn()) { f() }
-}
 
-type EbmlDeserializer_ = {mut parent: ebml::Doc,
-                          mut pos: uint};
+    fn emit_tup(&self, _len: uint, f: fn()) { f() }
+    fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
+}
 
-pub enum EbmlDeserializer {
-    EbmlDeserializer_(EbmlDeserializer_)
+struct Deserializer {
+    priv mut parent: Doc,
+    priv mut pos: uint,
 }
 
-pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer {
-    EbmlDeserializer_({mut parent: d, mut pos: d.start})
+pub fn Deserializer(d: Doc) -> Deserializer {
+    Deserializer { mut parent: d, mut pos: d.start }
 }
 
-priv impl EbmlDeserializer {
+priv impl Deserializer {
     fn _check_label(lbl: &str) {
         if self.pos < self.parent.end {
-            let {tag: r_tag, doc: r_doc} =
-                ebml::doc_at(self.parent.data, self.pos);
+            let TaggedDoc { tag: r_tag, doc: r_doc } =
+                doc_at(self.parent.data, self.pos);
+
             if r_tag == (EsLabel as uint) {
                 self.pos = r_doc.end;
-                let str = ebml::doc_as_str(r_doc);
+                let str = doc_as_str(r_doc);
                 if lbl != str {
                     fail fmt!("Expected label %s but found %s", lbl, str);
                 }
@@ -408,13 +450,13 @@ priv impl EbmlDeserializer {
         }
     }
 
-    fn next_doc(exp_tag: EbmlSerializerTag) -> ebml::Doc {
+    fn next_doc(exp_tag: EbmlSerializerTag) -> Doc {
         debug!(". next_doc(exp_tag=%?)", exp_tag);
         if self.pos >= self.parent.end {
             fail ~"no more documents in current node!";
         }
-        let {tag: r_tag, doc: r_doc} =
-            ebml::doc_at(self.parent.data, self.pos);
+        let TaggedDoc { tag: r_tag, doc: r_doc } =
+            doc_at(self.parent.data, self.pos);
         debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
                copy self.parent.start, copy self.parent.end,
                copy self.pos, r_tag, r_doc.start, r_doc.end);
@@ -427,10 +469,10 @@ priv impl EbmlDeserializer {
                       r_doc.end, self.parent.end);
         }
         self.pos = r_doc.end;
-        return r_doc;
+        r_doc
     }
 
-    fn push_doc<T>(d: ebml::Doc, f: fn() -> T) -> T{
+    fn push_doc<T>(d: Doc, f: fn() -> T) -> T{
         let old_parent = self.parent;
         let old_pos = self.pos;
         self.parent = d;
@@ -442,63 +484,76 @@ priv impl EbmlDeserializer {
     }
 
     fn _next_uint(exp_tag: EbmlSerializerTag) -> uint {
-        let r = ebml::doc_as_u32(self.next_doc(exp_tag));
+        let r = doc_as_u32(self.next_doc(exp_tag));
         debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
-        return r as uint;
+        r as uint
     }
 }
 
-impl EbmlDeserializer {
-    fn read_opaque<R>(op: fn(ebml::Doc) -> R) -> R {
+impl Deserializer {
+    fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R {
         do self.push_doc(self.next_doc(EsOpaque)) {
             op(copy self.parent)
         }
     }
 }
 
-impl EbmlDeserializer: serialization::Deserializer {
-    fn read_nil() -> () { () }
+impl Deserializer: serialization::Deserializer {
+    fn read_nil(&self) -> () { () }
 
-    fn read_u64() -> u64 { ebml::doc_as_u64(self.next_doc(EsU64)) }
-    fn read_u32() -> u32 { ebml::doc_as_u32(self.next_doc(EsU32)) }
-    fn read_u16() -> u16 { ebml::doc_as_u16(self.next_doc(EsU16)) }
-    fn read_u8 () -> u8  { ebml::doc_as_u8 (self.next_doc(EsU8 )) }
-    fn read_uint() -> uint {
-        let v = ebml::doc_as_u64(self.next_doc(EsUint));
+    fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
+    fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
+    fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
+    fn read_u8 (&self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
+    fn read_uint(&self) -> uint {
+        let v = doc_as_u64(self.next_doc(EsUint));
         if v > (core::uint::max_value as u64) {
             fail fmt!("uint %? too large for this architecture", v);
         }
-        return v as uint;
+        v as uint
     }
 
-    fn read_i64() -> i64 { ebml::doc_as_u64(self.next_doc(EsI64)) as i64 }
-    fn read_i32() -> i32 { ebml::doc_as_u32(self.next_doc(EsI32)) as i32 }
-    fn read_i16() -> i16 { ebml::doc_as_u16(self.next_doc(EsI16)) as i16 }
-    fn read_i8 () -> i8  { ebml::doc_as_u8 (self.next_doc(EsI8 )) as i8  }
-    fn read_int() -> int {
-        let v = ebml::doc_as_u64(self.next_doc(EsInt)) as i64;
+    fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 }
+    fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 }
+    fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 }
+    fn read_i8 (&self) -> i8  { doc_as_u8 (self.next_doc(EsI8 )) as i8  }
+    fn read_int(&self) -> int {
+        let v = doc_as_u64(self.next_doc(EsInt)) as i64;
         if v > (int::max_value as i64) || v < (int::min_value as i64) {
             fail fmt!("int %? out of range for this architecture", v);
         }
-        return v as int;
+        v as int
     }
 
-    fn read_bool() -> bool { ebml::doc_as_u8(self.next_doc(EsBool)) as bool }
+    fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool }
+
+    fn read_f64(&self) -> f64 { fail ~"read_f64()"; }
+    fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
+    fn read_float(&self) -> float { fail ~"read_float()"; }
 
-    fn read_f64() -> f64 { fail ~"read_f64()"; }
-    fn read_f32() -> f32 { fail ~"read_f32()"; }
-    fn read_float() -> float { fail ~"read_float()"; }
+    fn read_char(&self) -> char { fail ~"read_char()"; }
 
-    fn read_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) }
+    fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
+    fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
 
     // Compound types:
-    fn read_enum<T>(name: &str, f: fn() -> T) -> T {
+    fn read_owned<T>(&self, f: fn() -> T) -> T {
+        debug!("read_owned()");
+        f()
+    }
+
+    fn read_managed<T>(&self, f: fn() -> T) -> T {
+        debug!("read_managed()");
+        f()
+    }
+
+    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
         debug!("read_enum(%s)", name);
         self._check_label(name);
         self.push_doc(self.next_doc(EsEnum), f)
     }
 
-    fn read_enum_variant<T>(f: fn(uint) -> T) -> T {
+    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
         debug!("read_enum_variant()");
         let idx = self._next_uint(EsEnumVid);
         debug!("  idx=%u", idx);
@@ -507,13 +562,13 @@ impl EbmlDeserializer: serialization::Deserializer {
         }
     }
 
-    fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T {
+    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
         debug!("read_enum_variant_arg(idx=%u)", idx);
         f()
     }
 
-    fn read_vec<T>(f: fn(uint) -> T) -> T {
-        debug!("read_vec()");
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_owned_vec()");
         do self.push_doc(self.next_doc(EsVec)) {
             let len = self._next_uint(EsVecLen);
             debug!("  len=%u", len);
@@ -521,104 +576,69 @@ impl EbmlDeserializer: serialization::Deserializer {
         }
     }
 
-    fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T {
-        debug!("read_vec_elt(idx=%u)", idx);
-        self.push_doc(self.next_doc(EsVecElt), f)
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_managed_vec()");
+        do self.push_doc(self.next_doc(EsVec)) {
+            let len = self._next_uint(EsVecLen);
+            debug!("  len=%u", len);
+            f(len)
+        }
     }
 
-    fn read_box<T>(f: fn() -> T) -> T {
-        debug!("read_box()");
-        f()
+    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
+        debug!("read_vec_elt(idx=%u)", idx);
+        self.push_doc(self.next_doc(EsVecElt), f)
     }
 
-    fn read_uniq<T>(f: fn() -> T) -> T {
-        debug!("read_uniq()");
+    fn read_rec<T>(&self, f: fn() -> T) -> T {
+        debug!("read_rec()");
         f()
     }
 
-    fn read_rec<T>(f: fn() -> T) -> T {
-        debug!("read_rec()");
+    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
+        debug!("read_struct(name=%s)", name);
         f()
     }
 
-    fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T {
-        debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
-        self._check_label(f_name);
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
+        debug!("read_field(name=%s, idx=%u)", name, idx);
+        self._check_label(name);
         f()
     }
 
-    fn read_tup<T>(sz: uint, f: fn() -> T) -> T {
-        debug!("read_tup(sz=%u)", sz);
+    fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
+        debug!("read_tup(len=%u)", len);
         f()
     }
 
-    fn read_tup_elt<T>(idx: uint, f: fn() -> T) -> T {
+    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
         debug!("read_tup_elt(idx=%u)", idx);
         f()
     }
 }
 
-
 // ___________________________________________________________________________
 // Testing
 
-#[test]
-fn test_option_int() {
-    fn serialize_1<S: serialization::Serializer>(s: &S, v: int) {
-        s.emit_i64(v as i64);
-    }
-
-    fn serialize_0<S: serialization::Serializer>(s: &S, v: Option<int>) {
-        do s.emit_enum(~"core::option::t") {
-            match v {
-              None => s.emit_enum_variant(
-                  ~"core::option::None", 0u, 0u, || { } ),
-              Some(v0) => {
-                do s.emit_enum_variant(~"core::option::some", 1u, 1u) {
-                    s.emit_enum_variant_arg(0u, || serialize_1(s, v0));
-                }
-              }
-            }
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn test_option_int() {
+        fn test_v(v: Option<int>) {
+            debug!("v == %?", v);
+            let bytes = do io::with_bytes_writer |wr| {
+                let ebml_w = Serializer(wr);
+                v.serialize(&ebml_w)
+            };
+            let ebml_doc = Doc(@bytes);
+            let deser = Deserializer(ebml_doc);
+            let v1 = serialization::deserialize(&deser);
+            debug!("v1 == %?", v1);
+            assert v == v1;
         }
-    }
 
-    fn deserialize_1<S: serialization::Deserializer>(s: &S) -> int {
-        s.read_i64() as int
-    }
-
-    fn deserialize_0<S: serialization::Deserializer>(s: &S) -> Option<int> {
-        do s.read_enum(~"core::option::t") {
-            do s.read_enum_variant |i| {
-                match i {
-                  0 => None,
-                  1 => {
-                    let v0 = do s.read_enum_variant_arg(0u) {
-                        deserialize_1(s)
-                    };
-                    Some(v0)
-                  }
-                  _ => {
-                    fail #fmt("deserialize_0: unexpected variant %u", i);
-                  }
-                }
-            }
-        }
+        test_v(Some(22));
+        test_v(None);
+        test_v(Some(3));
     }
-
-    fn test_v(v: Option<int>) {
-        debug!("v == %?", v);
-        let bytes = do io::with_bytes_writer |wr| {
-            let ebml_w = ebml::Writer(wr);
-            serialize_0(&ebml_w, v);
-        };
-        let ebml_doc = ebml::Doc(@bytes);
-        let deser = ebml_deserializer(ebml_doc);
-        let v1 = deserialize_0(&deser);
-        debug!("v1 == %?", v1);
-        assert v == v1;
-    }
-
-    test_v(Some(22));
-    test_v(None);
-    test_v(Some(3));
 }
diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs
index f88aad1ac63..f5410233c92 100644
--- a/src/libstd/ebml2.rs
+++ b/src/libstd/ebml2.rs
@@ -1,644 +1 @@
-#[forbid(deprecated_mode)];
-use serialization2;
-
-// Simple Extensible Binary Markup Language (ebml) reader and writer on a
-// cursor model. See the specification here:
-//     http://www.matroska.org/technical/specs/rfc/index.html
-
-struct EbmlTag {
-    id: uint,
-    size: uint,
-}
-
-struct EbmlState {
-    ebml_tag: EbmlTag,
-    tag_pos: uint,
-    data_pos: uint,
-}
-
-// FIXME (#2739): When we have module renaming, make "reader" and "writer"
-// separate modules within this file.
-
-// ebml reading
-struct Doc {
-    data: @~[u8],
-    start: uint,
-    end: uint,
-}
-
-struct TaggedDoc {
-    tag: uint,
-    doc: Doc,
-}
-
-impl Doc: ops::Index<uint,Doc> {
-    pure fn index(tag: uint) -> Doc {
-        unsafe {
-            get_doc(self, tag)
-        }
-    }
-}
-
-fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
-    let a = data[start];
-    if a & 0x80u8 != 0u8 {
-        return {val: (a & 0x7fu8) as uint, next: start + 1u};
-    }
-    if a & 0x40u8 != 0u8 {
-        return {val: ((a & 0x3fu8) as uint) << 8u |
-                 (data[start + 1u] as uint),
-             next: start + 2u};
-    } else if a & 0x20u8 != 0u8 {
-        return {val: ((a & 0x1fu8) as uint) << 16u |
-                 (data[start + 1u] as uint) << 8u |
-                 (data[start + 2u] as uint),
-             next: start + 3u};
-    } else if a & 0x10u8 != 0u8 {
-        return {val: ((a & 0x0fu8) as uint) << 24u |
-                 (data[start + 1u] as uint) << 16u |
-                 (data[start + 2u] as uint) << 8u |
-                 (data[start + 3u] as uint),
-             next: start + 4u};
-    } else { error!("vint too big"); fail; }
-}
-
-pub fn Doc(data: @~[u8]) -> Doc {
-    Doc { data: data, start: 0u, end: vec::len::<u8>(*data) }
-}
-
-pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
-    let elt_tag = vuint_at(*data, start);
-    let elt_size = vuint_at(*data, elt_tag.next);
-    let end = elt_size.next + elt_size.val;
-    TaggedDoc {
-        tag: elt_tag.val,
-        doc: Doc { data: data, start: elt_size.next, end: end }
-    }
-}
-
-pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = vuint_at(*d.data, pos);
-        let elt_size = vuint_at(*d.data, elt_tag.next);
-        pos = elt_size.next + elt_size.val;
-        if elt_tag.val == tg {
-            return Some(Doc { data: d.data, start: elt_size.next, end: pos });
-        }
-    }
-    None
-}
-
-pub fn get_doc(d: Doc, tg: uint) -> Doc {
-    match maybe_get_doc(d, tg) {
-      Some(d) => d,
-      None => {
-        error!("failed to find block with tag %u", tg);
-        fail;
-      }
-    }
-}
-
-pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = vuint_at(*d.data, pos);
-        let elt_size = vuint_at(*d.data, elt_tag.next);
-        pos = elt_size.next + elt_size.val;
-        let doc = Doc { data: d.data, start: elt_size.next, end: pos };
-        if !it(elt_tag.val, doc) {
-            break;
-        }
-    }
-}
-
-pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
-    let mut pos = d.start;
-    while pos < d.end {
-        let elt_tag = vuint_at(*d.data, pos);
-        let elt_size = vuint_at(*d.data, elt_tag.next);
-        pos = elt_size.next + elt_size.val;
-        if elt_tag.val == tg {
-            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
-            if !it(doc) {
-                break;
-            }
-        }
-    }
-}
-
-pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
-
-pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
-    f(vec::view(*d.data, d.start, d.end))
-}
-
-pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) }
-
-pub fn doc_as_u8(d: Doc) -> u8 {
-    assert d.end == d.start + 1u;
-    (*d.data)[d.start]
-}
-
-pub fn doc_as_u16(d: Doc) -> u16 {
-    assert d.end == d.start + 2u;
-    io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
-}
-
-pub fn doc_as_u32(d: Doc) -> u32 {
-    assert d.end == d.start + 4u;
-    io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
-}
-
-pub fn doc_as_u64(d: Doc) -> u64 {
-    assert d.end == d.start + 8u;
-    io::u64_from_be_bytes(*d.data, d.start, 8u)
-}
-
-pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
-pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
-pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
-pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
-
-// ebml writing
-struct Serializer {
-    writer: io::Writer,
-    priv mut size_positions: ~[uint],
-}
-
-fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
-    match size {
-      1u => w.write(&[0x80u8 | (n as u8)]),
-      2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
-      3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
-                      n as u8]),
-      4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
-                      (n >> 8_u) as u8, n as u8]),
-      _ => fail fmt!("vint to write too big: %?", n)
-    };
-}
-
-fn write_vuint(w: io::Writer, n: uint) {
-    if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
-    if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
-    if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
-    if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
-    fail fmt!("vint to write too big: %?", n);
-}
-
-pub fn Serializer(w: io::Writer) -> Serializer {
-    let size_positions: ~[uint] = ~[];
-    Serializer { writer: w, mut size_positions: size_positions }
-}
-
-// FIXME (#2741): Provide a function to write the standard ebml header.
-impl Serializer {
-    fn start_tag(tag_id: uint) {
-        debug!("Start tag %u", tag_id);
-
-        // Write the enum ID:
-        write_vuint(self.writer, tag_id);
-
-        // Write a placeholder four-byte size.
-        self.size_positions.push(self.writer.tell());
-        let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
-        self.writer.write(zeroes);
-    }
-
-    fn end_tag() {
-        let last_size_pos = self.size_positions.pop();
-        let cur_pos = self.writer.tell();
-        self.writer.seek(last_size_pos as int, io::SeekSet);
-        let size = (cur_pos - last_size_pos - 4u);
-        write_sized_vuint(self.writer, size, 4u);
-        self.writer.seek(cur_pos as int, io::SeekSet);
-
-        debug!("End tag (size = %u)", size);
-    }
-
-    fn wr_tag(tag_id: uint, blk: fn()) {
-        self.start_tag(tag_id);
-        blk();
-        self.end_tag();
-    }
-
-    fn wr_tagged_bytes(tag_id: uint, b: &[u8]) {
-        write_vuint(self.writer, tag_id);
-        write_vuint(self.writer, vec::len(b));
-        self.writer.write(b);
-    }
-
-    fn wr_tagged_u64(tag_id: uint, v: u64) {
-        do io::u64_to_be_bytes(v, 8u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_u32(tag_id: uint, v: u32) {
-        do io::u64_to_be_bytes(v as u64, 4u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_u16(tag_id: uint, v: u16) {
-        do io::u64_to_be_bytes(v as u64, 2u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_u8(tag_id: uint, v: u8) {
-        self.wr_tagged_bytes(tag_id, &[v]);
-    }
-
-    fn wr_tagged_i64(tag_id: uint, v: i64) {
-        do io::u64_to_be_bytes(v as u64, 8u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_i32(tag_id: uint, v: i32) {
-        do io::u64_to_be_bytes(v as u64, 4u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_i16(tag_id: uint, v: i16) {
-        do io::u64_to_be_bytes(v as u64, 2u) |v| {
-            self.wr_tagged_bytes(tag_id, v);
-        }
-    }
-
-    fn wr_tagged_i8(tag_id: uint, v: i8) {
-        self.wr_tagged_bytes(tag_id, &[v as u8]);
-    }
-
-    fn wr_tagged_str(tag_id: uint, v: &str) {
-        str::byte_slice(v, |b| self.wr_tagged_bytes(tag_id, b));
-    }
-
-    fn wr_bytes(b: &[u8]) {
-        debug!("Write %u bytes", vec::len(b));
-        self.writer.write(b);
-    }
-
-    fn wr_str(s: &str) {
-        debug!("Write str: %?", s);
-        self.writer.write(str::to_bytes(s));
-    }
-}
-
-// FIXME (#2743): optionally perform "relaxations" on end_tag to more
-// efficiently encode sizes; this is a fixed point iteration
-
-// Set to true to generate more debugging in EBML serialization.
-// Totally lame approach.
-const debug: bool = false;
-
-enum EbmlSerializerTag {
-    EsUint, EsU64, EsU32, EsU16, EsU8,
-    EsInt, EsI64, EsI32, EsI16, EsI8,
-    EsBool,
-    EsStr,
-    EsF64, EsF32, EsFloat,
-    EsEnum, EsEnumVid, EsEnumBody,
-    EsVec, EsVecLen, EsVecElt,
-
-    EsOpaque,
-
-    EsLabel // Used only when debugging
-}
-
-priv impl Serializer {
-    // used internally to emit things like the vector length and so on
-    fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) {
-        assert v <= 0xFFFF_FFFF_u;
-        self.wr_tagged_u32(t as uint, v as u32);
-    }
-
-    fn _emit_label(label: &str) {
-        // There are various strings that we have access to, such as
-        // the name of a record field, which do not actually appear in
-        // the serialized EBML (normally).  This is just for
-        // efficiency.  When debugging, though, we can emit such
-        // labels and then they will be checked by deserializer to
-        // try and check failures more quickly.
-        if debug { self.wr_tagged_str(EsLabel as uint, label) }
-    }
-}
-
-impl Serializer {
-    fn emit_opaque(&self, f: fn()) {
-        do self.wr_tag(EsOpaque as uint) {
-            f()
-        }
-    }
-}
-
-impl Serializer: serialization2::Serializer {
-    fn emit_nil(&self) {}
-
-    fn emit_uint(&self, v: uint) {
-        self.wr_tagged_u64(EsUint as uint, v as u64);
-    }
-    fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
-    fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
-    fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
-    fn emit_u8(&self, v: u8)   { self.wr_tagged_u8 (EsU8  as uint, v); }
-
-    fn emit_int(&self, v: int) {
-        self.wr_tagged_i64(EsInt as uint, v as i64);
-    }
-    fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
-    fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
-    fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
-    fn emit_i8(&self, v: i8)   { self.wr_tagged_i8 (EsI8  as uint, v); }
-
-    fn emit_bool(&self, v: bool) {
-        self.wr_tagged_u8(EsBool as uint, v as u8)
-    }
-
-    // FIXME (#2742): implement these
-    fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; }
-    fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; }
-    fn emit_float(&self, _v: float) {
-        fail ~"Unimplemented: serializing a float";
-    }
-
-    fn emit_char(&self, _v: char) {
-        fail ~"Unimplemented: serializing a char";
-    }
-
-    fn emit_borrowed_str(&self, v: &str) {
-        self.wr_tagged_str(EsStr as uint, v)
-    }
-
-    fn emit_owned_str(&self, v: &str) {
-        self.emit_borrowed_str(v)
-    }
-
-    fn emit_managed_str(&self, v: &str) {
-        self.emit_borrowed_str(v)
-    }
-
-    fn emit_borrowed(&self, f: fn()) { f() }
-    fn emit_owned(&self, f: fn()) { f() }
-    fn emit_managed(&self, f: fn()) { f() }
-
-    fn emit_enum(&self, name: &str, f: fn()) {
-        self._emit_label(name);
-        self.wr_tag(EsEnum as uint, f)
-    }
-    fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint,
-                         f: fn()) {
-        self._emit_tagged_uint(EsEnumVid, v_id);
-        self.wr_tag(EsEnumBody as uint, f)
-    }
-    fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
-
-    fn emit_borrowed_vec(&self, len: uint, f: fn()) {
-        do self.wr_tag(EsVec as uint) {
-            self._emit_tagged_uint(EsVecLen, len);
-            f()
-        }
-    }
-
-    fn emit_owned_vec(&self, len: uint, f: fn()) {
-        self.emit_borrowed_vec(len, f)
-    }
-
-    fn emit_managed_vec(&self, len: uint, f: fn()) {
-        self.emit_borrowed_vec(len, f)
-    }
-
-    fn emit_vec_elt(&self, _idx: uint, f: fn()) {
-        self.wr_tag(EsVecElt as uint, f)
-    }
-
-    fn emit_rec(&self, f: fn()) { f() }
-    fn emit_struct(&self, _name: &str, f: fn()) { f() }
-    fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
-        self._emit_label(name);
-        f()
-    }
-
-    fn emit_tup(&self, _len: uint, f: fn()) { f() }
-    fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
-}
-
-struct Deserializer {
-    priv mut parent: Doc,
-    priv mut pos: uint,
-}
-
-pub fn Deserializer(d: Doc) -> Deserializer {
-    Deserializer { mut parent: d, mut pos: d.start }
-}
-
-priv impl Deserializer {
-    fn _check_label(lbl: &str) {
-        if self.pos < self.parent.end {
-            let TaggedDoc { tag: r_tag, doc: r_doc } =
-                doc_at(self.parent.data, self.pos);
-
-            if r_tag == (EsLabel as uint) {
-                self.pos = r_doc.end;
-                let str = doc_as_str(r_doc);
-                if lbl != str {
-                    fail fmt!("Expected label %s but found %s", lbl, str);
-                }
-            }
-        }
-    }
-
-    fn next_doc(exp_tag: EbmlSerializerTag) -> Doc {
-        debug!(". next_doc(exp_tag=%?)", exp_tag);
-        if self.pos >= self.parent.end {
-            fail ~"no more documents in current node!";
-        }
-        let TaggedDoc { tag: r_tag, doc: r_doc } =
-            doc_at(self.parent.data, self.pos);
-        debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
-               copy self.parent.start, copy self.parent.end,
-               copy self.pos, r_tag, r_doc.start, r_doc.end);
-        if r_tag != (exp_tag as uint) {
-            fail fmt!("expected EMBL doc with tag %? but found tag %?",
-                      exp_tag, r_tag);
-        }
-        if r_doc.end > self.parent.end {
-            fail fmt!("invalid EBML, child extends to 0x%x, parent to 0x%x",
-                      r_doc.end, self.parent.end);
-        }
-        self.pos = r_doc.end;
-        r_doc
-    }
-
-    fn push_doc<T>(d: Doc, f: fn() -> T) -> T{
-        let old_parent = self.parent;
-        let old_pos = self.pos;
-        self.parent = d;
-        self.pos = d.start;
-        let r = f();
-        self.parent = old_parent;
-        self.pos = old_pos;
-        move r
-    }
-
-    fn _next_uint(exp_tag: EbmlSerializerTag) -> uint {
-        let r = doc_as_u32(self.next_doc(exp_tag));
-        debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
-        r as uint
-    }
-}
-
-impl Deserializer {
-    fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R {
-        do self.push_doc(self.next_doc(EsOpaque)) {
-            op(copy self.parent)
-        }
-    }
-}
-
-impl Deserializer: serialization2::Deserializer {
-    fn read_nil(&self) -> () { () }
-
-    fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
-    fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
-    fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
-    fn read_u8 (&self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
-    fn read_uint(&self) -> uint {
-        let v = doc_as_u64(self.next_doc(EsUint));
-        if v > (core::uint::max_value as u64) {
-            fail fmt!("uint %? too large for this architecture", v);
-        }
-        v as uint
-    }
-
-    fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 }
-    fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 }
-    fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 }
-    fn read_i8 (&self) -> i8  { doc_as_u8 (self.next_doc(EsI8 )) as i8  }
-    fn read_int(&self) -> int {
-        let v = doc_as_u64(self.next_doc(EsInt)) as i64;
-        if v > (int::max_value as i64) || v < (int::min_value as i64) {
-            fail fmt!("int %? out of range for this architecture", v);
-        }
-        v as int
-    }
-
-    fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool }
-
-    fn read_f64(&self) -> f64 { fail ~"read_f64()"; }
-    fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
-    fn read_float(&self) -> float { fail ~"read_float()"; }
-
-    fn read_char(&self) -> char { fail ~"read_char()"; }
-
-    fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
-    fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
-
-    // Compound types:
-    fn read_owned<T>(&self, f: fn() -> T) -> T {
-        debug!("read_owned()");
-        f()
-    }
-
-    fn read_managed<T>(&self, f: fn() -> T) -> T {
-        debug!("read_managed()");
-        f()
-    }
-
-    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
-        debug!("read_enum(%s)", name);
-        self._check_label(name);
-        self.push_doc(self.next_doc(EsEnum), f)
-    }
-
-    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_enum_variant()");
-        let idx = self._next_uint(EsEnumVid);
-        debug!("  idx=%u", idx);
-        do self.push_doc(self.next_doc(EsEnumBody)) {
-            f(idx)
-        }
-    }
-
-    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
-        debug!("read_enum_variant_arg(idx=%u)", idx);
-        f()
-    }
-
-    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_owned_vec()");
-        do self.push_doc(self.next_doc(EsVec)) {
-            let len = self._next_uint(EsVecLen);
-            debug!("  len=%u", len);
-            f(len)
-        }
-    }
-
-    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_managed_vec()");
-        do self.push_doc(self.next_doc(EsVec)) {
-            let len = self._next_uint(EsVecLen);
-            debug!("  len=%u", len);
-            f(len)
-        }
-    }
-
-    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
-        debug!("read_vec_elt(idx=%u)", idx);
-        self.push_doc(self.next_doc(EsVecElt), f)
-    }
-
-    fn read_rec<T>(&self, f: fn() -> T) -> T {
-        debug!("read_rec()");
-        f()
-    }
-
-    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
-        debug!("read_struct(name=%s)", name);
-        f()
-    }
-
-    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
-        debug!("read_field(name=%s, idx=%u)", name, idx);
-        self._check_label(name);
-        f()
-    }
-
-    fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
-        debug!("read_tup(len=%u)", len);
-        f()
-    }
-
-    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
-        debug!("read_tup_elt(idx=%u)", idx);
-        f()
-    }
-}
-
-// ___________________________________________________________________________
-// Testing
-
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn test_option_int() {
-        fn test_v(v: Option<int>) {
-            debug!("v == %?", v);
-            let bytes = do io::with_bytes_writer |wr| {
-                let ebml_w = Serializer(wr);
-                v.serialize(&ebml_w)
-            };
-            let ebml_doc = Doc(@bytes);
-            let deser = Deserializer(ebml_doc);
-            let v1 = serialization2::deserialize(&deser);
-            debug!("v1 == %?", v1);
-            assert v == v1;
-        }
-
-        test_v(Some(22));
-        test_v(None);
-        test_v(Some(3));
-    }
-}
+pub use ebml::*;
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 09d00216209..fa7c0286dc1 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -63,7 +63,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer {
     Serializer { wr: wr }
 }
 
-pub impl Serializer: serialization2::Serializer {
+pub impl Serializer: serialization::Serializer {
     fn emit_nil(&self) { self.wr.write_str("null") }
 
     fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
@@ -167,7 +167,7 @@ pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer {
     PrettySerializer { wr: wr, indent: 0 }
 }
 
-pub impl PrettySerializer: serialization2::Serializer {
+pub impl PrettySerializer: serialization::Serializer {
     fn emit_nil(&self) { self.wr.write_str("null") }
 
     fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
@@ -273,8 +273,8 @@ pub impl PrettySerializer: serialization2::Serializer {
     }
 }
 
-pub impl Json: serialization2::Serializable {
-    fn serialize<S: serialization2::Serializer>(&self, s: &S) {
+pub impl Json: serialization::Serializable {
+    fn serialize<S: serialization::Serializer>(&self, s: &S) {
         match *self {
             Number(v) => v.serialize(s),
             String(ref v) => v.serialize(s),
@@ -721,7 +721,7 @@ priv impl Deserializer {
     }
 }
 
-pub impl Deserializer: serialization2::Deserializer {
+pub impl Deserializer: serialization::Deserializer {
     fn read_nil(&self) -> () {
         debug!("read_nil");
         match *self.pop() {
diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs
index bc528800666..6119c03cdca 100644
--- a/src/libstd/prettyprint.rs
+++ b/src/libstd/prettyprint.rs
@@ -2,131 +2,175 @@
 
 use io::Writer;
 use io::WriterUtil;
-use serialization::Serializer;
+use serialization;
 
-impl Writer: Serializer {
-    fn emit_nil() {
-        self.write_str(~"()")
+pub struct Serializer {
+    wr: io::Writer,
+}
+
+pub fn Serializer(wr: io::Writer) -> Serializer {
+    Serializer { wr: wr }
+}
+
+pub impl Serializer: serialization::Serializer {
+    fn emit_nil(&self) {
+        self.wr.write_str(~"()")
+    }
+
+    fn emit_uint(&self, v: uint) {
+        self.wr.write_str(fmt!("%?u", v));
+    }
+
+    fn emit_u64(&self, v: u64) {
+        self.wr.write_str(fmt!("%?_u64", v));
+    }
+
+    fn emit_u32(&self, v: u32) {
+        self.wr.write_str(fmt!("%?_u32", v));
+    }
+
+    fn emit_u16(&self, v: u16) {
+        self.wr.write_str(fmt!("%?_u16", v));
+    }
+
+    fn emit_u8(&self, v: u8) {
+        self.wr.write_str(fmt!("%?_u8", v));
     }
 
-    fn emit_uint(v: uint) {
-        self.write_str(fmt!("%?u", v));
+    fn emit_int(&self, v: int) {
+        self.wr.write_str(fmt!("%?", v));
     }
 
-    fn emit_u64(v: u64) {
-        self.write_str(fmt!("%?_u64", v));
+    fn emit_i64(&self, v: i64) {
+        self.wr.write_str(fmt!("%?_i64", v));
     }
 
-    fn emit_u32(v: u32) {
-        self.write_str(fmt!("%?_u32", v));
+    fn emit_i32(&self, v: i32) {
+        self.wr.write_str(fmt!("%?_i32", v));
     }
 
-    fn emit_u16(v: u16) {
-        self.write_str(fmt!("%?_u16", v));
+    fn emit_i16(&self, v: i16) {
+        self.wr.write_str(fmt!("%?_i16", v));
     }
 
-    fn emit_u8(v: u8) {
-        self.write_str(fmt!("%?_u8", v));
+    fn emit_i8(&self, v: i8) {
+        self.wr.write_str(fmt!("%?_i8", v));
     }
 
-    fn emit_int(v: int) {
-        self.write_str(fmt!("%?", v));
+    fn emit_bool(&self, v: bool) {
+        self.wr.write_str(fmt!("%b", v));
     }
 
-    fn emit_i64(v: i64) {
-        self.write_str(fmt!("%?_i64", v));
+    fn emit_float(&self, v: float) {
+        self.wr.write_str(fmt!("%?_f", v));
     }
 
-    fn emit_i32(v: i32) {
-        self.write_str(fmt!("%?_i32", v));
+    fn emit_f64(&self, v: f64) {
+        self.wr.write_str(fmt!("%?_f64", v));
     }
 
-    fn emit_i16(v: i16) {
-        self.write_str(fmt!("%?_i16", v));
+    fn emit_f32(&self, v: f32) {
+        self.wr.write_str(fmt!("%?_f32", v));
     }
 
-    fn emit_i8(v: i8) {
-        self.write_str(fmt!("%?_i8", v));
+    fn emit_char(&self, v: char) {
+        self.wr.write_str(fmt!("%?", v));
     }
 
-    fn emit_bool(v: bool) {
-        self.write_str(fmt!("%b", v));
+    fn emit_borrowed_str(&self, v: &str) {
+        self.wr.write_str(fmt!("&%?", v));
     }
 
-    fn emit_float(v: float) {
-        self.write_str(fmt!("%?_f", v));
+    fn emit_owned_str(&self, v: &str) {
+        self.wr.write_str(fmt!("~%?", v));
     }
 
-    fn emit_f64(v: f64) {
-        self.write_str(fmt!("%?_f64", v));
+    fn emit_managed_str(&self, v: &str) {
+        self.wr.write_str(fmt!("@%?", v));
     }
 
-    fn emit_f32(v: f32) {
-        self.write_str(fmt!("%?_f32", v));
+    fn emit_borrowed(&self, f: fn()) {
+        self.wr.write_str(~"&");
+        f();
     }
 
-    fn emit_str(v: &str) {
-        self.write_str(fmt!("%?", v));
+    fn emit_owned(&self, f: fn()) {
+        self.wr.write_str(~"~");
+        f();
+    }
+
+    fn emit_managed(&self, f: fn()) {
+        self.wr.write_str(~"@");
+        f();
+    }
+
+    fn emit_enum(&self, _name: &str, f: fn()) {
+        f();
     }
 
-    fn emit_enum(_name: &str, f: fn()) {
+    fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint,
+                         f: fn()) {
+        self.wr.write_str(v_name);
+        if sz > 0u { self.wr.write_str(~"("); }
         f();
+        if sz > 0u { self.wr.write_str(~")"); }
     }
 
-    fn emit_enum_variant(v_name: &str, _v_id: uint, sz: uint, f: fn()) {
-        self.write_str(v_name);
-        if sz > 0u { self.write_str(~"("); }
+    fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
-        if sz > 0u { self.write_str(~")"); }
     }
 
-    fn emit_enum_variant_arg(idx: uint, f: fn()) {
-        if idx > 0u { self.write_str(~", "); }
+    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"&[");
         f();
+        self.wr.write_str(~"]");
     }
 
-    fn emit_vec(_len: uint, f: fn()) {
-        self.write_str(~"[");
+    fn emit_owned_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"~[");
         f();
-        self.write_str(~"]");
+        self.wr.write_str(~"]");
     }
 
-    fn emit_vec_elt(idx: uint, f: fn()) {
-        if idx > 0u { self.write_str(~", "); }
+    fn emit_managed_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"@[");
         f();
+        self.wr.write_str(~"]");
     }
 
-    fn emit_box(f: fn()) {
-        self.write_str(~"@");
+    fn emit_vec_elt(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
     }
 
-    fn emit_uniq(f: fn()) {
-        self.write_str(~"~");
+    fn emit_rec(&self, f: fn()) {
+        self.wr.write_str(~"{");
         f();
+        self.wr.write_str(~"}");
     }
 
-    fn emit_rec(f: fn()) {
-        self.write_str(~"{");
+    fn emit_struct(&self, name: &str, f: fn()) {
+        self.wr.write_str(fmt!("%s {", name));
         f();
-        self.write_str(~"}");
+        self.wr.write_str(~"}");
     }
 
-    fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()) {
-        if f_idx > 0u { self.write_str(~", "); }
-        self.write_str(f_name);
-        self.write_str(~": ");
+    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
+        self.wr.write_str(name);
+        self.wr.write_str(~": ");
         f();
     }
 
-    fn emit_tup(_sz: uint, f: fn()) {
-        self.write_str(~"(");
+    fn emit_tup(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"(");
         f();
-        self.write_str(~")");
+        self.wr.write_str(~")");
     }
 
-    fn emit_tup_elt(idx: uint, f: fn()) {
-        if idx > 0u { self.write_str(~", "); }
+    fn emit_tup_elt(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
     }
 }
diff --git a/src/libstd/prettyprint2.rs b/src/libstd/prettyprint2.rs
index 87af519eb12..a3bf40ecf72 100644
--- a/src/libstd/prettyprint2.rs
+++ b/src/libstd/prettyprint2.rs
@@ -1,176 +1 @@
-#[forbid(deprecated_mode)];
-
-use io::Writer;
-use io::WriterUtil;
-use serialization2;
-
-pub struct Serializer {
-    wr: io::Writer,
-}
-
-pub fn Serializer(wr: io::Writer) -> Serializer {
-    Serializer { wr: wr }
-}
-
-pub impl Serializer: serialization2::Serializer {
-    fn emit_nil(&self) {
-        self.wr.write_str(~"()")
-    }
-
-    fn emit_uint(&self, v: uint) {
-        self.wr.write_str(fmt!("%?u", v));
-    }
-
-    fn emit_u64(&self, v: u64) {
-        self.wr.write_str(fmt!("%?_u64", v));
-    }
-
-    fn emit_u32(&self, v: u32) {
-        self.wr.write_str(fmt!("%?_u32", v));
-    }
-
-    fn emit_u16(&self, v: u16) {
-        self.wr.write_str(fmt!("%?_u16", v));
-    }
-
-    fn emit_u8(&self, v: u8) {
-        self.wr.write_str(fmt!("%?_u8", v));
-    }
-
-    fn emit_int(&self, v: int) {
-        self.wr.write_str(fmt!("%?", v));
-    }
-
-    fn emit_i64(&self, v: i64) {
-        self.wr.write_str(fmt!("%?_i64", v));
-    }
-
-    fn emit_i32(&self, v: i32) {
-        self.wr.write_str(fmt!("%?_i32", v));
-    }
-
-    fn emit_i16(&self, v: i16) {
-        self.wr.write_str(fmt!("%?_i16", v));
-    }
-
-    fn emit_i8(&self, v: i8) {
-        self.wr.write_str(fmt!("%?_i8", v));
-    }
-
-    fn emit_bool(&self, v: bool) {
-        self.wr.write_str(fmt!("%b", v));
-    }
-
-    fn emit_float(&self, v: float) {
-        self.wr.write_str(fmt!("%?_f", v));
-    }
-
-    fn emit_f64(&self, v: f64) {
-        self.wr.write_str(fmt!("%?_f64", v));
-    }
-
-    fn emit_f32(&self, v: f32) {
-        self.wr.write_str(fmt!("%?_f32", v));
-    }
-
-    fn emit_char(&self, v: char) {
-        self.wr.write_str(fmt!("%?", v));
-    }
-
-    fn emit_borrowed_str(&self, v: &str) {
-        self.wr.write_str(fmt!("&%?", v));
-    }
-
-    fn emit_owned_str(&self, v: &str) {
-        self.wr.write_str(fmt!("~%?", v));
-    }
-
-    fn emit_managed_str(&self, v: &str) {
-        self.wr.write_str(fmt!("@%?", v));
-    }
-
-    fn emit_borrowed(&self, f: fn()) {
-        self.wr.write_str(~"&");
-        f();
-    }
-
-    fn emit_owned(&self, f: fn()) {
-        self.wr.write_str(~"~");
-        f();
-    }
-
-    fn emit_managed(&self, f: fn()) {
-        self.wr.write_str(~"@");
-        f();
-    }
-
-    fn emit_enum(&self, _name: &str, f: fn()) {
-        f();
-    }
-
-    fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint,
-                         f: fn()) {
-        self.wr.write_str(v_name);
-        if sz > 0u { self.wr.write_str(~"("); }
-        f();
-        if sz > 0u { self.wr.write_str(~")"); }
-    }
-
-    fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        f();
-    }
-
-    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"&[");
-        f();
-        self.wr.write_str(~"]");
-    }
-
-    fn emit_owned_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"~[");
-        f();
-        self.wr.write_str(~"]");
-    }
-
-    fn emit_managed_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"@[");
-        f();
-        self.wr.write_str(~"]");
-    }
-
-    fn emit_vec_elt(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        f();
-    }
-
-    fn emit_rec(&self, f: fn()) {
-        self.wr.write_str(~"{");
-        f();
-        self.wr.write_str(~"}");
-    }
-
-    fn emit_struct(&self, name: &str, f: fn()) {
-        self.wr.write_str(fmt!("%s {", name));
-        f();
-        self.wr.write_str(~"}");
-    }
-
-    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        self.wr.write_str(name);
-        self.wr.write_str(~": ");
-        f();
-    }
-
-    fn emit_tup(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"(");
-        f();
-        self.wr.write_str(~")");
-    }
-
-    fn emit_tup_elt(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
-        f();
-    }
-}
+pub use prettyprint::*;
diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs
index 8ba00e65dec..5173ef163a2 100644
--- a/src/libstd/serialization.rs
+++ b/src/libstd/serialization.rs
@@ -1,270 +1,562 @@
 //! Support code for serialization.
 
-#[allow(deprecated_mode)];
-
 /*
 Core serialization interfaces.
 */
 
+#[forbid(deprecated_mode)];
+#[forbid(non_camel_case_types)];
+
 pub trait Serializer {
     // Primitive types:
-    fn emit_nil();
-    fn emit_uint(v: uint);
-    fn emit_u64(v: u64);
-    fn emit_u32(v: u32);
-    fn emit_u16(v: u16);
-    fn emit_u8(v: u8);
-    fn emit_int(v: int);
-    fn emit_i64(v: i64);
-    fn emit_i32(v: i32);
-    fn emit_i16(v: i16);
-    fn emit_i8(v: i8);
-    fn emit_bool(v: bool);
-    fn emit_float(v: float);
-    fn emit_f64(v: f64);
-    fn emit_f32(v: f32);
-    fn emit_str(v: &str);
+    fn emit_nil(&self);
+    fn emit_uint(&self, v: uint);
+    fn emit_u64(&self, v: u64);
+    fn emit_u32(&self, v: u32);
+    fn emit_u16(&self, v: u16);
+    fn emit_u8(&self, v: u8);
+    fn emit_int(&self, v: int);
+    fn emit_i64(&self, v: i64);
+    fn emit_i32(&self, v: i32);
+    fn emit_i16(&self, v: i16);
+    fn emit_i8(&self, v: i8);
+    fn emit_bool(&self, v: bool);
+    fn emit_float(&self, v: float);
+    fn emit_f64(&self, v: f64);
+    fn emit_f32(&self, v: f32);
+    fn emit_char(&self, v: char);
+    fn emit_borrowed_str(&self, v: &str);
+    fn emit_owned_str(&self, v: &str);
+    fn emit_managed_str(&self, v: &str);
 
     // Compound types:
-    fn emit_enum(name: &str, f: fn());
-    fn emit_enum_variant(v_name: &str, v_id: uint, sz: uint, f: fn());
-    fn emit_enum_variant_arg(idx: uint, f: fn());
-    fn emit_vec(len: uint, f: fn());
-    fn emit_vec_elt(idx: uint, f: fn());
-    fn emit_box(f: fn());
-    fn emit_uniq(f: fn());
-    fn emit_rec(f: fn());
-    fn emit_rec_field(f_name: &str, f_idx: uint, f: fn());
-    fn emit_tup(sz: uint, f: fn());
-    fn emit_tup_elt(idx: uint, f: fn());
+    fn emit_borrowed(&self, f: fn());
+    fn emit_owned(&self, f: fn());
+    fn emit_managed(&self, f: fn());
+
+    fn emit_enum(&self, name: &str, f: fn());
+    fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
+    fn emit_enum_variant_arg(&self, idx: uint, f: fn());
+
+    fn emit_borrowed_vec(&self, len: uint, f: fn());
+    fn emit_owned_vec(&self, len: uint, f: fn());
+    fn emit_managed_vec(&self, len: uint, f: fn());
+    fn emit_vec_elt(&self, idx: uint, f: fn());
+
+    fn emit_rec(&self, f: fn());
+    fn emit_struct(&self, name: &str, f: fn());
+    fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
+
+    fn emit_tup(&self, len: uint, f: fn());
+    fn emit_tup_elt(&self, idx: uint, f: fn());
 }
 
 pub trait Deserializer {
     // Primitive types:
-    fn read_nil() -> ();
+    fn read_nil(&self) -> ();
+    fn read_uint(&self) -> uint;
+    fn read_u64(&self) -> u64;
+    fn read_u32(&self) -> u32;
+    fn read_u16(&self) -> u16;
+    fn read_u8(&self) -> u8;
+    fn read_int(&self) -> int;
+    fn read_i64(&self) -> i64;
+    fn read_i32(&self) -> i32;
+    fn read_i16(&self) -> i16;
+    fn read_i8(&self) -> i8;
+    fn read_bool(&self) -> bool;
+    fn read_f64(&self) -> f64;
+    fn read_f32(&self) -> f32;
+    fn read_float(&self) -> float;
+    fn read_char(&self) -> char;
+    fn read_owned_str(&self) -> ~str;
+    fn read_managed_str(&self) -> @str;
 
-    fn read_uint() -> uint;
-    fn read_u64() -> u64;
-    fn read_u32() -> u32;
-    fn read_u16() -> u16;
-    fn read_u8() -> u8;
+    // Compound types:
+    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
+    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
 
-    fn read_int() -> int;
-    fn read_i64() -> i64;
-    fn read_i32() -> i32;
-    fn read_i16() -> i16;
-    fn read_i8() -> i8;
+    fn read_owned<T>(&self, f: fn() -> T) -> T;
+    fn read_managed<T>(&self, f: fn() -> T) -> T;
 
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
 
-    fn read_bool() -> bool;
+    fn read_rec<T>(&self, f: fn() -> T) -> T;
+    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
 
-    fn read_str() -> ~str;
+    fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
+    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
+}
 
-    fn read_f64() -> f64;
-    fn read_f32() -> f32;
-    fn read_float() -> float;
+pub trait Serializable {
+    fn serialize<S: Serializer>(&self, s: &S);
+}
 
-    // Compound types:
-    fn read_enum<T>(name: &str, f: fn() -> T) -> T;
-    fn read_enum_variant<T>(f: fn(uint) -> T) -> T;
-    fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T;
-    fn read_vec<T>(f: fn(uint) -> T) -> T;
-    fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T;
-    fn read_box<T>(f: fn() -> T) -> T;
-    fn read_uniq<T>(f: fn() -> T) -> T;
-    fn read_rec<T>(f: fn() -> T) -> T;
-    fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T;
-    fn read_tup<T>(sz: uint, f: fn() -> T) -> T;
-    fn read_tup_elt<T>(idx: uint, f: fn() -> T) -> T;
+pub trait Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
 }
 
-// ___________________________________________________________________________
-// Helper routines
-//
-// In some cases, these should eventually be coded as traits.
+pub impl uint: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
+}
 
-pub fn emit_from_vec<S: Serializer, T>(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
-    do s.emit_vec(vec::len(v)) {
-        for vec::eachi(v) |i,e| {
-            do s.emit_vec_elt(i) {
-                f(*e)
-            }
-        }
+pub impl uint: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
+        d.read_uint()
     }
 }
 
-pub fn read_to_vec<D: Deserializer, T: Copy>(&&d: D, f: fn() -> T) -> ~[T] {
-    do d.read_vec |len| {
-        do vec::from_fn(len) |i| {
-            d.read_vec_elt(i, || f())
-        }
+pub impl u8: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
+}
+
+pub impl u8: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
+        d.read_u8()
     }
 }
 
-pub trait SerializerHelpers {
-    fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T));
+pub impl u16: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
 }
 
-impl<S: Serializer> S: SerializerHelpers {
-    fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T)) {
-        emit_from_vec(self, v, f)
+pub impl u16: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
+        d.read_u16()
     }
 }
 
-pub trait DeserializerHelpers {
-    fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T];
+pub impl u32: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
 }
 
-impl<D: Deserializer> D: DeserializerHelpers {
-    fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T] {
-        read_to_vec(self, f)
+pub impl u32: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
+        d.read_u32()
     }
 }
 
-pub fn serialize_uint<S: Serializer>(&&s: S, v: uint) {
-    s.emit_uint(v);
+pub impl u64: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
 }
 
-pub fn deserialize_uint<D: Deserializer>(&&d: D) -> uint {
-    d.read_uint()
+pub impl u64: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
+        d.read_u64()
+    }
 }
 
-pub fn serialize_u8<S: Serializer>(&&s: S, v: u8) {
-    s.emit_u8(v);
+pub impl int: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
 }
 
-pub fn deserialize_u8<D: Deserializer>(&&d: D) -> u8 {
-    d.read_u8()
+pub impl int: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
+        d.read_int()
+    }
 }
 
-pub fn serialize_u16<S: Serializer>(&&s: S, v: u16) {
-    s.emit_u16(v);
+pub impl i8: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
 }
 
-pub fn deserialize_u16<D: Deserializer>(&&d: D) -> u16 {
-    d.read_u16()
+pub impl i8: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
+        d.read_i8()
+    }
 }
 
-pub fn serialize_u32<S: Serializer>(&&s: S, v: u32) {
-    s.emit_u32(v);
+pub impl i16: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
 }
 
-pub fn deserialize_u32<D: Deserializer>(&&d: D) -> u32 {
-    d.read_u32()
+pub impl i16: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
+        d.read_i16()
+    }
 }
 
-pub fn serialize_u64<S: Serializer>(&&s: S, v: u64) {
-    s.emit_u64(v);
+pub impl i32: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
 }
 
-pub fn deserialize_u64<D: Deserializer>(&&d: D) -> u64 {
-    d.read_u64()
+pub impl i32: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
+        d.read_i32()
+    }
 }
 
-pub fn serialize_int<S: Serializer>(&&s: S, v: int) {
-    s.emit_int(v);
+pub impl i64: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
 }
 
-pub fn deserialize_int<D: Deserializer>(&&d: D) -> int {
-    d.read_int()
+pub impl i64: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
+        d.read_i64()
+    }
 }
 
-pub fn serialize_i8<S: Serializer>(&&s: S, v: i8) {
-    s.emit_i8(v);
+pub impl &str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
 }
 
-pub fn deserialize_i8<D: Deserializer>(&&d: D) -> i8 {
-    d.read_i8()
+pub impl ~str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
 }
 
-pub fn serialize_i16<S: Serializer>(&&s: S, v: i16) {
-    s.emit_i16(v);
+pub impl ~str: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
+        d.read_owned_str()
+    }
 }
 
-pub fn deserialize_i16<D: Deserializer>(&&d: D) -> i16 {
-    d.read_i16()
+pub impl @str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
 }
 
-pub fn serialize_i32<S: Serializer>(&&s: S, v: i32) {
-    s.emit_i32(v);
+pub impl @str: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
+        d.read_managed_str()
+    }
 }
 
-pub fn deserialize_i32<D: Deserializer>(&&d: D) -> i32 {
-    d.read_i32()
+pub impl float: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
 }
 
-pub fn serialize_i64<S: Serializer>(&&s: S, v: i64) {
-    s.emit_i64(v);
+pub impl float: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
+        d.read_float()
+    }
 }
 
-pub fn deserialize_i64<D: Deserializer>(&&d: D) -> i64 {
-    d.read_i64()
+pub impl f32: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
 }
 
-pub fn serialize_str<S: Serializer>(&&s: S, v: &str) {
-    s.emit_str(v);
+pub impl f32: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
+        d.read_f32() }
 }
 
-pub fn deserialize_str<D: Deserializer>(&&d: D) -> ~str {
-    d.read_str()
+pub impl f64: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
 }
 
-pub fn serialize_float<S: Serializer>(&&s: S, v: float) {
-    s.emit_float(v);
+pub impl f64: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
+        d.read_f64()
+    }
 }
 
-pub fn deserialize_float<D: Deserializer>(&&d: D) -> float {
-    d.read_float()
+pub impl bool: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
 }
 
-pub fn serialize_f32<S: Serializer>(&&s: S, v: f32) {
-    s.emit_f32(v);
+pub impl bool: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
+        d.read_bool()
+    }
+}
+
+pub impl (): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
+}
+
+pub impl (): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
+        d.read_nil()
+    }
 }
 
-pub fn deserialize_f32<D: Deserializer>(&&d: D) -> f32 {
-    d.read_f32()
+pub impl<T: Serializable> &T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_borrowed(|| (**self).serialize(s))
+    }
 }
 
-pub fn serialize_f64<S: Serializer>(&&s: S, v: f64) {
-    s.emit_f64(v);
+pub impl<T: Serializable> ~T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_owned(|| (**self).serialize(s))
+    }
 }
 
-pub fn deserialize_f64<D: Deserializer>(&&d: D) -> f64 {
-    d.read_f64()
+pub impl<T: Deserializable> ~T: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
+        d.read_owned(|| ~deserialize(d))
+    }
 }
 
-pub fn serialize_bool<S: Serializer>(&&s: S, v: bool) {
-    s.emit_bool(v);
+pub impl<T: Serializable> @T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_managed(|| (**self).serialize(s))
+    }
 }
 
-pub fn deserialize_bool<D: Deserializer>(&&d: D) -> bool {
-    d.read_bool()
+pub impl<T: Deserializable> @T: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
+        d.read_managed(|| @deserialize(d))
+    }
 }
 
-pub fn serialize_Option<S: Serializer,T>(&&s: S, &&v: Option<T>,
-                                         st: fn(&&x: T)) {
-    do s.emit_enum(~"option") {
-        match v {
-          None => do s.emit_enum_variant(~"none", 0u, 0u) {
-          },
+pub impl<T: Serializable> &[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_borrowed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
 
-          Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
-            do s.emit_enum_variant_arg(0u) {
-                st(*v)
+pub impl<T: Serializable> ~[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_owned_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
             }
-          }
         }
     }
 }
 
-pub fn deserialize_Option<D: Deserializer,T: Copy>(&&d: D, st: fn() -> T)
-    -> Option<T> {
-    do d.read_enum(~"option") {
-        do d.read_enum_variant |i| {
-            match i {
-              0 => None,
-              1 => Some(d.read_enum_variant_arg(0u, || st() )),
-              _ => fail(#fmt("Bad variant for option: %u", i))
+pub impl<T: Deserializable> ~[T]: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
+        do d.read_owned_vec |len| {
+            do vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
+}
+
+pub impl<T: Serializable> @[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_managed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<T: Deserializable> @[T]: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
+        do d.read_managed_vec |len| {
+            do at_vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
+}
+
+pub impl<T: Serializable> Option<T>: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_enum(~"option") {
+            match *self {
+              None => do s.emit_enum_variant(~"none", 0u, 0u) {
+              },
+
+              Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
+                s.emit_enum_variant_arg(0u, || v.serialize(s))
+              }
+            }
+        }
+    }
+}
+
+pub impl<T: Deserializable> Option<T>: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
+        do d.read_enum(~"option") {
+            do d.read_enum_variant |i| {
+                match i {
+                  0 => None,
+                  1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))),
+                  _ => fail(#fmt("Bad variant for option: %u", i))
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable
+> (T0, T1): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1) => {
+                do s.emit_tup(2) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable
+> (T0, T1): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
+        do d.read_tup(2) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d))
+            )
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable,
+    T2: Serializable
+> (T0, T1, T2): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2) => {
+                do s.emit_tup(3) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable
+> (T0, T1, T2): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
+        do d.read_tup(3) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d))
+            )
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable,
+    T2: Serializable,
+    T3: Serializable
+> (T0, T1, T2, T3): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3) => {
+                do s.emit_tup(4) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                    s.emit_tup_elt(3, || t3.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable,
+    T3: Deserializable
+> (T0, T1, T2, T3): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
+        do d.read_tup(4) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d)),
+                d.read_tup_elt(3, || deserialize(d))
+            )
+        }
+    }
+}
+
+pub impl<
+    T0: Serializable,
+    T1: Serializable,
+    T2: Serializable,
+    T3: Serializable,
+    T4: Serializable
+> (T0, T1, T2, T3, T4): Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3, ref t4) => {
+                do s.emit_tup(5) {
+                    s.emit_tup_elt(0, || t0.serialize(s));
+                    s.emit_tup_elt(1, || t1.serialize(s));
+                    s.emit_tup_elt(2, || t2.serialize(s));
+                    s.emit_tup_elt(3, || t3.serialize(s));
+                    s.emit_tup_elt(4, || t4.serialize(s));
+                }
+            }
+        }
+    }
+}
+
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable,
+    T3: Deserializable,
+    T4: Deserializable
+> (T0, T1, T2, T3, T4): Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D)
+      -> (T0, T1, T2, T3, T4) {
+        do d.read_tup(5) {
+            (
+                d.read_tup_elt(0, || deserialize(d)),
+                d.read_tup_elt(1, || deserialize(d)),
+                d.read_tup_elt(2, || deserialize(d)),
+                d.read_tup_elt(3, || deserialize(d)),
+                d.read_tup_elt(4, || deserialize(d))
+            )
+        }
+    }
+}
+
+// ___________________________________________________________________________
+// Helper routines
+//
+// In some cases, these should eventually be coded as traits.
+
+pub trait SerializerHelpers {
+    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
+}
+
+pub impl<S: Serializer> S: SerializerHelpers {
+    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
+        do self.emit_owned_vec(v.len()) {
+            for v.eachi |i, e| {
+                do self.emit_vec_elt(i) {
+                    f(e)
+                }
+            }
+        }
+    }
+}
+
+pub trait DeserializerHelpers {
+    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
+}
+
+pub impl<D: Deserializer> D: DeserializerHelpers {
+    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
+        do self.read_owned_vec |len| {
+            do vec::from_fn(len) |i| {
+                self.read_vec_elt(i, || f())
             }
         }
     }
diff --git a/src/libstd/serialization2.rs b/src/libstd/serialization2.rs
index 5173ef163a2..9ea54477869 100644
--- a/src/libstd/serialization2.rs
+++ b/src/libstd/serialization2.rs
@@ -4,560 +4,4 @@
 Core serialization interfaces.
 */
 
-#[forbid(deprecated_mode)];
-#[forbid(non_camel_case_types)];
-
-pub trait Serializer {
-    // Primitive types:
-    fn emit_nil(&self);
-    fn emit_uint(&self, v: uint);
-    fn emit_u64(&self, v: u64);
-    fn emit_u32(&self, v: u32);
-    fn emit_u16(&self, v: u16);
-    fn emit_u8(&self, v: u8);
-    fn emit_int(&self, v: int);
-    fn emit_i64(&self, v: i64);
-    fn emit_i32(&self, v: i32);
-    fn emit_i16(&self, v: i16);
-    fn emit_i8(&self, v: i8);
-    fn emit_bool(&self, v: bool);
-    fn emit_float(&self, v: float);
-    fn emit_f64(&self, v: f64);
-    fn emit_f32(&self, v: f32);
-    fn emit_char(&self, v: char);
-    fn emit_borrowed_str(&self, v: &str);
-    fn emit_owned_str(&self, v: &str);
-    fn emit_managed_str(&self, v: &str);
-
-    // Compound types:
-    fn emit_borrowed(&self, f: fn());
-    fn emit_owned(&self, f: fn());
-    fn emit_managed(&self, f: fn());
-
-    fn emit_enum(&self, name: &str, f: fn());
-    fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
-    fn emit_enum_variant_arg(&self, idx: uint, f: fn());
-
-    fn emit_borrowed_vec(&self, len: uint, f: fn());
-    fn emit_owned_vec(&self, len: uint, f: fn());
-    fn emit_managed_vec(&self, len: uint, f: fn());
-    fn emit_vec_elt(&self, idx: uint, f: fn());
-
-    fn emit_rec(&self, f: fn());
-    fn emit_struct(&self, name: &str, f: fn());
-    fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
-
-    fn emit_tup(&self, len: uint, f: fn());
-    fn emit_tup_elt(&self, idx: uint, f: fn());
-}
-
-pub trait Deserializer {
-    // Primitive types:
-    fn read_nil(&self) -> ();
-    fn read_uint(&self) -> uint;
-    fn read_u64(&self) -> u64;
-    fn read_u32(&self) -> u32;
-    fn read_u16(&self) -> u16;
-    fn read_u8(&self) -> u8;
-    fn read_int(&self) -> int;
-    fn read_i64(&self) -> i64;
-    fn read_i32(&self) -> i32;
-    fn read_i16(&self) -> i16;
-    fn read_i8(&self) -> i8;
-    fn read_bool(&self) -> bool;
-    fn read_f64(&self) -> f64;
-    fn read_f32(&self) -> f32;
-    fn read_float(&self) -> float;
-    fn read_char(&self) -> char;
-    fn read_owned_str(&self) -> ~str;
-    fn read_managed_str(&self) -> @str;
-
-    // Compound types:
-    fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
-    fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
-    fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
-
-    fn read_owned<T>(&self, f: fn() -> T) -> T;
-    fn read_managed<T>(&self, f: fn() -> T) -> T;
-
-    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
-    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
-    fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
-
-    fn read_rec<T>(&self, f: fn() -> T) -> T;
-    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
-    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
-
-    fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
-    fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
-}
-
-pub trait Serializable {
-    fn serialize<S: Serializer>(&self, s: &S);
-}
-
-pub trait Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
-}
-
-pub impl uint: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
-}
-
-pub impl uint: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
-        d.read_uint()
-    }
-}
-
-pub impl u8: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
-}
-
-pub impl u8: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
-        d.read_u8()
-    }
-}
-
-pub impl u16: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
-}
-
-pub impl u16: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
-        d.read_u16()
-    }
-}
-
-pub impl u32: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
-}
-
-pub impl u32: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
-        d.read_u32()
-    }
-}
-
-pub impl u64: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
-}
-
-pub impl u64: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
-        d.read_u64()
-    }
-}
-
-pub impl int: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
-}
-
-pub impl int: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
-        d.read_int()
-    }
-}
-
-pub impl i8: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
-}
-
-pub impl i8: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
-        d.read_i8()
-    }
-}
-
-pub impl i16: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
-}
-
-pub impl i16: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
-        d.read_i16()
-    }
-}
-
-pub impl i32: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
-}
-
-pub impl i32: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
-        d.read_i32()
-    }
-}
-
-pub impl i64: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
-}
-
-pub impl i64: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
-        d.read_i64()
-    }
-}
-
-pub impl &str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
-}
-
-pub impl ~str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
-}
-
-pub impl ~str: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
-        d.read_owned_str()
-    }
-}
-
-pub impl @str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
-}
-
-pub impl @str: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
-        d.read_managed_str()
-    }
-}
-
-pub impl float: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
-}
-
-pub impl float: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
-        d.read_float()
-    }
-}
-
-pub impl f32: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
-}
-
-pub impl f32: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
-        d.read_f32() }
-}
-
-pub impl f64: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
-}
-
-pub impl f64: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
-        d.read_f64()
-    }
-}
-
-pub impl bool: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
-}
-
-pub impl bool: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
-        d.read_bool()
-    }
-}
-
-pub impl (): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
-}
-
-pub impl (): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
-        d.read_nil()
-    }
-}
-
-pub impl<T: Serializable> &T: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_borrowed(|| (**self).serialize(s))
-    }
-}
-
-pub impl<T: Serializable> ~T: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_owned(|| (**self).serialize(s))
-    }
-}
-
-pub impl<T: Deserializable> ~T: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
-        d.read_owned(|| ~deserialize(d))
-    }
-}
-
-pub impl<T: Serializable> @T: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_managed(|| (**self).serialize(s))
-    }
-}
-
-pub impl<T: Deserializable> @T: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
-        d.read_managed(|| @deserialize(d))
-    }
-}
-
-pub impl<T: Serializable> &[T]: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_borrowed_vec(self.len()) {
-            for self.eachi |i, e| {
-                s.emit_vec_elt(i, || e.serialize(s))
-            }
-        }
-    }
-}
-
-pub impl<T: Serializable> ~[T]: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_owned_vec(self.len()) {
-            for self.eachi |i, e| {
-                s.emit_vec_elt(i, || e.serialize(s))
-            }
-        }
-    }
-}
-
-pub impl<T: Deserializable> ~[T]: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
-        do d.read_owned_vec |len| {
-            do vec::from_fn(len) |i| {
-                d.read_vec_elt(i, || deserialize(d))
-            }
-        }
-    }
-}
-
-pub impl<T: Serializable> @[T]: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_managed_vec(self.len()) {
-            for self.eachi |i, e| {
-                s.emit_vec_elt(i, || e.serialize(s))
-            }
-        }
-    }
-}
-
-pub impl<T: Deserializable> @[T]: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
-        do d.read_managed_vec |len| {
-            do at_vec::from_fn(len) |i| {
-                d.read_vec_elt(i, || deserialize(d))
-            }
-        }
-    }
-}
-
-pub impl<T: Serializable> Option<T>: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_enum(~"option") {
-            match *self {
-              None => do s.emit_enum_variant(~"none", 0u, 0u) {
-              },
-
-              Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
-                s.emit_enum_variant_arg(0u, || v.serialize(s))
-              }
-            }
-        }
-    }
-}
-
-pub impl<T: Deserializable> Option<T>: Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
-        do d.read_enum(~"option") {
-            do d.read_enum_variant |i| {
-                match i {
-                  0 => None,
-                  1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))),
-                  _ => fail(#fmt("Bad variant for option: %u", i))
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable
-> (T0, T1): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1) => {
-                do s.emit_tup(2) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable
-> (T0, T1): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
-        do d.read_tup(2) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d))
-            )
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable,
-    T2: Serializable
-> (T0, T1, T2): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1, ref t2) => {
-                do s.emit_tup(3) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                    s.emit_tup_elt(2, || t2.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable,
-    T2: Deserializable
-> (T0, T1, T2): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
-        do d.read_tup(3) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d)),
-                d.read_tup_elt(2, || deserialize(d))
-            )
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable,
-    T2: Serializable,
-    T3: Serializable
-> (T0, T1, T2, T3): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1, ref t2, ref t3) => {
-                do s.emit_tup(4) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                    s.emit_tup_elt(2, || t2.serialize(s));
-                    s.emit_tup_elt(3, || t3.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable,
-    T2: Deserializable,
-    T3: Deserializable
-> (T0, T1, T2, T3): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
-        do d.read_tup(4) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d)),
-                d.read_tup_elt(2, || deserialize(d)),
-                d.read_tup_elt(3, || deserialize(d))
-            )
-        }
-    }
-}
-
-pub impl<
-    T0: Serializable,
-    T1: Serializable,
-    T2: Serializable,
-    T3: Serializable,
-    T4: Serializable
-> (T0, T1, T2, T3, T4): Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) {
-        match *self {
-            (ref t0, ref t1, ref t2, ref t3, ref t4) => {
-                do s.emit_tup(5) {
-                    s.emit_tup_elt(0, || t0.serialize(s));
-                    s.emit_tup_elt(1, || t1.serialize(s));
-                    s.emit_tup_elt(2, || t2.serialize(s));
-                    s.emit_tup_elt(3, || t3.serialize(s));
-                    s.emit_tup_elt(4, || t4.serialize(s));
-                }
-            }
-        }
-    }
-}
-
-pub impl<
-    T0: Deserializable,
-    T1: Deserializable,
-    T2: Deserializable,
-    T3: Deserializable,
-    T4: Deserializable
-> (T0, T1, T2, T3, T4): Deserializable {
-    static fn deserialize<D: Deserializer>(&self, d: &D)
-      -> (T0, T1, T2, T3, T4) {
-        do d.read_tup(5) {
-            (
-                d.read_tup_elt(0, || deserialize(d)),
-                d.read_tup_elt(1, || deserialize(d)),
-                d.read_tup_elt(2, || deserialize(d)),
-                d.read_tup_elt(3, || deserialize(d)),
-                d.read_tup_elt(4, || deserialize(d))
-            )
-        }
-    }
-}
-
-// ___________________________________________________________________________
-// Helper routines
-//
-// In some cases, these should eventually be coded as traits.
-
-pub trait SerializerHelpers {
-    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
-}
-
-pub impl<S: Serializer> S: SerializerHelpers {
-    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
-        do self.emit_owned_vec(v.len()) {
-            for v.eachi |i, e| {
-                do self.emit_vec_elt(i) {
-                    f(e)
-                }
-            }
-        }
-    }
-}
-
-pub trait DeserializerHelpers {
-    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
-}
-
-pub impl<D: Deserializer> D: DeserializerHelpers {
-    fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
-        do self.read_owned_vec |len| {
-            do vec::from_fn(len) |i| {
-                self.read_vec_elt(i, || f())
-            }
-        }
-    }
-}
+pub use serialization::*;
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 1c279f81cc3..f3e118461e6 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1,9 +1,9 @@
 // The Rust abstract syntax tree.
 
-use std::serialization2::{Serializable,
-                          Deserializable,
-                          Serializer,
-                          Deserializer};
+use std::serialization::{Serializable,
+                         Deserializable,
+                         Serializer,
+                         Deserializer};
 use codemap::{span, filename};
 use parse::token;
 
@@ -18,6 +18,8 @@ impl span: Deserializable {
     }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type spanned<T> = {node: T, span: span};
@@ -74,6 +76,8 @@ impl ident: to_bytes::IterBytes {
 // Functions may or may not have names.
 type fn_ident = Option<ident>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type path = {span: span,
@@ -86,6 +90,8 @@ type crate_num = int;
 
 type node_id = int;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type def_id = {crate: crate_num, node: node_id};
@@ -100,6 +106,8 @@ impl def_id : cmp::Eq {
 const local_crate: crate_num = 0;
 const crate_node_id: node_id = 0;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum ty_param_bound {
@@ -110,10 +118,14 @@ enum ty_param_bound {
     bound_trait(@ty),
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type ty_param = {ident: ident, id: node_id, bounds: @~[ty_param_bound]};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum def {
@@ -294,6 +306,8 @@ type crate_directive = spanned<crate_directive_>;
 
 type meta_item = spanned<meta_item_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum meta_item_ {
@@ -304,6 +318,8 @@ enum meta_item_ {
 
 type blk = spanned<blk_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type blk_ = {view_items: ~[@view_item],
@@ -312,14 +328,20 @@ type blk_ = {view_items: ~[@view_item],
              id: node_id,
              rules: blk_check_mode};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type pat = {id: node_id, node: pat_, span: span};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type field_pat = {ident: ident, pat: @pat};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum binding_mode {
@@ -377,6 +399,8 @@ impl binding_mode : cmp::Eq {
     pure fn ne(other: &binding_mode) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum pat_ {
@@ -401,6 +425,8 @@ enum pat_ {
     pat_range(@expr, @expr),
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum mutability { m_mutbl, m_imm, m_const, }
@@ -418,6 +444,8 @@ impl mutability : cmp::Eq {
     pure fn ne(other: &mutability) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum proto {
@@ -434,6 +462,8 @@ impl proto : cmp::Eq {
     pure fn ne(other: &proto) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum vstore {
@@ -444,6 +474,8 @@ enum vstore {
     vstore_slice(@region)         // &[1,2,3,4](foo)?
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum expr_vstore {
@@ -461,6 +493,8 @@ pure fn is_blockish(p: ast::proto) -> bool {
     }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum binop {
@@ -491,6 +525,8 @@ impl binop : cmp::Eq {
     pure fn ne(other: &binop) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum unop {
@@ -543,6 +579,8 @@ impl unop : cmp::Eq {
 
 // Generally, after typeck you can get the inferred value
 // using ty::resolved_T(...).
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum inferable<T> {
@@ -583,6 +621,8 @@ impl<T:cmp::Eq> inferable<T> : cmp::Eq {
 }
 
 // "resolved" mode: the real modes.
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum rmode { by_ref, by_val, by_move, by_copy }
@@ -606,6 +646,8 @@ type mode = inferable<rmode>;
 
 type stmt = spanned<stmt_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum stmt_ {
@@ -618,6 +660,8 @@ enum stmt_ {
     stmt_semi(@expr, node_id),
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum init_op { init_assign, init_move, }
@@ -642,12 +686,16 @@ impl init_op : cmp::Eq {
     pure fn ne(other: &init_op) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type initializer = {op: init_op, expr: @expr};
 
 // FIXME (pending discussion of #1697, #2178...): local should really be
 // a refinement on pat.
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type local_ =  {is_mutbl: bool, ty: @ty, pat: @pat,
@@ -657,20 +705,28 @@ type local = spanned<local_>;
 
 type decl = spanned<decl_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum decl_ { decl_local(~[@local]), decl_item(@item), }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type arm = {pats: ~[@pat], guard: Option<@expr>, body: blk};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type field_ = {mutbl: mutability, ident: ident, expr: @expr};
 
 type field = spanned<field_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum blk_check_mode { default_blk, unsafe_blk, }
@@ -687,20 +743,28 @@ impl blk_check_mode : cmp::Eq {
     pure fn ne(other: &blk_check_mode) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type expr = {id: node_id, callee_id: node_id, node: expr_, span: span};
 // Extra node ID is only used for index, assign_op, unary, binary
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum log_level { error, debug, other }
 // 0 = error, 1 = debug, 2 = other
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum alt_mode { alt_check, alt_exhaustive, }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum expr_ {
@@ -758,6 +822,8 @@ enum expr_ {
     expr_repeat(@expr /* element */, @expr /* count */, mutability)
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type capture_item_ = {
@@ -787,6 +853,8 @@ type capture_clause = @~[capture_item];
 // else knows what to do with them, so you'll probably get a syntax
 // error.
 //
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 #[doc="For macro invocations; parsing is delegated to the macro"]
@@ -852,6 +920,8 @@ enum token_tree {
 //
 type matcher = spanned<matcher_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum matcher_ {
@@ -868,12 +938,16 @@ type mac = spanned<mac_>;
 
 type mac_arg = Option<@expr>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type mac_body_ = {span: span};
 
 type mac_body = Option<mac_body_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum mac_ {
@@ -888,6 +962,8 @@ enum mac_ {
 
 type lit = spanned<lit_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum lit_ {
@@ -930,22 +1006,30 @@ impl ast::lit_: cmp::Eq {
 
 // NB: If you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type mt = {ty: @ty, mutbl: mutability};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type ty_field_ = {ident: ident, mt: mt};
 
 type ty_field = spanned<ty_field_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type ty_method = {ident: ident, attrs: ~[attribute], purity: purity,
                   decl: fn_decl, tps: ~[ty_param], self_ty: self_ty,
                   id: node_id, span: span};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 // A trait method is either required (meaning it doesn't have an
@@ -956,6 +1040,8 @@ enum trait_method {
     provided(@method),
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
@@ -986,6 +1072,8 @@ impl int_ty : cmp::Eq {
     pure fn ne(other: &int_ty) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
@@ -1014,6 +1102,8 @@ impl uint_ty : cmp::Eq {
     pure fn ne(other: &uint_ty) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum float_ty { ty_f, ty_f32, ty_f64, }
@@ -1033,11 +1123,15 @@ impl float_ty : cmp::Eq {
     pure fn ne(other: &float_ty) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type ty = {id: node_id, node: ty_, span: span};
 
 // Not represented directly in the AST, referred to by name through a ty_path.
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum prim_ty {
@@ -1086,10 +1180,14 @@ impl prim_ty : cmp::Eq {
     pure fn ne(other: &prim_ty) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type region = {id: node_id, node: region_};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum region_ {
@@ -1099,6 +1197,8 @@ enum region_ {
     re_named(ident)
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum ty_ {
@@ -1139,10 +1239,14 @@ impl ty : to_bytes::IterBytes {
 }
 
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type arg = {mode: mode, ty: @ty, ident: ident, id: node_id};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type fn_decl =
@@ -1150,6 +1254,8 @@ type fn_decl =
      output: @ty,
      cf: ret_style};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum purity {
@@ -1172,6 +1278,8 @@ impl purity : cmp::Eq {
     pure fn ne(other: &purity) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum ret_style {
@@ -1198,6 +1306,8 @@ impl ret_style : cmp::Eq {
     pure fn ne(other: &ret_style) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum self_ty_ {
@@ -1255,6 +1365,8 @@ impl self_ty_ : cmp::Eq {
 
 type self_ty = spanned<self_ty_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type method = {ident: ident, attrs: ~[attribute],
@@ -1263,10 +1375,14 @@ type method = {ident: ident, attrs: ~[attribute],
                id: node_id, span: span, self_id: node_id,
                vis: visibility};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type _mod = {view_items: ~[@view_item], items: ~[@item]};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum foreign_abi {
@@ -1276,6 +1392,8 @@ enum foreign_abi {
 }
 
 // Foreign mods can be named or anonymous
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum foreign_mod_sort { named, anonymous }
@@ -1301,6 +1419,8 @@ impl foreign_abi : cmp::Eq {
     pure fn ne(other: &foreign_abi) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type foreign_mod =
@@ -1308,10 +1428,14 @@ type foreign_mod =
      view_items: ~[@view_item],
      items: ~[@foreign_item]};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type variant_arg = {ty: @ty, id: node_id};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum variant_kind {
@@ -1320,14 +1444,20 @@ enum variant_kind {
     enum_variant_kind(enum_def)
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type enum_def_ = { variants: ~[variant], common: Option<@struct_def> };
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum enum_def = enum_def_;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
@@ -1335,12 +1465,16 @@ type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
 
 type variant = spanned<variant_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type path_list_ident_ = {name: ident, id: node_id};
 
 type path_list_ident = spanned<path_list_ident_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum namespace { module_ns, type_value_ns }
@@ -1354,6 +1488,8 @@ impl namespace : cmp::Eq {
 
 type view_path = spanned<view_path_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum view_path_ {
@@ -1372,11 +1508,15 @@ enum view_path_ {
     view_path_list(@path, ~[path_list_ident], node_id)
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type view_item = {node: view_item_, attrs: ~[attribute],
                   vis: visibility, span: span};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum view_item_ {
@@ -1391,6 +1531,8 @@ 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_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum attr_style { attr_outer, attr_inner, }
@@ -1403,6 +1545,8 @@ impl attr_style : cmp::Eq {
 }
 
 // doc-comments are promoted to attributes that have is_sugared_doc = true
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool};
@@ -1416,10 +1560,14 @@ type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool};
   conceptually, the impl_id stands in for the pair of (this class, this
   trait)
  */
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum visibility { public, private, inherited }
@@ -1438,6 +1586,8 @@ impl visibility : cmp::Eq {
     pure fn ne(other: &visibility) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type struct_field_ = {
@@ -1448,6 +1598,8 @@ type struct_field_ = {
 
 type struct_field = spanned<struct_field_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum struct_field_kind {
@@ -1455,6 +1607,8 @@ enum struct_field_kind {
     unnamed_field   // element of a tuple-like struct
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type struct_def = {
@@ -1472,12 +1626,16 @@ type struct_def = {
   FIXME (#3300): Should allow items to be anonymous. Right now
   we just use dummy names for anon items.
  */
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type item = {ident: ident, attrs: ~[attribute],
              id: node_id, node: item_,
              vis: visibility, span: span};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum item_ {
@@ -1496,6 +1654,8 @@ enum item_ {
     item_mac(mac),
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum class_mutability { class_mutable, class_immutable }
@@ -1520,6 +1680,8 @@ impl class_mutability : cmp::Eq {
 
 type class_ctor = spanned<class_ctor_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type class_ctor_ = {id: node_id,
@@ -1530,6 +1692,8 @@ type class_ctor_ = {id: node_id,
 
 type class_dtor = spanned<class_dtor_>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type class_dtor_ = {id: node_id,
@@ -1537,6 +1701,8 @@ type class_dtor_ = {id: node_id,
                     self_id: node_id,
                     body: blk};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type foreign_item =
@@ -1547,6 +1713,8 @@ type foreign_item =
      span: span,
      vis: visibility};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum foreign_item_ {
@@ -1557,6 +1725,8 @@ 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_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum inlined_item {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 47cbdb7ac6c..897a51f710c 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -406,6 +406,8 @@ fn dtor_dec() -> fn_decl {
 // ______________________________________________________________________
 // Enumerating the IDs which appear in an AST
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type id_range = {min: node_id, max: node_id};
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index 63a6551bf88..b06536f4e02 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -1,62 +1,64 @@
 /*
 
-The compiler code necessary to implement the #[auto_serialize]
-extension.  The idea here is that type-defining items may be tagged
-with #[auto_serialize], which will cause us to generate a little
-companion module with the same name as the item.
+The compiler code necessary to implement the #[auto_serialize] and
+#[auto_deserialize] extension.  The idea here is that type-defining items may
+be tagged with #[auto_serialize] and #[auto_deserialize], which will cause
+us to generate a little companion module with the same name as the item.
 
 For example, a type like:
 
-    type node_id = uint;
+    #[auto_serialize]
+    #[auto_deserialize]
+    struct Node {id: uint}
 
-would generate two functions like:
+would generate two implementations like:
 
-    fn serialize_node_id<S: serializer>(s: S, v: node_id) {
-        s.emit_uint(v);
+    impl Node: Serializable {
+        fn serialize<S: Serializer>(s: &S) {
+            do s.emit_struct("Node") {
+                s.emit_field("id", 0, || s.emit_uint(self))
+            }
+        }
     }
-    fn deserialize_node_id<D: deserializer>(d: D) -> node_id {
-        d.read_uint()
+
+    impl node_id: Deserializable {
+        static fn deserialize<D: Deserializer>(d: &D) -> Node {
+            do d.read_struct("Node") {
+                Node {
+                    id: d.read_field(~"x", 0, || deserialize(d))
+                }
+            }
+        }
     }
 
 Other interesting scenarios are whe the item has type parameters or
 references other non-built-in types.  A type definition like:
 
+    #[auto_serialize]
+    #[auto_deserialize]
     type spanned<T> = {node: T, span: span};
 
 would yield functions like:
 
-    fn serialize_spanned<S: serializer,T>(s: S, v: spanned<T>, t: fn(T)) {
-         s.emit_rec(2u) {||
-             s.emit_rec_field("node", 0u) {||
-                 t(s.node);
-             };
-             s.emit_rec_field("span", 1u) {||
-                 serialize_span(s, s.span);
-             };
-         }
-    }
-    fn deserialize_spanned<D: deserializer>(d: D, t: fn() -> T) -> node_id {
-         d.read_rec(2u) {||
-             {node: d.read_rec_field("node", 0u, t),
-              span: d.read_rec_field("span", 1u) {||deserialize_span(d)}}
-         }
+    impl<T: Serializable> spanned<T>: Serializable {
+        fn serialize<S: Serializer>(s: &S) {
+            do s.emit_rec {
+                s.emit_field("node", 0, || self.node.serialize(s));
+                s.emit_field("span", 1, || self.span.serialize(s));
+            }
+        }
     }
 
-In general, the code to serialize an instance `v` of a non-built-in
-type a::b::c<T0,...,Tn> looks like:
-
-    a::b::serialize_c(s, {|v| c_T0}, ..., {|v| c_Tn}, v)
-
-where `c_Ti` is the code to serialize an instance `v` of the type
-`Ti`.
-
-Similarly, the code to deserialize an instance of a non-built-in type
-`a::b::c<T0,...,Tn>` using the deserializer `d` looks like:
-
-    a::b::deserialize_c(d, {|| c_T0}, ..., {|| c_Tn})
-
-where `c_Ti` is the code to deserialize an instance of `Ti` using the
-deserializer `d`.
+    impl<T: Deserializable> spanned<T>: Deserializable {
+        static fn deserialize<D: Deserializer>(d: &D) -> spanned<T> {
+            do d.read_rec {
+                {
+                    node: d.read_field(~"node", 0, || deserialize(d)),
+                    span: d.read_field(~"span", 1, || deserialize(d)),
+                }
+            }
+        }
+    }
 
 FIXME (#2810)--Hygiene. Search for "__" strings.  We also assume "std" is the
 standard library.
@@ -69,788 +71,1035 @@ into the tree.  This is intended to prevent us from inserting the same
 node twice.
 
 */
+
 use base::*;
 use codemap::span;
 use std::map;
 use std::map::HashMap;
 
-export expand;
+export expand_auto_serialize;
+export expand_auto_deserialize;
 
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
-    #[legacy_exports];
     pub use ext;
     pub use parse;
 }
 
-type ser_tps_map = map::HashMap<ast::ident, fn@(@ast::expr) -> ~[@ast::stmt]>;
-type deser_tps_map = map::HashMap<ast::ident, fn@() -> @ast::expr>;
+fn expand_auto_serialize(
+    cx: ext_ctxt,
+    span: span,
+    _mitem: ast::meta_item,
+    in_items: ~[@ast::item]
+) -> ~[@ast::item] {
+    fn is_auto_serialize(a: &ast::attribute) -> bool {
+        attr::get_attr_name(*a) == ~"auto_serialize"
+    }
+
+    fn filter_attrs(item: @ast::item) -> @ast::item {
+        @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize(a)),
+          .. *item}
+    }
+
+    do vec::flat_map(in_items) |item| {
+        if item.attrs.any(is_auto_serialize) {
+            match item.node {
+                ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => {
+                    let ser_impl = mk_rec_ser_impl(
+                        cx,
+                        item.span,
+                        item.ident,
+                        fields,
+                        tps
+                    );
+
+                    ~[filter_attrs(*item), ser_impl]
+                },
+                ast::item_class(@{ fields, _}, tps) => {
+                    let ser_impl = mk_struct_ser_impl(
+                        cx,
+                        item.span,
+                        item.ident,
+                        fields,
+                        tps
+                    );
+
+                    ~[filter_attrs(*item), ser_impl]
+                },
+                ast::item_enum(enum_def, tps) => {
+                    let ser_impl = mk_enum_ser_impl(
+                        cx,
+                        item.span,
+                        item.ident,
+                        enum_def,
+                        tps
+                    );
+
+                    ~[filter_attrs(*item), ser_impl]
+                },
+                _ => {
+                    cx.span_err(span, ~"#[auto_serialize] can only be \
+                                        applied to structs, record types, \
+                                        and enum definitions");
+                    ~[*item]
+                }
+            }
+        } else {
+            ~[*item]
+        }
+    }
+}
 
-fn expand(cx: ext_ctxt,
-          span: span,
-          _mitem: ast::meta_item,
-          in_items: ~[@ast::item]) -> ~[@ast::item] {
-    fn not_auto_serialize(a: &ast::attribute) -> bool {
-        attr::get_attr_name(*a) != ~"auto_serialize"
+fn expand_auto_deserialize(
+    cx: ext_ctxt,
+    span: span,
+    _mitem: ast::meta_item,
+    in_items: ~[@ast::item]
+) -> ~[@ast::item] {
+    fn is_auto_deserialize(a: &ast::attribute) -> bool {
+        attr::get_attr_name(*a) == ~"auto_deserialize"
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
-        @{attrs: vec::filter(item.attrs, not_auto_serialize),
+        @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize(a)),
           .. *item}
     }
 
-    do vec::flat_map(in_items) |in_item| {
-        match in_item.node {
-          ast::item_ty(ty, tps) => {
-            vec::append(~[filter_attrs(*in_item)],
-                        ty_fns(cx, in_item.ident, ty, tps))
-          }
-
-          ast::item_enum(enum_definition, tps) => {
-            vec::append(~[filter_attrs(*in_item)],
-                        enum_fns(cx, in_item.ident,
-                                 in_item.span, enum_definition.variants, tps))
-          }
-
-          _ => {
-            cx.span_err(span, ~"#[auto_serialize] can only be \
-                               applied to type and enum \
-                               definitions");
-            ~[*in_item]
-          }
+    do vec::flat_map(in_items) |item| {
+        if item.attrs.any(is_auto_deserialize) {
+            match item.node {
+                ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => {
+                    let deser_impl = mk_rec_deser_impl(
+                        cx,
+                        item.span,
+                        item.ident,
+                        fields,
+                        tps
+                    );
+
+                    ~[filter_attrs(*item), deser_impl]
+                },
+                ast::item_class(@{ fields, _}, tps) => {
+                    let deser_impl = mk_struct_deser_impl(
+                        cx,
+                        item.span,
+                        item.ident,
+                        fields,
+                        tps
+                    );
+
+                    ~[filter_attrs(*item), deser_impl]
+                },
+                ast::item_enum(enum_def, tps) => {
+                    let deser_impl = mk_enum_deser_impl(
+                        cx,
+                        item.span,
+                        item.ident,
+                        enum_def,
+                        tps
+                    );
+
+                    ~[filter_attrs(*item), deser_impl]
+                },
+                _ => {
+                    cx.span_err(span, ~"#[auto_deserialize] can only be \
+                                        applied to structs, record types, \
+                                        and enum definitions");
+                    ~[*item]
+                }
+            }
+        } else {
+            ~[*item]
         }
     }
 }
 
 priv impl ext_ctxt {
-    fn helper_path(base_path: @ast::path,
-                   helper_name: ~str) -> @ast::path {
-        let head = vec::init(base_path.idents);
-        let tail = vec::last(base_path.idents);
-        self.path(base_path.span,
-                  vec::append(head,
-                              ~[self.parse_sess().interner.
-                                intern(@(helper_name + ~"_" +
-                                         *self.parse_sess().interner.get(
-                                             tail)))]))
-    }
-
-    fn ty_fn(span: span,
-             -input_tys: ~[@ast::ty],
-             -output: @ast::ty) -> @ast::ty {
-        let args = do vec::map(input_tys) |ty| {
-            {mode: ast::expl(ast::by_ref),
-             ty: *ty,
-             ident: parse::token::special_idents::invalid,
-             id: self.next_id()}
-        };
+    fn expr(span: span, node: ast::expr_) -> @ast::expr {
+        @{id: self.next_id(), callee_id: self.next_id(),
+          node: node, span: span}
+    }
+
+    fn path(span: span, strs: ~[ast::ident]) -> @ast::path {
+        @{span: span, global: false, idents: strs, rp: None, types: ~[]}
+    }
 
+    fn path_tps(span: span, strs: ~[ast::ident],
+                tps: ~[@ast::ty]) -> @ast::path {
+        @{span: span, global: false, idents: strs, rp: None, types: tps}
+    }
+
+    fn ty_path(span: span, strs: ~[ast::ident],
+               tps: ~[@ast::ty]) -> @ast::ty {
         @{id: self.next_id(),
-          node: ast::ty_fn(ast::proto_block,
-                           ast::impure_fn,
-                           @~[],
-                           {inputs: args,
-                            output: output,
-                            cf: ast::return_val}),
+          node: ast::ty_path(self.path_tps(span, strs, tps), self.next_id()),
           span: span}
     }
 
-    fn ty_nil(span: span) -> @ast::ty {
-        @{id: self.next_id(), node: ast::ty_nil, span: span}
+    fn binder_pat(span: span, nm: ast::ident) -> @ast::pat {
+        let path = @{span: span, global: false, idents: ~[nm],
+                     rp: None, types: ~[]};
+        @{id: self.next_id(),
+          node: ast::pat_ident(ast::bind_by_implicit_ref,
+                               path,
+                               None),
+          span: span}
     }
 
-    fn var_ref(span: span, name: ast::ident) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path(span, ~[name])))
+    fn stmt(expr: @ast::expr) -> @ast::stmt {
+        @{node: ast::stmt_semi(expr, self.next_id()),
+          span: expr.span}
     }
 
-    fn alt_stmt(arms: ~[ast::arm],
-                span: span, -v: @ast::expr) -> @ast::stmt {
-        self.stmt(
-            self.expr(
-                span,
-                ast::expr_match(v, arms)))
+    fn lit_str(span: span, s: @~str) -> @ast::expr {
+        self.expr(
+            span,
+            ast::expr_vstore(
+                self.expr(
+                    span,
+                    ast::expr_lit(
+                        @{node: ast::lit_str(s),
+                          span: span})),
+                ast::expr_vstore_uniq))
     }
 
-    fn clone_folder() -> fold::ast_fold {
-        fold::make_fold(@{
-            new_id: |_id| self.next_id(),
-            .. *fold::default_ast_fold()
-        })
+    fn lit_uint(span: span, i: uint) -> @ast::expr {
+        self.expr(
+            span,
+            ast::expr_lit(
+                @{node: ast::lit_uint(i as u64, ast::ty_u),
+                  span: span}))
     }
 
-    fn clone(v: @ast::expr) -> @ast::expr {
-        let fld = self.clone_folder();
-        fld.fold_expr(v)
+    fn lambda(blk: ast::blk) -> @ast::expr {
+        let ext_cx = self;
+        let blk_e = self.expr(blk.span, ast::expr_block(blk));
+        #ast{ || $(blk_e) }
     }
 
-    fn clone_ty(v: @ast::ty) -> @ast::ty {
-        let fld = self.clone_folder();
-        fld.fold_ty(v)
+    fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk {
+        {node: {view_items: ~[],
+                stmts: stmts,
+                expr: None,
+                id: self.next_id(),
+                rules: ast::default_blk},
+         span: span}
     }
 
-    fn clone_ty_param(v: ast::ty_param) -> ast::ty_param {
-        let fld = self.clone_folder();
-        fold::fold_ty_param(v, fld)
+    fn expr_blk(expr: @ast::expr) -> ast::blk {
+        {node: {view_items: ~[],
+                stmts: ~[],
+                expr: Some(expr),
+                id: self.next_id(),
+                rules: ast::default_blk},
+         span: expr.span}
     }
 
-    fn at(span: span, expr: @ast::expr) -> @ast::expr {
-        fn repl_sp(old_span: span, repl_span: span, with_span: span) -> span {
-            if old_span == repl_span {
-                with_span
-            } else {
-                old_span
-            }
-        }
+    fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr {
+        self.expr(span, ast::expr_path(self.path(span, strs)))
+    }
 
-        let fld = fold::make_fold(@{
-            new_span: |a| repl_sp(a, ast_util::dummy_sp(), span),
-            .. *fold::default_ast_fold()
-        });
+    fn expr_var(span: span, var: ~str) -> @ast::expr {
+        self.expr_path(span, ~[self.ident_of(var)])
+    }
 
-        fld.fold_expr(expr)
+    fn expr_field(
+        span: span,
+        expr: @ast::expr,
+        ident: ast::ident
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_field(expr, ident, ~[]))
     }
-}
 
-fn ser_path(cx: ext_ctxt, tps: ser_tps_map, path: @ast::path,
-                  -s: @ast::expr, -v: @ast::expr)
-    -> ~[@ast::stmt] {
-    let ext_cx = cx; // required for #ast{}
-
-    // We want to take a path like a::b::c<...> and generate a call
-    // like a::b::c::serialize(s, ...), as described above.
-
-    let callee =
-        cx.expr(
-            path.span,
-            ast::expr_path(
-                cx.helper_path(path, ~"serialize")));
-
-    let ty_args = do vec::map(path.types) |ty| {
-        let sv_stmts = ser_ty(cx, tps, *ty, cx.clone(s), #ast{ __v });
-        let sv = cx.expr(path.span,
-                         ast::expr_block(cx.blk(path.span, sv_stmts)));
-        cx.at(ty.span, #ast{ |__v| $(sv) })
-    };
+    fn expr_call(
+        span: span,
+        expr: @ast::expr,
+        args: ~[@ast::expr]
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_call(expr, args, false))
+    }
 
-    ~[cx.stmt(
-        cx.expr(
-            path.span,
-            ast::expr_call(callee, vec::append(~[s, v], ty_args), false)))]
+    fn lambda_expr(expr: @ast::expr) -> @ast::expr {
+        self.lambda(self.expr_blk(expr))
+    }
+
+    fn lambda_stmts(span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
+        self.lambda(self.blk(span, stmts))
+    }
 }
 
-fn ser_variant(cx: ext_ctxt,
-               tps: ser_tps_map,
-               tys: ~[@ast::ty],
-               span: span,
-               -s: @ast::expr,
-               pfn: fn(~[@ast::pat]) -> ast::pat_,
-               bodyfn: fn(-v: @ast::expr, ast::blk) -> @ast::expr,
-               argfn: fn(-v: @ast::expr, uint, ast::blk) -> @ast::expr)
-    -> ast::arm {
-    let vnames = do vec::from_fn(vec::len(tys)) |i| {
-        cx.parse_sess().interner.intern(@fmt!("__v%u", i))
-    };
-    let pats = do vec::from_fn(vec::len(tys)) |i| {
-        cx.binder_pat(tys[i].span, vnames[i])
-    };
-    let pat: @ast::pat = @{id: cx.next_id(), node: pfn(pats), span: span};
-    let stmts = do vec::from_fn(vec::len(tys)) |i| {
-        let v = cx.var_ref(span, vnames[i]);
-        let arg_blk =
-            cx.blk(
-                span,
-                ser_ty(cx, tps, tys[i], cx.clone(s), move v));
-        cx.stmt(argfn(cx.clone(s), i, arg_blk))
-    };
+fn mk_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    path: @ast::path,
+    tps: ~[ast::ty_param],
+    f: fn(@ast::ty) -> @ast::method
+) -> @ast::item {
+    // All the type parameters need to bound to the trait.
+    let trait_tps = do tps.map |tp| {
+        let t_bound = ast::bound_trait(@{
+            id: cx.next_id(),
+            node: ast::ty_path(path, cx.next_id()),
+            span: span,
+        });
 
-    let body_blk = cx.blk(span, stmts);
-    let body = cx.blk(span, ~[cx.stmt(bodyfn(move s, body_blk))]);
+        {
+            ident: tp.ident,
+            id: cx.next_id(),
+            bounds: @vec::append(~[t_bound], *tp.bounds)
+        }
+    };
 
-    {pats: ~[pat], guard: None, body: body}
+    let opt_trait = Some(@{
+        path: path,
+        ref_id: cx.next_id(),
+        impl_id: cx.next_id(),
+    });
+
+    let ty = cx.ty_path(
+        span,
+        ~[ident],
+        tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[]))
+    );
+
+    @{
+        // This is a new-style impl declaration.
+        // XXX: clownshoes
+        ident: ast::token::special_idents::clownshoes_extensions,
+        attrs: ~[],
+        id: cx.next_id(),
+        node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]),
+        vis: ast::public,
+        span: span,
+    }
 }
 
-fn ser_lambda(cx: ext_ctxt, tps: ser_tps_map, ty: @ast::ty,
-              -s: @ast::expr, -v: @ast::expr) -> @ast::expr {
-    cx.lambda(cx.blk(ty.span, ser_ty(cx, tps, ty, move s, move v)))
+fn mk_ser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    tps: ~[ast::ty_param],
+    body: @ast::expr
+) -> @ast::item {
+    // Make a path to the std::serialization::Serializable trait.
+    let path = cx.path(
+        span,
+        ~[
+            cx.ident_of(~"std"),
+            cx.ident_of(~"serialization"),
+            cx.ident_of(~"Serializable"),
+        ]
+    );
+
+    mk_impl(
+        cx,
+        span,
+        ident,
+        path,
+        tps,
+        |_ty| mk_ser_method(cx, span, cx.expr_blk(body))
+    )
 }
 
-fn is_vec_or_str(ty: @ast::ty) -> bool {
-    match ty.node {
-      ast::ty_vec(_) => true,
-      // This may be wrong if the user has shadowed (!) str
-      ast::ty_path(@{span: _, global: _, idents: ids,
-                             rp: None, types: _}, _)
-      if ids == ~[parse::token::special_idents::str] => true,
-      _ => false
-    }
+fn mk_deser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    tps: ~[ast::ty_param],
+    body: @ast::expr
+) -> @ast::item {
+    // Make a path to the std::serialization::Deserializable trait.
+    let path = cx.path(
+        span,
+        ~[
+            cx.ident_of(~"std"),
+            cx.ident_of(~"serialization"),
+            cx.ident_of(~"Deserializable"),
+        ]
+    );
+
+    mk_impl(
+        cx,
+        span,
+        ident,
+        path,
+        tps,
+        |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body))
+    )
 }
 
-fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
-          ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
-    -> ~[@ast::stmt] {
-
-    let ext_cx = cx; // required for #ast{}
-
-    match ty.node {
-      ast::ty_nil => {
-        ~[#ast[stmt]{$(s).emit_nil()}]
-      }
-
-      ast::ty_bot => {
-        cx.span_err(
-            ty.span, fmt!("Cannot serialize bottom type"));
+fn mk_ser_method(
+    cx: ext_ctxt,
+    span: span,
+    ser_body: ast::blk
+) -> @ast::method {
+    let ser_bound = cx.ty_path(
+        span,
+        ~[
+            cx.ident_of(~"std"),
+            cx.ident_of(~"serialization"),
+            cx.ident_of(~"Serializer"),
+        ],
         ~[]
-      }
-
-      ast::ty_box(mt) => {
-        let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) });
-        ~[#ast[stmt]{$(s).emit_box($(l));}]
-      }
+    );
+
+    let ser_tps = ~[{
+        ident: cx.ident_of(~"__S"),
+        id: cx.next_id(),
+        bounds: @~[ast::bound_trait(ser_bound)],
+    }];
+
+    let ty_s = @{
+        id: cx.next_id(),
+        node: ast::ty_rptr(
+            @{
+                id: cx.next_id(),
+                node: ast::re_anon,
+            },
+            {
+                ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]),
+                mutbl: ast::m_imm
+            }
+        ),
+        span: span,
+    };
 
-      // For unique evecs/estrs, just pass through to underlying vec or str
-      ast::ty_uniq(mt) if is_vec_or_str(mt.ty) => {
-        ser_ty(cx, tps, mt.ty, move s, move v)
-      }
+    let ser_inputs = ~[{
+        mode: ast::infer(cx.next_id()),
+        ty: ty_s,
+        ident: cx.ident_of(~"__s"),
+        id: cx.next_id(),
+    }];
+
+    let ser_output = @{
+        id: cx.next_id(),
+        node: ast::ty_nil,
+        span: span,
+    };
 
-      ast::ty_uniq(mt) => {
-        let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) });
-        ~[#ast[stmt]{$(s).emit_uniq($(l));}]
-      }
+    let ser_decl = {
+        inputs: ser_inputs,
+        output: ser_output,
+        cf: ast::return_val,
+    };
 
-      ast::ty_ptr(_) | ast::ty_rptr(_, _) => {
-        cx.span_err(ty.span, ~"cannot serialize pointer types");
-        ~[]
-      }
-
-      ast::ty_rec(flds) => {
-        let fld_stmts = do vec::from_fn(vec::len(flds)) |fidx| {
-            let fld = flds[fidx];
-            let vf = cx.expr(fld.span,
-                             ast::expr_field(cx.clone(v),
-                                             fld.node.ident,
-                                             ~[]));
-            let s = cx.clone(s);
-            let f = cx.lit_str(fld.span, cx.parse_sess().interner.get(
-                fld.node.ident));
-            let i = cx.lit_uint(fld.span, fidx);
-            let l = ser_lambda(cx, tps, fld.node.mt.ty, cx.clone(s), move vf);
-            #ast[stmt]{$(s).emit_rec_field($(f), $(i), $(l));}
-        };
-        let fld_lambda = cx.lambda(cx.blk(ty.span, fld_stmts));
-        ~[#ast[stmt]{$(s).emit_rec($(fld_lambda));}]
-      }
+    @{
+        ident: cx.ident_of(~"serialize"),
+        attrs: ~[],
+        tps: ser_tps,
+        self_ty: { node: ast::sty_region(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,
+    }
+}
 
-      ast::ty_fn(*) => {
-        cx.span_err(ty.span, ~"cannot serialize function types");
+fn mk_deser_method(
+    cx: ext_ctxt,
+    span: span,
+    ty: @ast::ty,
+    deser_body: ast::blk
+) -> @ast::method {
+    let deser_bound = cx.ty_path(
+        span,
+        ~[
+            cx.ident_of(~"std"),
+            cx.ident_of(~"serialization"),
+            cx.ident_of(~"Deserializer"),
+        ],
         ~[]
-      }
-
-      ast::ty_tup(tys) => {
-        // Generate code like
-        //
-        // match v {
-        //    (v1, v2, v3) {
-        //       .. serialize v1, v2, v3 ..
-        //    }
-        // };
-
-        let arms = ~[
-            ser_variant(
-
-                cx, tps, tys, ty.span, move s,
-
-                // Generate pattern (v1, v2, v3)
-                |pats| ast::pat_tup(pats),
-
-                // Generate body s.emit_tup(3, {|| blk })
-                |-s, blk| {
-                    let sz = cx.lit_uint(ty.span, vec::len(tys));
-                    let body = cx.lambda(blk);
-                    #ast{ $(s).emit_tup($(sz), $(body)) }
-                },
-
-                // Generate s.emit_tup_elt(i, {|| blk })
-                |-s, i, blk| {
-                    let idx = cx.lit_uint(ty.span, i);
-                    let body = cx.lambda(blk);
-                    #ast{ $(s).emit_tup_elt($(idx), $(body)) }
-                })
-        ];
-        ~[cx.alt_stmt(arms, ty.span, move v)]
-      }
-
-      ast::ty_path(path, _) => {
-        if path.idents.len() == 1 && path.types.is_empty() {
-            let ident = path.idents[0];
-
-            match tps.find(ident) {
-              Some(f) => f(v),
-              None => ser_path(cx, tps, path, move s, move v)
+    );
+
+    let deser_tps = ~[{
+        ident: cx.ident_of(~"__D"),
+        id: cx.next_id(),
+        bounds: @~[ast::bound_trait(deser_bound)],
+    }];
+
+    let ty_d = @{
+        id: cx.next_id(),
+        node: ast::ty_rptr(
+            @{
+                id: cx.next_id(),
+                node: ast::re_anon,
+            },
+            {
+                ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]),
+                mutbl: ast::m_imm
             }
-        } else {
-            ser_path(cx, tps, path, move s, move v)
-        }
-      }
-
-      ast::ty_mac(_) => {
-        cx.span_err(ty.span, ~"cannot serialize macro types");
-        ~[]
-      }
+        ),
+        span: span,
+    };
 
-      ast::ty_infer => {
-        cx.span_err(ty.span, ~"cannot serialize inferred types");
-        ~[]
-      }
+    let deser_inputs = ~[{
+        mode: ast::infer(cx.next_id()),
+        ty: ty_d,
+        ident: cx.ident_of(~"__d"),
+        id: cx.next_id(),
+    }];
+
+    let deser_decl = {
+        inputs: deser_inputs,
+        output: ty,
+        cf: ast::return_val,
+    };
 
-      ast::ty_vec(mt) => {
-        let ser_e =
-            cx.expr(
-                ty.span,
-                ast::expr_block(
-                    cx.blk(
-                        ty.span,
-                        ser_ty(
-                            cx, tps, mt.ty,
-                            cx.clone(s),
-                            cx.at(ty.span, #ast{ __e })))));
-
-        ~[#ast[stmt]{
-            std::serialization::emit_from_vec($(s), $(v), |__e| $(ser_e))
-        }]
-      }
-
-      ast::ty_fixed_length(_, _) => {
-        cx.span_unimpl(ty.span, ~"serialization for fixed length types");
-      }
+    @{
+        ident: cx.ident_of(~"deserialize"),
+        attrs: ~[],
+        tps: deser_tps,
+        self_ty: { 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_ser_fn(cx: ext_ctxt, span: span, name: ast::ident,
-             tps: ~[ast::ty_param],
-             f: fn(ext_ctxt, ser_tps_map,
-                   -v: @ast::expr, -v: @ast::expr) -> ~[@ast::stmt])
-    -> @ast::item {
-    let ext_cx = cx; // required for #ast
-
-    let tp_types = vec::map(tps, |tp| cx.ty_path(span, ~[tp.ident], ~[]));
-    let v_ty = cx.ty_path(span, ~[name], tp_types);
-
-    let tp_inputs =
-        vec::map(tps, |tp|
-            {mode: ast::expl(ast::by_ref),
-             ty: cx.ty_fn(span,
-                          ~[cx.ty_path(span, ~[tp.ident], ~[])],
-                          cx.ty_nil(span)),
-             ident: cx.ident_of(~"__s" + cx.str_of(tp.ident)),
-             id: cx.next_id()});
-
-    debug!("tp_inputs = %?", tp_inputs);
-
-
-    let ser_inputs: ~[ast::arg] =
-        vec::append(~[{mode: ast::expl(ast::by_ref),
-                      ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]),
-                      ident: cx.ident_of(~"__s"),
-                      id: cx.next_id()},
-                     {mode: ast::expl(ast::by_ref),
-                      ty: v_ty,
-                      ident: cx.ident_of(~"__v"),
-                      id: cx.next_id()}],
-                    tp_inputs);
-
-    let tps_map = map::HashMap();
-    for vec::each2(tps, tp_inputs) |tp, arg| {
-        let arg_ident = arg.ident;
-        tps_map.insert(
-            tp.ident,
-            fn@(v: @ast::expr) -> ~[@ast::stmt] {
-                let f = cx.var_ref(span, arg_ident);
-                debug!("serializing type arg %s", cx.str_of(arg_ident));
-                ~[#ast[stmt]{$(f)($(v));}]
-            });
-    }
-
-    let ser_bnds = @~[
-        ast::bound_trait(cx.ty_path(span,
-                                    ~[cx.ident_of(~"std"),
-                                      cx.ident_of(~"serialization"),
-                                      cx.ident_of(~"Serializer")],
-                                    ~[]))];
-
-    let ser_tps: ~[ast::ty_param] =
-        vec::append(~[{ident: cx.ident_of(~"__S"),
-                      id: cx.next_id(),
-                      bounds: ser_bnds}],
-                    vec::map(tps, |tp| cx.clone_ty_param(*tp)));
-
-    let ser_output: @ast::ty = @{id: cx.next_id(),
-                                 node: ast::ty_nil,
-                                 span: span};
-
-    let ser_blk = cx.blk(span,
-                         f(cx, tps_map, #ast{ __s }, #ast{ __v }));
-
-    @{ident: cx.ident_of(~"serialize_" + cx.str_of(name)),
-      attrs: ~[],
-      id: cx.next_id(),
-      node: ast::item_fn({inputs: ser_inputs,
-                          output: ser_output,
-                          cf: ast::return_val},
-                         ast::impure_fn,
-                         ser_tps,
-                         ser_blk),
-      vis: ast::public,
-      span: span}
-}
-
-// ______________________________________________________________________
-
-fn deser_path(cx: ext_ctxt, tps: deser_tps_map, path: @ast::path,
-                    -d: @ast::expr) -> @ast::expr {
-    // We want to take a path like a::b::c<...> and generate a call
-    // like a::b::c::deserialize(d, ...), as described above.
+fn mk_rec_ser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    fields: ~[ast::ty_field],
+    tps: ~[ast::ty_param]
+) -> @ast::item {
+    let fields = mk_ser_fields(cx, span, mk_rec_fields(fields));
+
+    // ast for `__s.emit_rec(|| $(fields))`
+    let body = cx.expr_call(
+        span,
+        cx.expr_field(
+            span,
+            cx.expr_var(span, ~"__s"),
+            cx.ident_of(~"emit_rec")
+        ),
+        ~[cx.lambda_stmts(span, fields)]
+    );
 
-    let callee =
-        cx.expr(
-            path.span,
-            ast::expr_path(
-                cx.helper_path(path, ~"deserialize")));
+    mk_ser_impl(cx, span, ident, tps, body)
+}
 
-    let ty_args = do vec::map(path.types) |ty| {
-        let dv_expr = deser_ty(cx, tps, *ty, cx.clone(d));
-        cx.lambda(cx.expr_blk(dv_expr))
-    };
+fn mk_rec_deser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    fields: ~[ast::ty_field],
+    tps: ~[ast::ty_param]
+) -> @ast::item {
+    let fields = mk_deser_fields(cx, span, mk_rec_fields(fields));
+
+    // ast for `read_rec(|| $(fields))`
+    let body = cx.expr_call(
+        span,
+        cx.expr_field(
+            span,
+            cx.expr_var(span, ~"__d"),
+            cx.ident_of(~"read_rec")
+        ),
+        ~[
+            cx.lambda_expr(
+                cx.expr(
+                    span,
+                    ast::expr_rec(fields, None)
+                )
+            )
+        ]
+    );
+
+    mk_deser_impl(cx, span, ident, tps, body)
+}
 
-    cx.expr(path.span, ast::expr_call(callee, vec::append(~[d], ty_args),
-                                      false))
+fn mk_struct_ser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    fields: ~[@ast::struct_field],
+    tps: ~[ast::ty_param]
+) -> @ast::item {
+    let fields = mk_ser_fields(cx, span, mk_struct_fields(fields));
+
+    // ast for `__s.emit_struct($(name), || $(fields))`
+    let ser_body = cx.expr_call(
+        span,
+        cx.expr_field(
+            span,
+            cx.expr_var(span, ~"__s"),
+            cx.ident_of(~"emit_struct")
+        ),
+        ~[
+            cx.lit_str(span, @cx.str_of(ident)),
+            cx.lambda_stmts(span, fields),
+        ]
+    );
+
+    mk_ser_impl(cx, span, ident, tps, ser_body)
 }
 
-fn deser_lambda(cx: ext_ctxt, tps: deser_tps_map, ty: @ast::ty,
-                -d: @ast::expr) -> @ast::expr {
-    cx.lambda(cx.expr_blk(deser_ty(cx, tps, ty, move d)))
+fn mk_struct_deser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    fields: ~[@ast::struct_field],
+    tps: ~[ast::ty_param]
+) -> @ast::item {
+    let fields = mk_deser_fields(cx, span, mk_struct_fields(fields));
+
+    // ast for `read_struct($(name), || $(fields))`
+    let body = cx.expr_call(
+        span,
+        cx.expr_field(
+            span,
+            cx.expr_var(span, ~"__d"),
+            cx.ident_of(~"read_struct")
+        ),
+        ~[
+            cx.lit_str(span, @cx.str_of(ident)),
+            cx.lambda_expr(
+                cx.expr(
+                    span,
+                    ast::expr_struct(
+                        cx.path(span, ~[ident]),
+                        fields,
+                        None
+                    )
+                )
+            ),
+        ]
+    );
+
+    mk_deser_impl(cx, span, ident, tps, body)
 }
 
-fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
-                  ty: @ast::ty, -d: @ast::expr) -> @ast::expr {
-
-    let ext_cx = cx; // required for #ast{}
-
-    match ty.node {
-      ast::ty_nil => {
-        #ast{ $(d).read_nil() }
-      }
-
-      ast::ty_bot => {
-        #ast{ fail }
-      }
-
-      ast::ty_box(mt) => {
-        let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
-        #ast{ @$(d).read_box($(l)) }
-      }
-
-      // For unique evecs/estrs, just pass through to underlying vec or str
-      ast::ty_uniq(mt) if is_vec_or_str(mt.ty) => {
-        deser_ty(cx, tps, mt.ty, move d)
-      }
-
-      ast::ty_uniq(mt) => {
-        let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
-        #ast{ ~$(d).read_uniq($(l)) }
-      }
-
-      ast::ty_ptr(_) | ast::ty_rptr(_, _) => {
-        #ast{ fail }
-      }
-
-      ast::ty_rec(flds) => {
-        let fields = do vec::from_fn(vec::len(flds)) |fidx| {
-            let fld = flds[fidx];
-            let d = cx.clone(d);
-            let f = cx.lit_str(fld.span, @cx.str_of(fld.node.ident));
-            let i = cx.lit_uint(fld.span, fidx);
-            let l = deser_lambda(cx, tps, fld.node.mt.ty, cx.clone(d));
-            {node: {mutbl: fld.node.mt.mutbl,
-                    ident: fld.node.ident,
-                    expr: #ast{ $(d).read_rec_field($(f), $(i), $(l))} },
-             span: fld.span}
-        };
-        let fld_expr = cx.expr(ty.span, ast::expr_rec(fields, None));
-        let fld_lambda = cx.lambda(cx.expr_blk(fld_expr));
-        #ast{ $(d).read_rec($(fld_lambda)) }
-      }
-
-      ast::ty_fn(*) => {
-        #ast{ fail }
-      }
-
-      ast::ty_tup(tys) => {
-        // Generate code like
-        //
-        // d.read_tup(3u) {||
-        //   (d.read_tup_elt(0u, {||...}),
-        //    d.read_tup_elt(1u, {||...}),
-        //    d.read_tup_elt(2u, {||...}))
-        // }
-
-        let arg_exprs = do vec::from_fn(vec::len(tys)) |i| {
-            let idx = cx.lit_uint(ty.span, i);
-            let body = deser_lambda(cx, tps, tys[i], cx.clone(d));
-            #ast{ $(d).read_tup_elt($(idx), $(body)) }
-        };
-        let body =
-            cx.lambda(cx.expr_blk(
-                cx.expr(ty.span, ast::expr_tup(arg_exprs))));
-        let sz = cx.lit_uint(ty.span, vec::len(tys));
-        #ast{ $(d).read_tup($(sz), $(body)) }
-      }
-
-      ast::ty_path(path, _) => {
-        if vec::len(path.idents) == 1u &&
-            vec::is_empty(path.types) {
-            let ident = path.idents[0];
-
-            match tps.find(ident) {
-              Some(f) => f(),
-              None => deser_path(cx, tps, path, move d)
-            }
-        } else {
-            deser_path(cx, tps, path, move d)
+// 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 serialization
+// generator code.
+type field = { span: span, ident: ast::ident, mutbl: ast::mutability };
+
+fn mk_rec_fields(fields: ~[ast::ty_field]) -> ~[field] {
+    do fields.map |field| {
+        {
+            span: field.span,
+            ident: field.node.ident,
+            mutbl: field.node.mt.mutbl,
         }
-      }
-
-      ast::ty_mac(_) => {
-        #ast{ fail }
-      }
+    }
+}
 
-      ast::ty_infer => {
-        #ast{ fail }
-      }
+fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] {
+    do fields.map |field| {
+        let (ident, mutbl) = match field.node.kind {
+            ast::named_field(ident, mutbl, _) => (ident, mutbl),
+            _ => fail ~"[auto_serialize] does not support \
+                        unnamed fields",
+        };
 
-      ast::ty_vec(mt) => {
-        let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
-        #ast{ std::serialization::read_to_vec($(d), $(l)) }
-      }
+        {
+            span: field.span,
+            ident: ident,
+            mutbl: match mutbl {
+                ast::class_mutable => ast::m_mutbl,
+                ast::class_immutable => ast::m_imm,
+            },
+        }
+    }
+}
 
-      ast::ty_fixed_length(_, _) => {
-        cx.span_unimpl(ty.span, ~"deserialization for fixed length types");
-      }
+fn mk_ser_fields(
+    cx: ext_ctxt,
+    span: span,
+    fields: ~[field]
+) -> ~[@ast::stmt] {
+    do fields.mapi |idx, field| {
+        // ast for `|| self.$(name).serialize(__s)`
+        let expr_lambda = cx.lambda_expr(
+            cx.expr_call(
+                span,
+                cx.expr_field(
+                    span,
+                    cx.expr_field(
+                        span,
+                        cx.expr_var(span, ~"self"),
+                        field.ident
+                    ),
+                    cx.ident_of(~"serialize")
+                ),
+                ~[cx.expr_var(span, ~"__s")]
+            )
+        );
+
+        // ast for `__s.emit_field($(name), $(idx), $(expr_lambda))`
+        cx.stmt(
+            cx.expr_call(
+                span,
+                cx.expr_field(
+                    span,
+                    cx.expr_var(span, ~"__s"),
+                    cx.ident_of(~"emit_field")
+                ),
+                ~[
+                    cx.lit_str(span, @cx.str_of(field.ident)),
+                    cx.lit_uint(span, idx),
+                    expr_lambda,
+                ]
+            )
+        )
     }
 }
 
-fn mk_deser_fn(cx: ext_ctxt, span: span,
-               name: ast::ident, tps: ~[ast::ty_param],
-               f: fn(ext_ctxt, deser_tps_map, -v: @ast::expr) -> @ast::expr)
-    -> @ast::item {
-    let ext_cx = cx; // required for #ast
-
-    let tp_types = vec::map(tps, |tp| cx.ty_path(span, ~[tp.ident], ~[]));
-    let v_ty = cx.ty_path(span, ~[name], tp_types);
-
-    let tp_inputs =
-        vec::map(tps, |tp|
-            {mode: ast::expl(ast::by_ref),
-             ty: cx.ty_fn(span,
-                          ~[],
-                          cx.ty_path(span, ~[tp.ident], ~[])),
-             ident: cx.ident_of(~"__d" + cx.str_of(tp.ident)),
-             id: cx.next_id()});
-
-    debug!("tp_inputs = %?", tp_inputs);
-
-    let deser_inputs: ~[ast::arg] =
-        vec::append(~[{mode: ast::expl(ast::by_ref),
-                      ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]),
-                      ident: cx.ident_of(~"__d"),
-                      id: cx.next_id()}],
-                    tp_inputs);
-
-    let tps_map = map::HashMap();
-    for vec::each2(tps, tp_inputs) |tp, arg| {
-        let arg_ident = arg.ident;
-        tps_map.insert(
-            tp.ident,
-            fn@() -> @ast::expr {
-                let f = cx.var_ref(span, arg_ident);
-                #ast{ $(f)() }
-            });
-    }
-
-    let deser_bnds = @~[
-        ast::bound_trait(cx.ty_path(
+fn mk_deser_fields(
+    cx: ext_ctxt,
+    span: span,
+    fields: ~[{ span: span, ident: ast::ident, mutbl: ast::mutability }]
+) -> ~[ast::field] {
+    do fields.mapi |idx, field| {
+        // ast for `|| std::serialization::deserialize(__d)`
+        let expr_lambda = cx.lambda(
+            cx.expr_blk(
+                cx.expr_call(
+                    span,
+                    cx.expr_path(span, ~[
+                        cx.ident_of(~"std"),
+                        cx.ident_of(~"serialization"),
+                        cx.ident_of(~"deserialize"),
+                    ]),
+                    ~[cx.expr_var(span, ~"__d")]
+                )
+            )
+        );
+
+        // ast for `__d.read_field($(name), $(idx), $(expr_lambda))`
+        let expr: @ast::expr = cx.expr_call(
             span,
-            ~[cx.ident_of(~"std"), cx.ident_of(~"serialization"),
-              cx.ident_of(~"Deserializer")],
-            ~[]))];
-
-    let deser_tps: ~[ast::ty_param] =
-        vec::append(~[{ident: cx.ident_of(~"__D"),
-                      id: cx.next_id(),
-                      bounds: deser_bnds}],
-                    vec::map(tps, |tp| {
-                        let cloned = cx.clone_ty_param(*tp);
-                        {bounds: @(vec::append(*cloned.bounds,
-                                               ~[ast::bound_copy])),
-                         .. cloned}
-                    }));
-
-    let deser_blk = cx.expr_blk(f(cx, tps_map, #ast[expr]{__d}));
-
-    @{ident: cx.ident_of(~"deserialize_" + cx.str_of(name)),
-      attrs: ~[],
-      id: cx.next_id(),
-      node: ast::item_fn({inputs: deser_inputs,
-                          output: v_ty,
-                          cf: ast::return_val},
-                         ast::impure_fn,
-                         deser_tps,
-                         deser_blk),
-      vis: ast::public,
-      span: span}
+            cx.expr_field(
+                span,
+                cx.expr_var(span, ~"__d"),
+                cx.ident_of(~"read_field")
+            ),
+            ~[
+                cx.lit_str(span, @cx.str_of(field.ident)),
+                cx.lit_uint(span, idx),
+                expr_lambda,
+            ]
+        );
+
+        {
+            node: { mutbl: field.mutbl, ident: field.ident, expr: expr },
+            span: span,
+        }
+    }
 }
 
-fn ty_fns(cx: ext_ctxt, name: ast::ident,
-          ty: @ast::ty, tps: ~[ast::ty_param])
-    -> ~[@ast::item] {
+fn mk_enum_ser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    enum_def: ast::enum_def,
+    tps: ~[ast::ty_param]
+) -> @ast::item {
+    let body = mk_enum_ser_body(
+        cx,
+        span,
+        ident,
+        enum_def.variants
+    );
+
+    mk_ser_impl(cx, span, ident, tps, body)
+}
 
-    let span = ty.span;
-    ~[
-        mk_ser_fn(cx, span, name, tps, |a,b,c,d| ser_ty(a, b, ty, move c,
-                                                        move d)),
-        mk_deser_fn(cx, span, name, tps, |a,b,c| deser_ty(a, b, ty, move c))
-    ]
+fn mk_enum_deser_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    enum_def: ast::enum_def,
+    tps: ~[ast::ty_param]
+) -> @ast::item {
+    let body = mk_enum_deser_body(
+        cx,
+        span,
+        ident,
+        enum_def.variants
+    );
+
+    mk_deser_impl(cx, span, ident, tps, body)
 }
 
-fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident,
-            e_span: span, variants: ~[ast::variant],
-            -s: @ast::expr, -v: @ast::expr) -> ~[@ast::stmt] {
-    let ext_cx = cx;
-    let arms = do vec::from_fn(vec::len(variants)) |vidx| {
-        let variant = variants[vidx];
-        let v_span = variant.span;
-        let v_name = variant.node.name;
+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_by_implicit_ref,
+            cx.path(span, ~[v_name]),
+            None
+        )
+    } else {
+        ast::pat_enum(
+            cx.path(span, ~[v_name]),
+            Some(pats)
+        )
+    };
 
-        match variant.node.kind {
-            ast::tuple_variant_kind(args) => {
-                let variant_tys = vec::map(args, |a| a.ty);
-
-                ser_variant(
-                    cx, tps, variant_tys, v_span, cx.clone(s),
-
-                    // Generate pattern var(v1, v2, v3)
-                    |pats| {
-                        if vec::is_empty(pats) {
-                            ast::pat_ident(ast::bind_by_implicit_ref,
-                                           cx.path(v_span, ~[v_name]),
-                                           None)
-                        } else {
-                            ast::pat_enum(cx.path(v_span, ~[v_name]),
-                                                  Some(pats))
-                        }
-                    },
+    let pat = @{
+        id: cx.next_id(),
+        node: pat_node,
+        span: span,
+    };
 
-                    // Generate body s.emit_enum_variant("foo", 0u,
-                    //                                   3u, {|| blk })
-                    |-s, blk| {
-                        let v_name = cx.lit_str(v_span, @cx.str_of(v_name));
-                        let v_id = cx.lit_uint(v_span, vidx);
-                        let sz = cx.lit_uint(v_span, vec::len(variant_tys));
-                        let body = cx.lambda(blk);
-                        #ast[expr]{
-                            $(s).emit_enum_variant($(v_name), $(v_id),
-                                                   $(sz), $(body))
-                        }
-                    },
+    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")
+        );
 
-                    // Generate s.emit_enum_variant_arg(i, {|| blk })
-                    |-s, i, blk| {
-                        let idx = cx.lit_uint(v_span, i);
-                        let body = cx.lambda(blk);
-                        #ast[expr]{
-                            $(s).emit_enum_variant_arg($(idx), $(body))
-                        }
-                    })
-            }
-            _ =>
-                fail ~"struct variants unimplemented for auto serialize"
-        }
+        // ast for `|| $(v).serialize(__s)`
+        let expr_serialize = cx.lambda_expr(
+             cx.expr_call(
+                span,
+                cx.expr_field(
+                    span,
+                    cx.expr_path(span, ~[names[a_idx]]),
+                    cx.ident_of(~"serialize")
+                ),
+                ~[cx.expr_var(span, ~"__s")]
+            )
+        );
+
+        // ast for `$(expr_emit)($(a_idx), $(expr_serialize))`
+        cx.stmt(
+            cx.expr_call(
+                span,
+                expr_emit,
+                ~[cx.lit_uint(span, a_idx), expr_serialize]
+            )
+        )
     };
-    let lam = cx.lambda(cx.blk(e_span, ~[cx.alt_stmt(arms, e_span, move v)]));
-    let e_name = cx.lit_str(e_span, @cx.str_of(e_name));
-    ~[#ast[stmt]{ $(s).emit_enum($(e_name), $(lam)) }]
-}
 
-fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident,
-              e_span: span, variants: ~[ast::variant],
-              -d: @ast::expr) -> @ast::expr {
-    let ext_cx = cx;
-    let mut arms: ~[ast::arm] = do vec::from_fn(vec::len(variants)) |vidx| {
-        let variant = variants[vidx];
-        let v_span = variant.span;
-        let v_name = variant.node.name;
+    // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))`
+    let body = cx.expr_call(
+        span,
+        cx.expr_field(
+            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(span, stmts),
+        ]
+    );
+
+    { pats: ~[pat], guard: None, body: cx.expr_blk(body) }
+}
 
-        let 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(args) => {
-                let tys = vec::map(args, |a| a.ty);
-
-                let arg_exprs = do vec::from_fn(vec::len(tys)) |i| {
-                    let idx = cx.lit_uint(v_span, i);
-                    let body = deser_lambda(cx, tps, tys[i], cx.clone(d));
-                    #ast{ $(d).read_enum_variant_arg($(idx), $(body)) }
-                };
-
-                body = {
-                    if vec::is_empty(tys) {
-                        // for a nullary variant v, do "v"
-                        cx.var_ref(v_span, v_name)
-                    } else {
-                        // for an n-ary variant v, do "v(a_1, ..., a_n)"
-                        cx.expr(v_span, ast::expr_call(
-                            cx.var_ref(v_span, v_name), arg_exprs, false))
-                    }
-                };
-            }
+            ast::tuple_variant_kind(args) =>
+                ser_variant(cx, span, variant.node.name, v_idx, args),
             ast::struct_variant_kind(*) =>
                 fail ~"struct variants unimplemented",
             ast::enum_variant_kind(*) =>
-                fail ~"enum variants unimplemented"
+                fail ~"enum 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_var(span, ~"self"))
+            ),
+            arms
+        )
+    );
+
+    // ast for `__s.emit_enum($(name), || $(match_expr))`
+    cx.expr_call(
+        span,
+        cx.expr_field(
+            span,
+            cx.expr_var(span, ~"__s"),
+            cx.ident_of(~"emit_enum")
+        ),
+        ~[
+            cx.lit_str(span, @cx.str_of(name)),
+            cx.lambda_expr(match_expr),
+        ]
+    )
+}
 
-        {pats: ~[@{id: cx.next_id(),
-                  node: ast::pat_lit(cx.lit_uint(v_span, vidx)),
-                  span: v_span}],
-         guard: None,
-         body: cx.expr_blk(body)}
+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 `|| std::serialization::deserialize(__d)`
+        let expr_lambda = cx.lambda_expr(
+            cx.expr_call(
+                span,
+                cx.expr_path(span, ~[
+                    cx.ident_of(~"std"),
+                    cx.ident_of(~"serialization"),
+                    cx.ident_of(~"deserialize"),
+                ]),
+                ~[cx.expr_var(span, ~"__d")]
+            )
+        );
+
+        // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))`
+        cx.expr_call(
+            span,
+            cx.expr_field(
+                span,
+                cx.expr_var(span, ~"__d"),
+                cx.ident_of(~"read_enum_variant_arg")
+            ),
+            ~[cx.lit_uint(span, idx), expr_lambda]
+        )
     };
 
-    let impossible_case = {pats: ~[@{id: cx.next_id(),
-                                     node: ast::pat_wild,
-                                     span: e_span}],
-                        guard: None,
-                        // FIXME #3198: proper error message
-                           body: cx.expr_blk(cx.expr(e_span,
-                                                     ast::expr_fail(None)))};
-    arms += ~[impossible_case];
-
-    // Generate code like:
-    let e_name = cx.lit_str(e_span, @cx.str_of(e_name));
-    let alt_expr = cx.expr(e_span,
-                           ast::expr_match(#ast{__i}, arms));
-    let var_lambda = #ast{ |__i| $(alt_expr) };
-    let read_var = #ast{ $(cx.clone(d)).read_enum_variant($(var_lambda)) };
-    let read_lambda = cx.lambda(cx.expr_blk(read_var));
-    #ast{ $(d).read_enum($(e_name), $(read_lambda)) }
+    // ast for `$(name)($(args))`
+    cx.expr_call(span, cx.expr_path(span, ~[name]), args)
 }
 
-fn enum_fns(cx: ext_ctxt, e_name: ast::ident, e_span: span,
-               variants: ~[ast::variant], tps: ~[ast::ty_param])
-    -> ~[@ast::item] {
-    ~[
-        mk_ser_fn(cx, e_span, e_name, tps,
-                  |a,b,c,d| ser_enum(a, b, e_name, e_span, variants, move c,
-                                     move d)),
-        mk_deser_fn(cx, e_span, e_name, tps,
-          |a,b,c| deser_enum(a, b, e_name, e_span, variants, move c))
-    ]
+fn mk_enum_deser_body(
+    cx: ext_ctxt,
+    span: span,
+    name: ast::ident,
+    variants: ~[ast::variant]
+) -> @ast::expr {
+    let mut arms = do variants.mapi |v_idx, variant| {
+        let body = match variant.node.kind {
+            ast::tuple_variant_kind(args) => {
+                if args.is_empty() {
+                    // for a nullary variant v, do "v"
+                    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(
+                        cx,
+                        span,
+                        variant.node.name,
+                        args
+                    )
+                }
+            },
+            ast::struct_variant_kind(*) =>
+                fail ~"struct variants unimplemented",
+            ast::enum_variant_kind(*) =>
+                fail ~"enum variants unimplemented",
+        };
+
+        let pat = @{
+            id: cx.next_id(),
+            node: ast::pat_lit(cx.lit_uint(span, v_idx)),
+            span: span,
+        };
+
+        {
+            pats: ~[pat],
+            guard: None,
+            body: cx.expr_blk(body),
+        }
+    };
+
+    let impossible_case = {
+        pats: ~[@{ id: cx.next_id(), node: ast::pat_wild, span: span}],
+        guard: None,
+
+        // FIXME(#3198): proper error message
+        body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))),
+    };
+
+    arms.push(impossible_case);
+
+    // ast for `|i| { match i { $(arms) } }`
+    let expr_lambda = cx.expr(
+        span,
+        ast::expr_fn_block(
+            {
+                inputs: ~[{
+                    mode: ast::infer(cx.next_id()),
+                    ty: @{
+                        id: cx.next_id(),
+                        node: ast::ty_infer,
+                        span: span
+                    },
+                    ident: cx.ident_of(~"i"),
+                    id: cx.next_id(),
+                }],
+                output: @{
+                    id: cx.next_id(),
+                    node: ast::ty_infer,
+                    span: span,
+                },
+                cf: ast::return_val,
+            },
+            cx.expr_blk(
+                cx.expr(
+                    span,
+                    ast::expr_match(cx.expr_var(span, ~"i"), arms)
+                )
+            ),
+            @~[]
+        )
+    );
+
+    // ast for `__d.read_enum_variant($(expr_lambda))`
+    let expr_lambda = cx.lambda_expr(
+        cx.expr_call(
+            span,
+            cx.expr_field(
+                span,
+                cx.expr_var(span, ~"__d"),
+                cx.ident_of(~"read_enum_variant")
+            ),
+            ~[expr_lambda]
+        )
+    );
+
+    // ast for `__d.read_enum($(e_name), $(expr_lambda))`
+    cx.expr_call(
+        span,
+        cx.expr_field(
+            span,
+            cx.expr_var(span, ~"__d"),
+            cx.ident_of(~"read_enum")
+        ),
+        ~[
+            cx.lit_str(span, @cx.str_of(name)),
+            expr_lambda
+        ]
+    )
 }
diff --git a/src/libsyntax/ext/auto_serialize2.rs b/src/libsyntax/ext/auto_serialize2.rs
index ba48b0d3f5f..b3102f8b4f7 100644
--- a/src/libsyntax/ext/auto_serialize2.rs
+++ b/src/libsyntax/ext/auto_serialize2.rs
@@ -214,120 +214,6 @@ fn expand_auto_deserialize(
     }
 }
 
-priv impl ext_ctxt {
-    fn expr(span: span, node: ast::expr_) -> @ast::expr {
-        @{id: self.next_id(), callee_id: self.next_id(),
-          node: node, span: span}
-    }
-
-    fn path(span: span, strs: ~[ast::ident]) -> @ast::path {
-        @{span: span, global: false, idents: strs, rp: None, types: ~[]}
-    }
-
-    fn path_tps(span: span, strs: ~[ast::ident],
-                tps: ~[@ast::ty]) -> @ast::path {
-        @{span: span, global: false, idents: strs, rp: None, types: tps}
-    }
-
-    fn ty_path(span: span, strs: ~[ast::ident],
-               tps: ~[@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(span: span, nm: ast::ident) -> @ast::pat {
-        let path = @{span: span, global: false, idents: ~[nm],
-                     rp: None, types: ~[]};
-        @{id: self.next_id(),
-          node: ast::pat_ident(ast::bind_by_implicit_ref,
-                               path,
-                               None),
-          span: span}
-    }
-
-    fn stmt(expr: @ast::expr) -> @ast::stmt {
-        @{node: ast::stmt_semi(expr, self.next_id()),
-          span: expr.span}
-    }
-
-    fn lit_str(span: span, s: @~str) -> @ast::expr {
-        self.expr(
-            span,
-            ast::expr_vstore(
-                self.expr(
-                    span,
-                    ast::expr_lit(
-                        @{node: ast::lit_str(s),
-                          span: span})),
-                ast::expr_vstore_uniq))
-    }
-
-    fn lit_uint(span: span, i: uint) -> @ast::expr {
-        self.expr(
-            span,
-            ast::expr_lit(
-                @{node: ast::lit_uint(i as u64, ast::ty_u),
-                  span: span}))
-    }
-
-    fn lambda(blk: ast::blk) -> @ast::expr {
-        let ext_cx = self;
-        let blk_e = self.expr(blk.span, ast::expr_block(blk));
-        #ast{ || $(blk_e) }
-    }
-
-    fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk {
-        {node: {view_items: ~[],
-                stmts: stmts,
-                expr: None,
-                id: self.next_id(),
-                rules: ast::default_blk},
-         span: span}
-    }
-
-    fn expr_blk(expr: @ast::expr) -> ast::blk {
-        {node: {view_items: ~[],
-                stmts: ~[],
-                expr: Some(expr),
-                id: self.next_id(),
-                rules: ast::default_blk},
-         span: expr.span}
-    }
-
-    fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path(span, strs)))
-    }
-
-    fn expr_var(span: span, var: ~str) -> @ast::expr {
-        self.expr_path(span, ~[self.ident_of(var)])
-    }
-
-    fn expr_field(
-        span: span,
-        expr: @ast::expr,
-        ident: ast::ident
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_field(expr, ident, ~[]))
-    }
-
-    fn expr_call(
-        span: span,
-        expr: @ast::expr,
-        args: ~[@ast::expr]
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_call(expr, args, false))
-    }
-
-    fn lambda_expr(expr: @ast::expr) -> @ast::expr {
-        self.lambda(self.expr_blk(expr))
-    }
-
-    fn lambda_stmts(span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
-        self.lambda(self.blk(span, stmts))
-    }
-}
-
 fn mk_impl(
     cx: ext_ctxt,
     span: span,
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 794c5233e21..ab56b6bb322 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -81,8 +81,6 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
                             builtin_item_tt(
                                 ext::tt::macro_rules::add_new_extension));
     syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext));
-    syntax_expanders.insert(~"auto_serialize",
-                            item_decorator(ext::auto_serialize::expand));
     syntax_expanders.insert(
         ~"auto_serialize2",
         item_decorator(ext::auto_serialize2::expand_auto_serialize));
@@ -143,16 +141,10 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
     syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext));
     syntax_expanders.insert(
         ~"auto_serialize",
-        item_decorator(ext::auto_serialize2::expand_auto_serialize));
+        item_decorator(ext::auto_serialize::expand_auto_serialize));
     syntax_expanders.insert(
         ~"auto_deserialize",
-        item_decorator(ext::auto_serialize2::expand_auto_deserialize));
-    syntax_expanders.insert(
-        ~"auto_serialize2",
-        item_decorator(ext::auto_serialize2::expand_auto_serialize));
-    syntax_expanders.insert(
-        ~"auto_deserialize2",
-        item_decorator(ext::auto_serialize2::expand_auto_deserialize));
+        item_decorator(ext::auto_serialize::expand_auto_deserialize));
     syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext));
     syntax_expanders.insert(~"concat_idents",
                             builtin(ext::concat_idents::expand_syntax_ext));
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 19e79a4ae7a..b63260997f7 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -2,6 +2,8 @@ use util::interner;
 use util::interner::interner;
 use std::map::HashMap;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum binop {
@@ -17,6 +19,8 @@ enum binop {
     SHR,
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum token {
@@ -75,6 +79,8 @@ enum token {
     EOF,
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 /// For interpolation during macro expansion.
diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc
index 4a6bac9cd64..4c29fc5512a 100644
--- a/src/libsyntax/syntax.rc
+++ b/src/libsyntax/syntax.rc
@@ -128,9 +128,9 @@ mod ext {
     mod ident_to_str;
     #[legacy_exports]
     mod log_syntax;
-    #[cfg(stage0)]
     #[legacy_exports]
     mod auto_serialize;
+    #[cfg(stage0)]
     #[legacy_exports]
     mod auto_serialize2;
     #[legacy_exports]
diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs
index 197e567ab2f..6b8c995ffd2 100644
--- a/src/rustc/metadata/decoder.rs
+++ b/src/rustc/metadata/decoder.rs
@@ -1,8 +1,9 @@
 // Decoding metadata from a single crate's metadata
 
-use std::{ebml2, map};
+use std::ebml;
+use std::map;
 use std::map::HashMap;
-use std::serialization2::deserialize;
+use std::serialization::deserialize;
 use io::WriterUtil;
 use dvec::DVec;
 use syntax::{ast, ast_util};
@@ -64,25 +65,25 @@ export translate_def_id;
 // what crate that's in and give us a def_id that makes sense for the current
 // build.
 
-fn lookup_hash(d: ebml2::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) ->
-   Option<ebml2::Doc> {
-    let index = ebml2::get_doc(d, tag_index);
-    let table = ebml2::get_doc(index, tag_index_table);
+fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) ->
+   Option<ebml::Doc> {
+    let index = ebml::get_doc(d, tag_index);
+    let table = ebml::get_doc(index, tag_index_table);
     let hash_pos = table.start + hash % 256u * 4u;
     let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4u) as uint;
-    let tagged_doc = ebml2::doc_at(d.data, pos);
+    let tagged_doc = ebml::doc_at(d.data, pos);
 
     let belt = tag_index_buckets_bucket_elt;
-    for ebml2::tagged_docs(tagged_doc.doc, belt) |elt| {
+    for ebml::tagged_docs(tagged_doc.doc, belt) |elt| {
         let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint;
         if eq_fn(vec::view(*elt.data, elt.start + 4u, elt.end)) {
-            return Some(ebml2::doc_at(d.data, pos).doc);
+            return Some(ebml::doc_at(d.data, pos).doc);
         }
     };
     None
 }
 
-fn maybe_find_item(item_id: int, items: ebml2::Doc) -> Option<ebml2::Doc> {
+fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option<ebml::Doc> {
     fn eq_item(bytes: &[u8], item_id: int) -> bool {
         return io::u64_from_be_bytes(vec::view(bytes, 0u, 4u), 0u, 4u) as int
             == item_id;
@@ -92,14 +93,14 @@ fn maybe_find_item(item_id: int, items: ebml2::Doc) -> Option<ebml2::Doc> {
                 item_id.hash() as uint)
 }
 
-fn find_item(item_id: int, items: ebml2::Doc) -> ebml2::Doc {
+fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {
     return maybe_find_item(item_id, items).get();
 }
 
-// Looks up an item in the given metadata and returns an ebml2 doc pointing
+// Looks up an item in the given metadata and returns an ebml doc pointing
 // to the item data.
-fn lookup_item(item_id: int, data: @~[u8]) -> ebml2::Doc {
-    let items = ebml2::get_doc(ebml2::Doc(data), tag_items);
+fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
+    let items = ebml::get_doc(ebml::Doc(data), tag_items);
     match maybe_find_item(item_id, items) {
        None => fail(fmt!("lookup_item: id not found: %d", item_id)),
        Some(d) => d
@@ -137,9 +138,9 @@ impl Family : cmp::Eq {
     pure fn ne(other: &Family) -> bool { !self.eq(other) }
 }
 
-fn item_family(item: ebml2::Doc) -> Family {
-    let fam = ebml2::get_doc(item, tag_items_data_item_family);
-    match ebml2::doc_as_u8(fam) as char {
+fn item_family(item: ebml::Doc) -> Family {
+    let fam = ebml::get_doc(item, tag_items_data_item_family);
+    match ebml::doc_as_u8(fam) as char {
       'c' => Const,
       'f' => Fn,
       'u' => UnsafeFn,
@@ -165,59 +166,59 @@ fn item_family(item: ebml2::Doc) -> Family {
     }
 }
 
-fn item_symbol(item: ebml2::Doc) -> ~str {
-    let sym = ebml2::get_doc(item, tag_items_data_item_symbol);
-    return str::from_bytes(ebml2::doc_data(sym));
+fn item_symbol(item: ebml::Doc) -> ~str {
+    let sym = ebml::get_doc(item, tag_items_data_item_symbol);
+    return str::from_bytes(ebml::doc_data(sym));
 }
 
-fn item_parent_item(d: ebml2::Doc) -> Option<ast::def_id> {
-    for ebml2::tagged_docs(d, tag_items_data_parent_item) |did| {
-        return Some(ebml2::with_doc_data(did, |d| parse_def_id(d)));
+fn item_parent_item(d: ebml::Doc) -> Option<ast::def_id> {
+    for ebml::tagged_docs(d, tag_items_data_parent_item) |did| {
+        return Some(ebml::with_doc_data(did, |d| parse_def_id(d)));
     }
     None
 }
 
-fn item_def_id(d: ebml2::Doc, cdata: cmd) -> ast::def_id {
-    let tagdoc = ebml2::get_doc(d, tag_def_id);
-    return translate_def_id(cdata, ebml2::with_doc_data(tagdoc,
+fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
+    let tagdoc = ebml::get_doc(d, tag_def_id);
+    return translate_def_id(cdata, ebml::with_doc_data(tagdoc,
                                                     |d| parse_def_id(d)));
 }
 
-fn each_reexport(d: ebml2::Doc, f: fn(ebml2::Doc) -> bool) {
-    for ebml2::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
+fn each_reexport(d: ebml::Doc, f: fn(ebml::Doc) -> bool) {
+    for ebml::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
         if !f(reexport_doc) {
             return;
         }
     }
 }
 
-fn field_mutability(d: ebml2::Doc) -> ast::class_mutability {
+fn field_mutability(d: ebml::Doc) -> ast::class_mutability {
     // Use maybe_get_doc in case it's a method
     option::map_default(
-        &ebml2::maybe_get_doc(d, tag_class_mut),
+        &ebml::maybe_get_doc(d, tag_class_mut),
         ast::class_immutable,
         |d| {
-            match ebml2::doc_as_u8(*d) as char {
+            match ebml::doc_as_u8(*d) as char {
               'm' => ast::class_mutable,
               _   => ast::class_immutable
             }
         })
 }
 
-fn variant_disr_val(d: ebml2::Doc) -> Option<int> {
-    do option::chain(ebml2::maybe_get_doc(d, tag_disr_val)) |val_doc| {
-        int::parse_bytes(ebml2::doc_data(val_doc), 10u)
+fn variant_disr_val(d: ebml::Doc) -> Option<int> {
+    do option::chain(ebml::maybe_get_doc(d, tag_disr_val)) |val_doc| {
+        int::parse_bytes(ebml::doc_data(val_doc), 10u)
     }
 }
 
-fn doc_type(doc: ebml2::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
-    let tp = ebml2::get_doc(doc, tag_items_data_item_type);
+fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
+    let tp = ebml::get_doc(doc, tag_items_data_item_type);
     parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, |did| {
         translate_def_id(cdata, did)
     })
 }
 
-fn item_type(item_id: ast::def_id, item: ebml2::Doc,
+fn item_type(item_id: ast::def_id, item: ebml::Doc,
              tcx: ty::ctxt, cdata: cmd) -> ty::t {
     let t = doc_type(item, tcx, cdata);
     if family_names_type(item_family(item)) {
@@ -225,18 +226,18 @@ fn item_type(item_id: ast::def_id, item: ebml2::Doc,
     } else { t }
 }
 
-fn item_impl_traits(item: ebml2::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] {
+fn item_impl_traits(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] {
     let mut results = ~[];
-    for ebml2::tagged_docs(item, tag_impl_trait) |ity| {
+    for ebml::tagged_docs(item, tag_impl_trait) |ity| {
         results.push(doc_type(ity, tcx, cdata));
     };
     results
 }
 
-fn item_ty_param_bounds(item: ebml2::Doc, tcx: ty::ctxt, cdata: cmd)
+fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd)
     -> @~[ty::param_bounds] {
     let mut bounds = ~[];
-    for ebml2::tagged_docs(item, tag_items_data_item_ty_param_bounds) |p| {
+    for ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds) |p| {
         let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx, |did| {
             translate_def_id(cdata, did)
         });
@@ -245,42 +246,42 @@ fn item_ty_param_bounds(item: ebml2::Doc, tcx: ty::ctxt, cdata: cmd)
     @bounds
 }
 
-fn item_ty_region_param(item: ebml2::Doc) -> Option<ty::region_variance> {
-    ebml2::maybe_get_doc(item, tag_region_param).map(|doc| {
-        deserialize(&ebml2::Deserializer(*doc))
+fn item_ty_region_param(item: ebml::Doc) -> Option<ty::region_variance> {
+    ebml::maybe_get_doc(item, tag_region_param).map(|doc| {
+        deserialize(&ebml::Deserializer(*doc))
     })
 }
 
-fn item_ty_param_count(item: ebml2::Doc) -> uint {
+fn item_ty_param_count(item: ebml::Doc) -> uint {
     let mut n = 0u;
-    ebml2::tagged_docs(item, tag_items_data_item_ty_param_bounds,
+    ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds,
                       |_p| { n += 1u; true } );
     n
 }
 
-fn enum_variant_ids(item: ebml2::Doc, cdata: cmd) -> ~[ast::def_id] {
+fn enum_variant_ids(item: ebml::Doc, cdata: cmd) -> ~[ast::def_id] {
     let mut ids: ~[ast::def_id] = ~[];
     let v = tag_items_data_item_variant;
-    for ebml2::tagged_docs(item, v) |p| {
-        let ext = ebml2::with_doc_data(p, |d| parse_def_id(d));
+    for ebml::tagged_docs(item, v) |p| {
+        let ext = ebml::with_doc_data(p, |d| parse_def_id(d));
         ids.push({crate: cdata.cnum, node: ext.node});
     };
     return ids;
 }
 
-fn item_path(intr: @ident_interner, item_doc: ebml2::Doc) -> ast_map::path {
-    let path_doc = ebml2::get_doc(item_doc, tag_path);
+fn item_path(intr: @ident_interner, item_doc: ebml::Doc) -> ast_map::path {
+    let path_doc = ebml::get_doc(item_doc, tag_path);
 
-    let len_doc = ebml2::get_doc(path_doc, tag_path_len);
-    let len = ebml2::doc_as_u32(len_doc) as uint;
+    let len_doc = ebml::get_doc(path_doc, tag_path_len);
+    let len = ebml::doc_as_u32(len_doc) as uint;
 
     let mut result = vec::with_capacity(len);
-    for ebml2::docs(path_doc) |tag, elt_doc| {
+    for ebml::docs(path_doc) |tag, elt_doc| {
         if tag == tag_path_elt_mod {
-            let str = ebml2::doc_as_str(elt_doc);
+            let str = ebml::doc_as_str(elt_doc);
             result.push(ast_map::path_mod(intr.intern(@str)));
         } else if tag == tag_path_elt_name {
-            let str = ebml2::doc_as_str(elt_doc);
+            let str = ebml::doc_as_str(elt_doc);
             result.push(ast_map::path_name(intr.intern(@str)));
         } else {
             // ignore tag_path_len element
@@ -290,12 +291,12 @@ fn item_path(intr: @ident_interner, item_doc: ebml2::Doc) -> ast_map::path {
     return result;
 }
 
-fn item_name(intr: @ident_interner, item: ebml2::Doc) -> ast::ident {
-    let name = ebml2::get_doc(item, tag_paths_data_name);
-    intr.intern(@str::from_bytes(ebml2::doc_data(name)))
+fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident {
+    let name = ebml::get_doc(item, tag_paths_data_name);
+    intr.intern(@str::from_bytes(ebml::doc_data(name)))
 }
 
-fn item_to_def_like(item: ebml2::Doc, did: ast::def_id, cnum: ast::crate_num)
+fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
         -> def_like {
     let fam = item_family(item);
     match fam {
@@ -367,10 +368,10 @@ fn get_impl_traits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ~[ty::t] {
 
 fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
                    name: ast::ident) -> ast::def_id {
-    let items = ebml2::get_doc(ebml2::Doc(cdata.data), tag_items);
+    let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items);
     let mut found = None;
-    for ebml2::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| {
-        let m_did = ebml2::with_doc_data(mid, |d| parse_def_id(d));
+    for ebml::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| {
+        let m_did = ebml::with_doc_data(mid, |d| parse_def_id(d));
         if item_name(intr, find_item(m_did.node, items)) == name {
             found = Some(translate_def_id(cdata, m_did));
         }
@@ -380,14 +381,14 @@ fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
 
 fn get_class_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
                     name: ast::ident) -> ast::def_id {
-    let items = ebml2::get_doc(ebml2::Doc(cdata.data), tag_items);
+    let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items);
     let mut found = None;
     let cls_items = match maybe_find_item(id, items) {
       Some(it) => it,
       None => fail (fmt!("get_class_method: class id not found \
                               when looking up method %s", *intr.get(name)))
     };
-    for ebml2::tagged_docs(cls_items, tag_item_trait_method) |mid| {
+    for ebml::tagged_docs(cls_items, tag_item_trait_method) |mid| {
         let m_did = item_def_id(mid, cdata);
         if item_name(intr, mid) == name {
             found = Some(m_did);
@@ -401,16 +402,16 @@ fn get_class_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
 }
 
 fn class_dtor(cdata: cmd, id: ast::node_id) -> Option<ast::def_id> {
-    let items = ebml2::get_doc(ebml2::Doc(cdata.data), tag_items);
+    let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items);
     let mut found = None;
     let cls_items = match maybe_find_item(id, items) {
             Some(it) => it,
             None     => fail (fmt!("class_dtor: class id not found \
               when looking up dtor for %d", id))
     };
-    for ebml2::tagged_docs(cls_items, tag_item_dtor) |doc| {
-         let doc1 = ebml2::get_doc(doc, tag_def_id);
-         let did = ebml2::with_doc_data(doc1, |d| parse_def_id(d));
+    for ebml::tagged_docs(cls_items, tag_item_dtor) |doc| {
+         let doc1 = ebml::get_doc(doc, tag_def_id);
+         let did = ebml::with_doc_data(doc1, |d| parse_def_id(d));
          found = Some(translate_def_id(cdata, did));
     };
     found
@@ -452,14 +453,14 @@ fn path_entry(path_string: ~str, def_like: def_like) -> path_entry {
 
 /// Iterates over all the paths in the given crate.
 fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) {
-    let root = ebml2::Doc(cdata.data);
-    let items = ebml2::get_doc(root, tag_items);
-    let items_data = ebml2::get_doc(items, tag_items_data);
+    let root = ebml::Doc(cdata.data);
+    let items = ebml::get_doc(root, tag_items);
+    let items_data = ebml::get_doc(items, tag_items_data);
 
     let mut broken = false;
 
     // First, go through all the explicit items.
-    for ebml2::tagged_docs(items_data, tag_items_data_item) |item_doc| {
+    for ebml::tagged_docs(items_data, tag_items_data_item) |item_doc| {
         if !broken {
             let path = ast_map::path_to_str_with_sep(
                 item_path(intr, item_doc), ~"::", intr);
@@ -482,16 +483,16 @@ fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) {
             for each_reexport(item_doc) |reexport_doc| {
                 if !broken {
                     let def_id_doc =
-                        ebml2::get_doc(reexport_doc,
+                        ebml::get_doc(reexport_doc,
                             tag_items_data_item_reexport_def_id);
                     let def_id =
-                        ebml2::with_doc_data(def_id_doc, |d| parse_def_id(d));
+                        ebml::with_doc_data(def_id_doc, |d| parse_def_id(d));
                     let def_id = translate_def_id(cdata, def_id);
 
                     let reexport_name_doc =
-                        ebml2::get_doc(reexport_doc,
+                        ebml::get_doc(reexport_doc,
                                       tag_items_data_item_reexport_name);
-                    let reexport_name = ebml2::doc_as_str(reexport_name_doc);
+                    let reexport_name = ebml::doc_as_str(reexport_name_doc);
 
                     let reexport_path;
                     if path == ~"" {
@@ -540,7 +541,7 @@ type decode_inlined_item = fn(
     cdata: cstore::crate_metadata,
     tcx: ty::ctxt,
     path: ast_map::path,
-    par_doc: ebml2::Doc) -> Option<ast::inlined_item>;
+    par_doc: ebml::Doc) -> Option<ast::inlined_item>;
 
 fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt,
                       id: ast::node_id,
@@ -571,7 +572,7 @@ fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt,
 fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
                      tcx: ty::ctxt) -> ~[ty::variant_info] {
     let data = cdata.data;
-    let items = ebml2::get_doc(ebml2::Doc(data), tag_items);
+    let items = ebml::get_doc(ebml::Doc(data), tag_items);
     let item = find_item(id, items);
     let mut infos: ~[ty::variant_info] = ~[];
     let variant_ids = enum_variant_ids(item, cdata);
@@ -609,7 +610,7 @@ type method_info = {
 
 type _impl = {did: ast::def_id, ident: ast::ident, methods: ~[@method_info]};
 
-fn get_self_ty(item: ebml2::Doc) -> ast::self_ty_ {
+fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ {
     fn get_mutability(ch: u8) -> ast::mutability {
         match ch as char {
             'i' => { ast::m_imm }
@@ -621,8 +622,8 @@ fn get_self_ty(item: ebml2::Doc) -> ast::self_ty_ {
         }
     }
 
-    let self_type_doc = ebml2::get_doc(item, tag_item_trait_method_self_ty);
-    let string = ebml2::doc_as_str(self_type_doc);
+    let self_type_doc = ebml::get_doc(item, tag_item_trait_method_self_ty);
+    let string = ebml::doc_as_str(self_type_doc);
 
     let self_ty_kind = string[0];
     match self_ty_kind as char {
@@ -638,11 +639,11 @@ fn get_self_ty(item: ebml2::Doc) -> ast::self_ty_ {
     }
 }
 
-fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml2::Doc,
+fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
                      base_tps: uint) -> ~[@method_info] {
     let mut rslt = ~[];
-    for ebml2::tagged_docs(item, tag_item_impl_method) |doc| {
-        let m_did = ebml2::with_doc_data(doc, |d| parse_def_id(d));
+    for ebml::tagged_docs(item, tag_item_impl_method) |doc| {
+        let m_did = ebml::with_doc_data(doc, |d| parse_def_id(d));
         let mth_item = lookup_item(m_did.node, cdata.data);
         let self_ty = get_self_ty(mth_item);
         rslt.push(@{did: translate_def_id(cdata, m_did),
@@ -662,8 +663,8 @@ fn get_impls_for_mod(intr: @ident_interner, cdata: cmd,
     let data = cdata.data;
     let mod_item = lookup_item(m_id, data);
     let mut result = ~[];
-    for ebml2::tagged_docs(mod_item, tag_mod_impl) |doc| {
-        let did = ebml2::with_doc_data(doc, |d| parse_def_id(d));
+    for ebml::tagged_docs(mod_item, tag_mod_impl) |doc| {
+        let did = ebml::with_doc_data(doc, |d| parse_def_id(d));
         let local_did = translate_def_id(cdata, did);
         debug!("(get impls for mod) getting did %? for '%?'",
                local_did, name);
@@ -690,7 +691,7 @@ fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id,
     let data = cdata.data;
     let item = lookup_item(id, data);
     let mut result = ~[];
-    for ebml2::tagged_docs(item, tag_item_trait_method) |mth| {
+    for ebml::tagged_docs(item, tag_item_trait_method) |mth| {
         let bounds = item_ty_param_bounds(mth, tcx, cdata);
         let name = item_name(intr, mth);
         let ty = doc_type(mth, tcx, cdata);
@@ -722,7 +723,7 @@ fn get_method_names_if_trait(intr: @ident_interner, cdata: cmd,
     }
 
     let resulting_methods = @DVec();
-    for ebml2::tagged_docs(item, tag_item_trait_method) |method| {
+    for ebml::tagged_docs(item, tag_item_trait_method) |method| {
         resulting_methods.push(
             (item_name(intr, method), get_self_ty(method)));
     }
@@ -734,8 +735,8 @@ fn get_item_attrs(cdata: cmd,
                   f: fn(~[@ast::meta_item])) {
 
     let item = lookup_item(node_id, cdata.data);
-    for ebml2::tagged_docs(item, tag_attributes) |attributes| {
-        for ebml2::tagged_docs(attributes, tag_attribute) |attribute| {
+    for ebml::tagged_docs(item, tag_attributes) |attributes| {
+        for ebml::tagged_docs(attributes, tag_attribute) |attribute| {
             f(get_meta_items(attribute));
         }
     }
@@ -747,7 +748,7 @@ fn get_class_members(intr: @ident_interner, cdata: cmd, id: ast::node_id,
     let data = cdata.data;
     let item = lookup_item(id, data);
     let mut result = ~[];
-    for ebml2::tagged_docs(item, tag_item_field) |an_item| {
+    for ebml::tagged_docs(item, tag_item_field) |an_item| {
        let f = item_family(an_item);
        if p(f) {
           let name = item_name(intr, an_item);
@@ -787,15 +788,15 @@ fn family_names_type(fam: Family) -> bool {
     match fam { Type | Mod | Trait => true, _ => false }
 }
 
-fn read_path(d: ebml2::Doc) -> {path: ~str, pos: uint} {
-    let desc = ebml2::doc_data(d);
+fn read_path(d: ebml::Doc) -> {path: ~str, pos: uint} {
+    let desc = ebml::doc_data(d);
     let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint;
     let pathbytes = vec::slice::<u8>(desc, 4u, vec::len::<u8>(desc));
     let path = str::from_bytes(pathbytes);
     return {path: path, pos: pos};
 }
 
-fn describe_def(items: ebml2::Doc, id: ast::def_id) -> ~str {
+fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
     if id.crate != ast::local_crate { return ~"external"; }
     let it = match maybe_find_item(id.node, items) {
         Some(it) => it,
@@ -830,36 +831,36 @@ fn item_family_to_str(fam: Family) -> ~str {
     }
 }
 
-fn get_meta_items(md: ebml2::Doc) -> ~[@ast::meta_item] {
+fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] {
     let mut items: ~[@ast::meta_item] = ~[];
-    for ebml2::tagged_docs(md, tag_meta_item_word) |meta_item_doc| {
-        let nd = ebml2::get_doc(meta_item_doc, tag_meta_item_name);
-        let n = str::from_bytes(ebml2::doc_data(nd));
+    for ebml::tagged_docs(md, tag_meta_item_word) |meta_item_doc| {
+        let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name);
+        let n = str::from_bytes(ebml::doc_data(nd));
         items.push(attr::mk_word_item(n));
     };
-    for ebml2::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| {
-        let nd = ebml2::get_doc(meta_item_doc, tag_meta_item_name);
-        let vd = ebml2::get_doc(meta_item_doc, tag_meta_item_value);
-        let n = str::from_bytes(ebml2::doc_data(nd));
-        let v = str::from_bytes(ebml2::doc_data(vd));
+    for ebml::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| {
+        let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name);
+        let vd = ebml::get_doc(meta_item_doc, tag_meta_item_value);
+        let n = str::from_bytes(ebml::doc_data(nd));
+        let v = str::from_bytes(ebml::doc_data(vd));
         // FIXME (#623): Should be able to decode meta_name_value variants,
         // but currently the encoder just drops them
         items.push(attr::mk_name_value_item_str(n, v));
     };
-    for ebml2::tagged_docs(md, tag_meta_item_list) |meta_item_doc| {
-        let nd = ebml2::get_doc(meta_item_doc, tag_meta_item_name);
-        let n = str::from_bytes(ebml2::doc_data(nd));
+    for ebml::tagged_docs(md, tag_meta_item_list) |meta_item_doc| {
+        let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name);
+        let n = str::from_bytes(ebml::doc_data(nd));
         let subitems = get_meta_items(meta_item_doc);
         items.push(attr::mk_list_item(n, subitems));
     };
     return items;
 }
 
-fn get_attributes(md: ebml2::Doc) -> ~[ast::attribute] {
+fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] {
     let mut attrs: ~[ast::attribute] = ~[];
-    match ebml2::maybe_get_doc(md, tag_attributes) {
+    match ebml::maybe_get_doc(md, tag_attributes) {
       option::Some(attrs_d) => {
-        for ebml2::tagged_docs(attrs_d, tag_attribute) |attr_doc| {
+        for ebml::tagged_docs(attrs_d, tag_attribute) |attr_doc| {
             let meta_items = get_meta_items(attr_doc);
             // Currently it's only possible to have a single meta item on
             // an attribute
@@ -877,13 +878,13 @@ fn get_attributes(md: ebml2::Doc) -> ~[ast::attribute] {
 }
 
 fn list_meta_items(intr: @ident_interner,
-                   meta_items: ebml2::Doc, out: io::Writer) {
+                   meta_items: ebml::Doc, out: io::Writer) {
     for get_meta_items(meta_items).each |mi| {
         out.write_str(fmt!("%s\n", pprust::meta_item_to_str(*mi, intr)));
     }
 }
 
-fn list_crate_attributes(intr: @ident_interner, md: ebml2::Doc, hash: ~str,
+fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: ~str,
                          out: io::Writer) {
     out.write_str(fmt!("=Crate Attributes (%s)=\n", hash));
 
@@ -895,7 +896,7 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml2::Doc, hash: ~str,
 }
 
 fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] {
-    return get_attributes(ebml2::Doc(data));
+    return get_attributes(ebml::Doc(data));
 }
 
 type crate_dep = {cnum: ast::crate_num, name: ast::ident,
@@ -903,13 +904,13 @@ type crate_dep = {cnum: ast::crate_num, name: ast::ident,
 
 fn get_crate_deps(intr: @ident_interner, data: @~[u8]) -> ~[crate_dep] {
     let mut deps: ~[crate_dep] = ~[];
-    let cratedoc = ebml2::Doc(data);
-    let depsdoc = ebml2::get_doc(cratedoc, tag_crate_deps);
+    let cratedoc = ebml::Doc(data);
+    let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps);
     let mut crate_num = 1;
-    fn docstr(doc: ebml2::Doc, tag_: uint) -> ~str {
-        str::from_bytes(ebml2::doc_data(ebml2::get_doc(doc, tag_)))
+    fn docstr(doc: ebml::Doc, tag_: uint) -> ~str {
+        str::from_bytes(ebml::doc_data(ebml::get_doc(doc, tag_)))
     }
-    for ebml2::tagged_docs(depsdoc, tag_crate_dep) |depdoc| {
+    for ebml::tagged_docs(depsdoc, tag_crate_dep) |depdoc| {
         deps.push({cnum: crate_num,
                   name: intr.intern(@docstr(depdoc, tag_crate_dep_name)),
                   vers: docstr(depdoc, tag_crate_dep_vers),
@@ -932,9 +933,9 @@ fn list_crate_deps(intr: @ident_interner, data: @~[u8], out: io::Writer) {
 }
 
 fn get_crate_hash(data: @~[u8]) -> ~str {
-    let cratedoc = ebml2::Doc(data);
-    let hashdoc = ebml2::get_doc(cratedoc, tag_crate_hash);
-    return str::from_bytes(ebml2::doc_data(hashdoc));
+    let cratedoc = ebml::Doc(data);
+    let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash);
+    return str::from_bytes(ebml::doc_data(hashdoc));
 }
 
 fn get_crate_vers(data: @~[u8]) -> ~str {
@@ -988,7 +989,7 @@ fn get_crate_module_paths(intr: @ident_interner, cdata: cmd)
 fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8],
                        out: io::Writer) {
     let hash = get_crate_hash(bytes);
-    let md = ebml2::Doc(bytes);
+    let md = ebml::Doc(bytes);
     list_crate_attributes(intr, md, hash, out);
     list_crate_deps(intr, bytes, out);
 }
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 95696a14156..f188d8ee5d8 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -2,10 +2,10 @@
 
 use util::ppaux::ty_to_str;
 
-use std::{ebml2, map};
+use std::{ebml, map};
 use std::map::HashMap;
 use io::WriterUtil;
-use ebml2::Serializer;
+use ebml::Serializer;
 use syntax::ast::*;
 use syntax::print::pprust;
 use syntax::{ast_util, visit};
@@ -40,7 +40,7 @@ export encode_def_id;
 type abbrev_map = map::HashMap<ty::t, tyencode::ty_abbrev>;
 
 type encode_inlined_item = fn@(ecx: @encode_ctxt,
-                               ebml_w: ebml2::Serializer,
+                               ebml_w: ebml::Serializer,
                                path: ast_map::path,
                                ii: ast::inlined_item);
 
@@ -86,15 +86,15 @@ fn reachable(ecx: @encode_ctxt, id: node_id) -> bool {
     ecx.reachable.contains_key(id)
 }
 
-fn encode_name(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, name: ident) {
+fn encode_name(ecx: @encode_ctxt, ebml_w: ebml::Serializer, name: ident) {
     ebml_w.wr_tagged_str(tag_paths_data_name, ecx.tcx.sess.str_of(name));
 }
 
-fn encode_def_id(ebml_w: ebml2::Serializer, id: def_id) {
+fn encode_def_id(ebml_w: ebml::Serializer, id: def_id) {
     ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
 }
 
-fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                        it: @ast::item) {
     let opt_rp = ecx.tcx.region_paramd_items.find(it.id);
     for opt_rp.each |rp| {
@@ -104,7 +104,7 @@ fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     }
 }
 
-fn encode_mutability(ebml_w: ebml2::Serializer, mt: class_mutability) {
+fn encode_mutability(ebml_w: ebml::Serializer, mt: class_mutability) {
     do ebml_w.wr_tag(tag_class_mut) {
         let val = match mt {
           class_immutable => 'a',
@@ -116,7 +116,7 @@ fn encode_mutability(ebml_w: ebml2::Serializer, mt: class_mutability) {
 
 type entry<T> = {val: T, pos: uint};
 
-fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, path: &[ident],
+fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Serializer, path: &[ident],
                 index: &mut ~[entry<~str>], name: ident) {
     let mut full_path = ~[];
     full_path.push_all(path);
@@ -127,7 +127,7 @@ fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, path: &[ident],
          pos: ebml_w.writer.tell()});
 }
 
-fn encode_trait_ref(ebml_w: ebml2::Serializer, ecx: @encode_ctxt,
+fn encode_trait_ref(ebml_w: ebml::Serializer, ecx: @encode_ctxt,
                     t: @trait_ref) {
     ebml_w.start_tag(tag_impl_trait);
     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
@@ -136,7 +136,7 @@ fn encode_trait_ref(ebml_w: ebml2::Serializer, ecx: @encode_ctxt,
 
 
 // Item info table encoding
-fn encode_family(ebml_w: ebml2::Serializer, c: char) {
+fn encode_family(ebml_w: ebml::Serializer, c: char) {
     ebml_w.start_tag(tag_items_data_item_family);
     ebml_w.writer.write(&[c as u8]);
     ebml_w.end_tag();
@@ -144,7 +144,7 @@ fn encode_family(ebml_w: ebml2::Serializer, c: char) {
 
 fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) }
 
-fn encode_ty_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt,
+fn encode_ty_type_param_bounds(ebml_w: ebml::Serializer, ecx: @encode_ctxt,
                                params: @~[ty::param_bounds]) {
     let ty_str_ctxt = @{diag: ecx.diag,
                         ds: def_to_str,
@@ -158,7 +158,7 @@ fn encode_ty_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt,
     }
 }
 
-fn encode_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt,
+fn encode_type_param_bounds(ebml_w: ebml::Serializer, ecx: @encode_ctxt,
                             params: ~[ty_param]) {
     let ty_param_bounds =
         @params.map(|param| ecx.tcx.ty_param_bounds.get(param.id));
@@ -166,13 +166,13 @@ fn encode_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt,
 }
 
 
-fn encode_variant_id(ebml_w: ebml2::Serializer, vid: def_id) {
+fn encode_variant_id(ebml_w: ebml::Serializer, vid: def_id) {
     ebml_w.start_tag(tag_items_data_item_variant);
     ebml_w.writer.write(str::to_bytes(def_to_str(vid)));
     ebml_w.end_tag();
 }
 
-fn write_type(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, typ: ty::t) {
+fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Serializer, typ: ty::t) {
     let ty_str_ctxt =
         @{diag: ecx.diag,
           ds: def_to_str,
@@ -182,7 +182,7 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, typ: ty::t) {
     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
 }
 
-fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                 vstore: ty::vstore) {
     let ty_str_ctxt =
         @{diag: ecx.diag,
@@ -193,13 +193,13 @@ fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
 }
 
-fn encode_type(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, typ: ty::t) {
+fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Serializer, typ: ty::t) {
     ebml_w.start_tag(tag_items_data_item_type);
     write_type(ecx, ebml_w, typ);
     ebml_w.end_tag();
 }
 
-fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, id: node_id) {
+fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id) {
     ebml_w.start_tag(tag_items_data_item_symbol);
     let sym = match ecx.item_symbols.find(id) {
       Some(x) => x,
@@ -212,27 +212,27 @@ fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, id: node_id) {
     ebml_w.end_tag();
 }
 
-fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                        id: node_id) {
     ebml_w.start_tag(tag_items_data_item_symbol);
     ebml_w.writer.write(str::to_bytes(ecx.discrim_symbols.get(id)));
     ebml_w.end_tag();
 }
 
-fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                    disr_val: int) {
     ebml_w.start_tag(tag_disr_val);
     ebml_w.writer.write(str::to_bytes(int::to_str(disr_val,10u)));
     ebml_w.end_tag();
 }
 
-fn encode_parent_item(ebml_w: ebml2::Serializer, id: def_id) {
+fn encode_parent_item(ebml_w: ebml::Serializer, id: def_id) {
     ebml_w.start_tag(tag_items_data_parent_item);
     ebml_w.writer.write(str::to_bytes(def_to_str(id)));
     ebml_w.end_tag();
 }
 
-fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                             id: node_id, variants: ~[variant],
                             path: ast_map::path, index: @mut ~[entry<int>],
                             ty_params: ~[ty_param]) {
@@ -269,9 +269,9 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     }
 }
 
-fn encode_path(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_path(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                path: ast_map::path, name: ast_map::path_elt) {
-    fn encode_path_elt(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+    fn encode_path_elt(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                        elt: ast_map::path_elt) {
         let (tag, name) = match elt {
           ast_map::path_mod(name) => (tag_path_elt_mod, name),
@@ -290,7 +290,7 @@ fn encode_path(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     }
 }
 
-fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, md: _mod,
+fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::Serializer, md: _mod,
                        id: node_id, path: ast_map::path, name: ident) {
     ebml_w.start_tag(tag_items_data_item);
     encode_def_id(ebml_w, local_def(id));
@@ -348,7 +348,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, md: _mod,
     ebml_w.end_tag();
 }
 
-fn encode_visibility(ebml_w: ebml2::Serializer, visibility: visibility) {
+fn encode_visibility(ebml_w: ebml::Serializer, visibility: visibility) {
     encode_family(ebml_w, match visibility {
         public => 'g',
         private => 'j',
@@ -356,7 +356,7 @@ fn encode_visibility(ebml_w: ebml2::Serializer, visibility: visibility) {
     });
 }
 
-fn encode_self_type(ebml_w: ebml2::Serializer, self_type: ast::self_ty_) {
+fn encode_self_type(ebml_w: ebml::Serializer, self_type: ast::self_ty_) {
     ebml_w.start_tag(tag_item_trait_method_self_ty);
 
     // Encode the base self type.
@@ -389,7 +389,7 @@ fn encode_self_type(ebml_w: ebml2::Serializer, self_type: ast::self_ty_) {
 }
 
 /* Returns an index of items in this class */
-fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                          id: node_id, path: ast_map::path,
                          class_tps: ~[ty_param],
                          fields: ~[@struct_field],
@@ -445,7 +445,7 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
 }
 
 // This is for encoding info for ctors and dtors
-fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                         id: node_id, ident: ident, path: ast_map::path,
                         item: Option<inlined_item>, tps: ~[ty_param]) {
         ebml_w.start_tag(tag_items_data_item);
@@ -470,7 +470,7 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
         ebml_w.end_tag();
 }
 
-fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                           impl_path: ast_map::path, should_inline: bool,
                           parent_id: node_id,
                           m: @method, all_tps: ~[ty_param]) {
@@ -520,7 +520,7 @@ fn should_inline(attrs: ~[attribute]) -> bool {
 }
 
 
-fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                         item: @item, index: @mut ~[entry<int>],
                         path: ast_map::path) {
 
@@ -533,7 +533,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
         };
     if !must_write && !reachable(ecx, item.id) { return; }
 
-    fn add_to_index_(item: @item, ebml_w: ebml2::Serializer,
+    fn add_to_index_(item: @item, ebml_w: ebml::Serializer,
                      index: @mut ~[entry<int>]) {
         index.push({val: item.id, pos: ebml_w.writer.tell()});
     }
@@ -810,7 +810,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     }
 }
 
-fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                                 nitem: @foreign_item,
                                 index: @mut ~[entry<int>],
                                 path: ast_map::path, abi: foreign_abi) {
@@ -843,7 +843,7 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     ebml_w.end_tag();
 }
 
-fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                          crate: @crate) -> ~[entry<int>] {
     let index = @mut ~[];
     ebml_w.start_tag(tag_items_data);
@@ -898,7 +898,7 @@ fn create_index<T: Copy Hash IterBytes>(index: ~[entry<T>]) ->
     return buckets_frozen;
 }
 
-fn encode_index<T>(ebml_w: ebml2::Serializer, buckets: ~[@~[entry<T>]],
+fn encode_index<T>(ebml_w: ebml::Serializer, buckets: ~[@~[entry<T>]],
                    write_fn: fn(io::Writer, T)) {
     let writer = ebml_w.writer;
     ebml_w.start_tag(tag_index);
@@ -933,7 +933,7 @@ fn write_int(writer: io::Writer, &&n: int) {
     writer.write_be_u32(n as u32);
 }
 
-fn encode_meta_item(ebml_w: ebml2::Serializer, mi: meta_item) {
+fn encode_meta_item(ebml_w: ebml::Serializer, mi: meta_item) {
     match mi.node {
       meta_word(name) => {
         ebml_w.start_tag(tag_meta_item_word);
@@ -970,7 +970,7 @@ fn encode_meta_item(ebml_w: ebml2::Serializer, mi: meta_item) {
     }
 }
 
-fn encode_attributes(ebml_w: ebml2::Serializer, attrs: ~[attribute]) {
+fn encode_attributes(ebml_w: ebml::Serializer, attrs: ~[attribute]) {
     ebml_w.start_tag(tag_attributes);
     for attrs.each |attr| {
         ebml_w.start_tag(tag_attribute);
@@ -1031,7 +1031,7 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] {
     return attrs;
 }
 
-fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                      cstore: cstore::cstore) {
 
     fn get_ordered_deps(ecx: @encode_ctxt, cstore: cstore::cstore)
@@ -1077,7 +1077,7 @@ fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     ebml_w.end_tag();
 }
 
-fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
+fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                     dep: decoder::crate_dep) {
     ebml_w.start_tag(tag_crate_dep);
     ebml_w.start_tag(tag_crate_dep_name);
@@ -1092,7 +1092,7 @@ fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml2::Serializer,
     ebml_w.end_tag();
 }
 
-fn encode_hash(ebml_w: ebml2::Serializer, hash: ~str) {
+fn encode_hash(ebml_w: ebml::Serializer, hash: ~str) {
     ebml_w.start_tag(tag_crate_hash);
     ebml_w.writer.write(str::to_bytes(hash));
     ebml_w.end_tag();
@@ -1130,7 +1130,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
         type_abbrevs: ty::new_ty_hash()
      });
 
-    let ebml_w = ebml2::Serializer(wr as io::Writer);
+    let ebml_w = ebml::Serializer(wr as io::Writer);
 
     encode_hash(ebml_w, ecx.link_meta.extras_hash);
 
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index 39ec58c079e..103f1eecf87 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -7,15 +7,14 @@ use syntax::visit;
 use syntax::ast_map;
 use syntax::ast_util;
 use syntax::codemap::span;
-use std::ebml2;
-use std::ebml2::Serializer;
-use std::ebml2::get_doc;
+use std::ebml;
+use std::ebml::{Serializer, get_doc};
 use std::map::HashMap;
-use std::serialization2;
-use std::serialization2::{Serializable,
-                          SerializerHelpers,
-                          DeserializerHelpers,
-                          deserialize};
+use std::serialization;
+use std::serialization::{Serializable,
+                         SerializerHelpers,
+                         DeserializerHelpers,
+                         deserialize};
 use middle::{ty, typeck};
 use middle::typeck::{method_origin, method_map_entry,
                      vtable_res,
@@ -74,7 +73,7 @@ trait tr {
 // Top-level methods.
 
 fn encode_inlined_item(ecx: @e::encode_ctxt,
-                       ebml_w: ebml2::Serializer,
+                       ebml_w: ebml::Serializer,
                        path: ast_map::path,
                        ii: ast::inlined_item,
                        maps: maps) {
@@ -100,14 +99,14 @@ fn decode_inlined_item(cdata: cstore::crate_metadata,
                        tcx: ty::ctxt,
                        maps: maps,
                        path: ast_map::path,
-                       par_doc: ebml2::Doc) -> Option<ast::inlined_item> {
+                       par_doc: ebml::Doc) -> Option<ast::inlined_item> {
     let dcx = @{cdata: cdata, tcx: tcx, maps: maps};
     match par_doc.opt_child(c::tag_ast) {
       None => None,
       Some(ast_doc) => {
         debug!("> Decoding inlined fn: %s::?",
                ast_map::path_to_str(path, tcx.sess.parse_sess.interner));
-        let ast_dsr = &ebml2::Deserializer(ast_doc);
+        let ast_dsr = &ebml::Deserializer(ast_doc);
         let from_id_range = deserialize(ast_dsr);
         let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range);
         let xcx = extended_decode_ctxt_(@{dcx: dcx,
@@ -185,7 +184,7 @@ trait def_id_serializer_helpers {
     fn emit_def_id(did: ast::def_id);
 }
 
-impl<S: serialization2::Serializer> S: def_id_serializer_helpers {
+impl<S: serialization::Serializer> S: def_id_serializer_helpers {
     fn emit_def_id(did: ast::def_id) {
         did.serialize(&self)
     }
@@ -195,7 +194,7 @@ trait def_id_deserializer_helpers {
     fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id;
 }
 
-impl<D: serialization2::Deserializer> D: def_id_deserializer_helpers {
+impl<D: serialization::Deserializer> D: def_id_deserializer_helpers {
 
     fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id {
         let did: ast::def_id = deserialize(&self);
@@ -218,7 +217,7 @@ impl<D: serialization2::Deserializer> D: def_id_deserializer_helpers {
 // We also have to adjust the spans: for now we just insert a dummy span,
 // but eventually we should add entries to the local codemap as required.
 
-fn encode_ast(ebml_w: ebml2::Serializer, item: ast::inlined_item) {
+fn encode_ast(ebml_w: ebml::Serializer, item: ast::inlined_item) {
     do ebml_w.wr_tag(c::tag_tree as uint) {
         item.serialize(&ebml_w)
     }
@@ -278,9 +277,9 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
     }
 }
 
-fn decode_ast(par_doc: ebml2::Doc) -> ast::inlined_item {
+fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
     let chi_doc = par_doc[c::tag_tree as uint];
-    let d = &ebml2::Deserializer(chi_doc);
+    let d = &ebml::Deserializer(chi_doc);
     deserialize(d)
 }
 
@@ -332,12 +331,12 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
 // ______________________________________________________________________
 // Encoding and decoding of ast::def
 
-fn encode_def(ebml_w: ebml2::Serializer, def: ast::def) {
+fn encode_def(ebml_w: ebml::Serializer, def: ast::def) {
     def.serialize(&ebml_w)
 }
 
-fn decode_def(xcx: extended_decode_ctxt, doc: ebml2::Doc) -> ast::def {
-    let dsr = &ebml2::Deserializer(doc);
+fn decode_def(xcx: extended_decode_ctxt, doc: ebml::Doc) -> ast::def {
+    let dsr = &ebml::Deserializer(doc);
     let def: ast::def = deserialize(dsr);
     def.tr(xcx)
 }
@@ -423,7 +422,7 @@ impl ty::bound_region: tr {
 // ______________________________________________________________________
 // Encoding and decoding of freevar information
 
-fn encode_freevar_entry(ebml_w: ebml2::Serializer, fv: @freevar_entry) {
+fn encode_freevar_entry(ebml_w: ebml::Serializer, fv: @freevar_entry) {
     (*fv).serialize(&ebml_w)
 }
 
@@ -431,7 +430,7 @@ trait ebml_deserializer_helper {
     fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry;
 }
 
-impl ebml2::Deserializer: ebml_deserializer_helper {
+impl ebml::Deserializer: ebml_deserializer_helper {
     fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry {
         let fv: freevar_entry = deserialize(&self);
         fv.tr(xcx)
@@ -452,7 +451,7 @@ trait read_method_map_entry_helper {
 }
 
 fn serialize_method_map_entry(ecx: @e::encode_ctxt,
-                              ebml_w: ebml2::Serializer,
+                              ebml_w: ebml::Serializer,
                               mme: method_map_entry) {
     do ebml_w.emit_rec {
         do ebml_w.emit_field(~"self_arg", 0u) {
@@ -464,7 +463,7 @@ fn serialize_method_map_entry(ecx: @e::encode_ctxt,
     }
 }
 
-impl ebml2::Deserializer: read_method_map_entry_helper {
+impl ebml::Deserializer: read_method_map_entry_helper {
     fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry {
         do self.read_rec {
             {self_arg:
@@ -503,7 +502,7 @@ impl method_origin: tr {
 // Encoding and decoding vtable_res
 
 fn encode_vtable_res(ecx: @e::encode_ctxt,
-                     ebml_w: ebml2::Serializer,
+                     ebml_w: ebml::Serializer,
                      dr: typeck::vtable_res) {
     // can't autogenerate this code because automatic serialization of
     // ty::t doesn't work, and there is no way (atm) to have
@@ -515,7 +514,7 @@ fn encode_vtable_res(ecx: @e::encode_ctxt,
 }
 
 fn encode_vtable_origin(ecx: @e::encode_ctxt,
-                      ebml_w: ebml2::Serializer,
+                      ebml_w: ebml::Serializer,
                       vtable_origin: typeck::vtable_origin) {
     do ebml_w.emit_enum(~"vtable_origin") {
         match vtable_origin {
@@ -562,7 +561,7 @@ trait vtable_deserialization_helpers {
     fn read_vtable_origin(xcx: extended_decode_ctxt) -> typeck::vtable_origin;
 }
 
-impl ebml2::Deserializer: vtable_deserialization_helpers {
+impl ebml::Deserializer: vtable_deserialization_helpers {
     fn read_vtable_res(xcx: extended_decode_ctxt) -> typeck::vtable_res {
         @self.read_to_vec(|| self.read_vtable_origin(xcx) )
     }
@@ -639,7 +638,7 @@ trait ebml_writer_helpers {
     fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty);
 }
 
-impl ebml2::Serializer: ebml_writer_helpers {
+impl ebml::Serializer: ebml_writer_helpers {
     fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t) {
         do self.emit_opaque {
             e::write_type(ecx, self, ty)
@@ -692,7 +691,7 @@ trait write_tag_and_id {
     fn id(id: ast::node_id);
 }
 
-impl ebml2::Serializer: write_tag_and_id {
+impl ebml::Serializer: write_tag_and_id {
     fn tag(tag_id: c::astencode_tag, f: fn()) {
         do self.wr_tag(tag_id as uint) { f() }
     }
@@ -704,7 +703,7 @@ impl ebml2::Serializer: write_tag_and_id {
 
 fn encode_side_tables_for_ii(ecx: @e::encode_ctxt,
                              maps: maps,
-                             ebml_w: ebml2::Serializer,
+                             ebml_w: ebml::Serializer,
                              ii: ast::inlined_item) {
     do ebml_w.wr_tag(c::tag_table as uint) {
         ast_util::visit_ids_for_inlined_item(
@@ -720,7 +719,7 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt,
 
 fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
                              maps: maps,
-                             ebml_w: ebml2::Serializer,
+                             ebml_w: ebml::Serializer,
                              id: ast::node_id) {
     let tcx = ecx.tcx;
 
@@ -849,13 +848,13 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
 
 trait doc_decoder_helpers {
     fn as_int() -> int;
-    fn opt_child(tag: c::astencode_tag) -> Option<ebml2::Doc>;
+    fn opt_child(tag: c::astencode_tag) -> Option<ebml::Doc>;
 }
 
-impl ebml2::Doc: doc_decoder_helpers {
-    fn as_int() -> int { ebml2::doc_as_u64(self) as int }
-    fn opt_child(tag: c::astencode_tag) -> Option<ebml2::Doc> {
-        ebml2::maybe_get_doc(self, tag as uint)
+impl ebml::Doc: doc_decoder_helpers {
+    fn as_int() -> int { ebml::doc_as_u64(self) as int }
+    fn opt_child(tag: c::astencode_tag) -> Option<ebml::Doc> {
+        ebml::maybe_get_doc(self, tag as uint)
     }
 }
 
@@ -868,7 +867,7 @@ trait ebml_deserializer_decoder_helpers {
                                 -> ty::ty_param_bounds_and_ty;
 }
 
-impl ebml2::Deserializer: ebml_deserializer_decoder_helpers {
+impl ebml::Deserializer: ebml_deserializer_decoder_helpers {
 
     fn read_arg(xcx: extended_decode_ctxt) -> ty::arg {
         do self.read_opaque |doc| {
@@ -923,10 +922,10 @@ impl ebml2::Deserializer: ebml_deserializer_decoder_helpers {
 }
 
 fn decode_side_tables(xcx: extended_decode_ctxt,
-                      ast_doc: ebml2::Doc) {
+                      ast_doc: ebml::Doc) {
     let dcx = xcx.dcx;
     let tbl_doc = ast_doc[c::tag_table as uint];
-    for ebml2::docs(tbl_doc) |tag, entry_doc| {
+    for ebml::docs(tbl_doc) |tag, entry_doc| {
         let id0 = entry_doc[c::tag_table_id as uint].as_int();
         let id = xcx.tr_id(id0);
 
@@ -940,7 +939,7 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
             dcx.tcx.legacy_boxed_traits.insert(id, ());
         } else {
             let val_doc = entry_doc[c::tag_table_val as uint];
-            let val_dsr = &ebml2::Deserializer(val_doc);
+            let val_dsr = &ebml::Deserializer(val_doc);
             if tag == (c::tag_table_def as uint) {
                 let def = decode_def(xcx, val_doc);
                 dcx.tcx.def_map.insert(id, def);
@@ -993,16 +992,16 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
 // Testing of astencode_gen
 
 #[cfg(test)]
-fn encode_item_ast(ebml_w: ebml2::Serializer, item: @ast::item) {
+fn encode_item_ast(ebml_w: ebml::Serializer, item: @ast::item) {
     do ebml_w.wr_tag(c::tag_tree as uint) {
         (*item).serialize(&ebml_w)
     }
 }
 
 #[cfg(test)]
-fn decode_item_ast(par_doc: ebml2::Doc) -> @ast::item {
+fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
     let chi_doc = par_doc[c::tag_tree as uint];
-    let d = &ebml2::Deserializer(chi_doc);
+    let d = &ebml::Deserializer(chi_doc);
     @deserialize(d)
 }
 
@@ -1029,17 +1028,17 @@ fn mk_ctxt() -> fake_ext_ctxt {
 #[cfg(test)]
 fn roundtrip(in_item: @ast::item) {
     let bytes = do io::with_bytes_writer |wr| {
-        let ebml_w = ebml2::Serializer(wr);
+        let ebml_w = ebml::Serializer(wr);
         encode_item_ast(ebml_w, in_item);
     };
-    let ebml_doc = ebml2::Doc(@bytes);
+    let ebml_doc = ebml::Doc(@bytes);
     let out_item = decode_item_ast(ebml_doc);
 
     let exp_str = do io::with_str_writer |w| {
-        in_item.serialize(&std::prettyprint2::Serializer(w))
+        in_item.serialize(&std::prettyprint::Serializer(w))
     };
     let out_str = do io::with_str_writer |w| {
-        out_item.serialize(&std::prettyprint2::Serializer(w))
+        out_item.serialize(&std::prettyprint::Serializer(w))
     };
 
     debug!("expected string: %s", exp_str);
diff --git a/src/rustc/middle/freevars.rs b/src/rustc/middle/freevars.rs
index d26b9566c97..28400b5455d 100644
--- a/src/rustc/middle/freevars.rs
+++ b/src/rustc/middle/freevars.rs
@@ -16,6 +16,8 @@ export has_freevars;
 
 // A vector of defs representing the free variables referred to in a function.
 // (The def_upvar will already have been stripped).
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type freevar_entry = {
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index bbc3a06fb67..85f03e1f0b3 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -211,6 +211,8 @@ type method = {ident: ast::ident,
 
 type mt = {ty: t, mutbl: ast::mutability};
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum vstore {
@@ -271,6 +273,8 @@ enum ast_ty_to_ty_cache_entry {
 
 type opt_region_variance = Option<region_variance>;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum region_variance { rv_covariant, rv_invariant, rv_contravariant }
@@ -289,6 +293,8 @@ impl region_variance : cmp::Eq {
     pure fn ne(other: &region_variance) -> bool { !self.eq(other) }
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type AutoAdjustment = {
@@ -296,6 +302,8 @@ type AutoAdjustment = {
     autoref: Option<AutoRef>
 };
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type AutoRef = {
@@ -304,6 +312,8 @@ type AutoRef = {
     mutbl: ast::mutability
 };
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum AutoRefKind {
@@ -509,6 +519,8 @@ impl param_ty : to_bytes::IterBytes {
 
 
 /// Representation of regions:
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum region {
@@ -538,6 +550,8 @@ enum region {
     re_var(RegionVid)
 }
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum bound_region {
@@ -669,6 +683,8 @@ enum param_bound {
 enum TyVid = uint;
 enum IntVid = uint;
 enum FnVid = uint;
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum RegionVid = uint;
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index c2bd7f26bad..027a1d06742 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -75,6 +75,8 @@ export method_static, method_param, method_trait, method_self;
 export vtable_static, vtable_param, vtable_trait;
 export provided_methods_map;
 
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 enum method_origin {
@@ -93,6 +95,8 @@ enum method_origin {
 
 // details for a method invoked with a receiver whose type is a type parameter
 // with a bounded trait.
+#[auto_serialize]
+#[auto_deserialize]
 #[auto_serialize2]
 #[auto_deserialize2]
 type method_param = {
diff --git a/src/test/run-pass/auto_serialize2.rs b/src/test/run-pass/auto_serialize.rs
index 4503ea6c7e0..6c85f59b74e 100644
--- a/src/test/run-pass/auto_serialize2.rs
+++ b/src/test/run-pass/auto_serialize.rs
@@ -4,10 +4,10 @@ extern mod std;
 // the common code.
 
 use cmp::Eq;
-use std::ebml2;
+use std::ebml;
 use io::Writer;
-use std::serialization2::{Serializable, Deserializable, deserialize};
-use std::prettyprint2;
+use std::serialization::{Serializable, Deserializable, deserialize};
+use std::prettyprint;
 
 fn test_ser_and_deser<A:Eq Serializable Deserializable>(
     a1: &A,
@@ -15,23 +15,23 @@ fn test_ser_and_deser<A:Eq Serializable Deserializable>(
 ) {
     // check the pretty printer:
     let s = do io::with_str_writer |w| {
-        a1.serialize(&prettyprint2::Serializer(w))
+        a1.serialize(&prettyprint::Serializer(w))
     };
     debug!("s == %?", s);
     assert s == expected;
 
     // check the EBML serializer:
     let bytes = do io::with_bytes_writer |wr| {
-        let ebml_w = &ebml2::Serializer(wr);
+        let ebml_w = &ebml::Serializer(wr);
         a1.serialize(ebml_w)
     };
-    let d = ebml2::Doc(@bytes);
-    let a2: A = deserialize(&ebml2::Deserializer(d));
+    let d = ebml::Doc(@bytes);
+    let a2: A = deserialize(&ebml::Deserializer(d));
     assert *a1 == a2;
 }
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 enum Expr {
     Val(uint),
     Plus(@Expr, @Expr),
@@ -105,8 +105,8 @@ impl CLike : cmp::Eq {
     pure fn ne(other: &CLike) -> bool { !self.eq(other) }
 }
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 type Spanned<T> = {lo: uint, hi: uint, node: T};
 
 impl<T:cmp::Eq> Spanned<T> : cmp::Eq {
@@ -116,27 +116,27 @@ impl<T:cmp::Eq> Spanned<T> : cmp::Eq {
     pure fn ne(other: &Spanned<T>) -> bool { !self.eq(other) }
 }
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 type SomeRec = {v: ~[uint]};
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 enum AnEnum = SomeRec;
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 struct Point {x: uint, y: uint}
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 enum Quark<T> {
     Top(T),
     Bottom(T)
 }
 
-#[auto_serialize2]
-#[auto_deserialize2]
+#[auto_serialize]
+#[auto_deserialize]
 enum CLike { A, B, C }
 
 fn main() {