summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorSimon BD <simon@server>2012-10-22 18:33:41 -0500
committerSimon BD <simon@server>2012-10-22 18:33:41 -0500
commitcc0f2c6bb26ba38d3487a396fa8625e938af6820 (patch)
tree6c2063df35144c5477b0adc9e49933d71224dc2a /src/libsyntax/ext
parent9aec7a3e85c5b07923eab05d3ebe9d031bf258f3 (diff)
parent9ee5fff4f16cfc3390bd69abbb46b0a68521667c (diff)
downloadrust-cc0f2c6bb26ba38d3487a396fa8625e938af6820.tar.gz
rust-cc0f2c6bb26ba38d3487a396fa8625e938af6820.zip
Merge remote-tracking branch 'original/incoming' into incoming
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/auto_serialize.rs1731
-rw-r--r--src/libsyntax/ext/auto_serialize2.rs1025
-rw-r--r--src/libsyntax/ext/base.rs27
-rw-r--r--src/libsyntax/ext/env.rs4
-rw-r--r--src/libsyntax/ext/fmt.rs16
-rw-r--r--src/libsyntax/ext/pipes.rs4
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs60
-rw-r--r--src/libsyntax/ext/pipes/check.rs4
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs2
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs8
-rw-r--r--src/libsyntax/ext/pipes/proto.rs12
-rw-r--r--src/libsyntax/ext/qquote.rs22
-rw-r--r--src/libsyntax/ext/simplext.rs4
-rw-r--r--src/libsyntax/ext/trace_macros.rs6
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs14
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs6
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs9
17 files changed, 1049 insertions, 1905 deletions
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index 64915c60742..47e61c26f38 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -1,62 +1,70 @@
 /*
 
-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<S: Serializer> node_id: Serializable<S> {
+        fn serialize(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<D: Deserializer> node_id: Deserializable {
+        static fn deserialize(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<
+        S: Serializer,
+        T: Serializable<S>
+    > spanned<T>: Serializable<S> {
+        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<
+        D: Deserializer,
+        T: Deserializable<D>
+    > spanned<T>: Deserializable<D> {
+        static fn deserialize(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,137 +77,167 @@ 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(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_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, not_auto_serialize),
+        @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize(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_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]
         }
     }
 }
 
-trait ext_ctxt_helpers {
-    fn helper_path(base_path: @ast::path, helper_name: ~str) -> @ast::path;
-    fn path(span: span, strs: ~[ast::ident]) -> @ast::path;
-    fn path_tps(span: span, strs: ~[ast::ident],
-                tps: ~[@ast::ty]) -> @ast::path;
-    fn ty_path(span: span, strs: ~[ast::ident], tps: ~[@ast::ty]) -> @ast::ty;
-    fn ty_fn(span: span,
-             -input_tys: ~[@ast::ty],
-             -output: @ast::ty) -> @ast::ty;
-    fn ty_nil(span: span) -> @ast::ty;
-    fn expr(span: span, node: ast::expr_) -> @ast::expr;
-    fn var_ref(span: span, name: ast::ident) -> @ast::expr;
-    fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk;
-    fn expr_blk(expr: @ast::expr) -> ast::blk;
-    fn binder_pat(span: span, nm: ast::ident) -> @ast::pat;
-    fn stmt(expr: @ast::expr) -> @ast::stmt;
-    fn alt_stmt(arms: ~[ast::arm], span: span, -v: @ast::expr) -> @ast::stmt;
-    fn lit_str(span: span, s: @~str) -> @ast::expr;
-    fn lit_uint(span: span, i: uint) -> @ast::expr;
-    fn lambda(blk: ast::blk) -> @ast::expr;
-    fn clone_folder() -> fold::ast_fold;
-    fn clone(v: @ast::expr) -> @ast::expr;
-    fn clone_ty(v: @ast::ty) -> @ast::ty;
-    fn clone_ty_param(v: ast::ty_param) -> ast::ty_param;
-    fn at(span: span, expr: @ast::expr) -> @ast::expr;
-}
-
-impl ext_ctxt: ext_ctxt_helpers {
-    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 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 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 filter_attrs(item: @ast::item) -> @ast::item {
+        @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize(a)),
+          .. *item}
     }
 
-    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}
+    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]
+        }
     }
+}
 
-    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()}
-        };
-
-        @{id: self.next_id(),
-          node: ast::ty_fn(ast::proto_block,
-                           ast::impure_fn,
-                           @~[],
-                           {inputs: args,
-                            output: output,
-                            cf: ast::return_val}),
-          span: span}
-    }
+priv impl ext_ctxt {
+    fn bind_path(
+        span: span,
+        ident: ast::ident,
+        path: @ast::path,
+        bounds: @~[ast::ty_param_bound]
+    ) -> ast::ty_param {
+        let bound = ast::ty_param_bound(@{
+            id: self.next_id(),
+            node: ast::ty_path(path, self.next_id()),
+            span: span,
+        });
 
-    fn ty_nil(span: span) -> @ast::ty {
-        @{id: self.next_id(), node: ast::ty_nil, span: span}
+        {
+            ident: ident,
+            id: self.next_id(),
+            bounds: @vec::append(~[bound], *bounds)
+        }
     }
 
     fn expr(span: span, node: ast::expr_) -> @ast::expr {
@@ -207,26 +245,20 @@ impl ext_ctxt: ext_ctxt_helpers {
           node: node, span: span}
     }
 
-    fn var_ref(span: span, name: ast::ident) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path(span, ~[name])))
+    fn path(span: span, strs: ~[ast::ident]) -> @ast::path {
+        @{span: span, global: false, idents: strs, rp: None, types: ~[]}
     }
 
-    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 path_tps(span: span, strs: ~[ast::ident],
+                tps: ~[@ast::Ty]) -> @ast::path {
+        @{span: span, global: false, idents: strs, rp: None, types: tps}
     }
 
-    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 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 {
@@ -244,14 +276,6 @@ impl ext_ctxt: ext_ctxt_helpers {
           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,
@@ -278,686 +302,835 @@ impl ext_ctxt: ext_ctxt_helpers {
         #ast{ || $(blk_e) }
     }
 
-    fn clone_folder() -> fold::ast_fold {
-        fold::make_fold(@{
-            new_id: |_id| self.next_id(),
-            .. *fold::default_ast_fold()
-        })
+    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(v: @ast::expr) -> @ast::expr {
-        let fld = self.clone_folder();
-        fld.fold_expr(v)
+    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 clone_ty(v: @ast::ty) -> @ast::ty {
-        let fld = self.clone_folder();
-        fld.fold_ty(v)
+    fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr {
+        self.expr(span, ast::expr_path(self.path(span, strs)))
     }
 
-    fn clone_ty_param(v: ast::ty_param) -> ast::ty_param {
-        let fld = self.clone_folder();
-        fold::fold_ty_param(v, fld)
+    fn expr_var(span: span, var: ~str) -> @ast::expr {
+        self.expr_path(span, ~[self.ident_of(var)])
     }
 
-    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
-            }
-        }
-
-        let fld = fold::make_fold(@{
-            new_span: |a| repl_sp(a, ast_util::dummy_sp(), span),
-            .. *fold::default_ast_fold()
-        });
+    fn expr_field(
+        span: span,
+        expr: @ast::expr,
+        ident: ast::ident
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_field(expr, ident, ~[]))
+    }
 
-        fld.fold_expr(expr)
+    fn expr_call(
+        span: span,
+        expr: @ast::expr,
+        args: ~[@ast::expr]
+    ) -> @ast::expr {
+        self.expr(span, ast::expr_call(expr, args, false))
     }
-}
 
-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 lambda_expr(expr: @ast::expr) -> @ast::expr {
+        self.lambda(self.expr_blk(expr))
+    }
 
-    ~[cx.stmt(
-        cx.expr(
-            path.span,
-            ast::expr_call(callee, vec::append(~[s, v], ty_args), false)))]
+    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))
-    };
-
-    let body_blk = cx.blk(span, stmts);
-    let body = cx.blk(span, ~[cx.stmt(bodyfn(move s, body_blk))]);
+fn mk_impl(
+    cx: ext_ctxt,
+    span: span,
+    ident: ast::ident,
+    ty_param: ast::ty_param,
+    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 mut trait_tps = vec::append(
+        ~[ty_param],
+         do tps.map |tp| {
+            let t_bound = ast::ty_param_bound(@{
+                id: cx.next_id(),
+                node: ast::ty_path(path, cx.next_id()),
+                span: span,
+            });
 
-    {pats: ~[pat], guard: None, body: body}
+            {
+                ident: tp.ident,
+                id: cx.next_id(),
+                bounds: @vec::append(~[t_bound], *tp.bounds)
+            }
+        }
+    );
+
+    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 typaram.
+    let ty_param = cx.bind_path(
+        span,
+        cx.ident_of(~"__S"),
+        cx.path(
+            span,
+            ~[
+                cx.ident_of(~"std"),
+                cx.ident_of(~"serialization"),
+                cx.ident_of(~"Serializer"),
+            ]
+        ),
+        @~[]
+    );
+
+    // Make a path to the std::serialization::Serializable trait.
+    let path = cx.path_tps(
+        span,
+        ~[
+            cx.ident_of(~"std"),
+            cx.ident_of(~"serialization"),
+            cx.ident_of(~"Serializable"),
+        ],
+        ~[cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[])]
+    );
+
+    mk_impl(
+        cx,
+        span,
+        ident,
+        ty_param,
+        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 typaram.
+    let ty_param = cx.bind_path(
+        span,
+        cx.ident_of(~"__D"),
+        cx.path(
+            span,
+            ~[
+                cx.ident_of(~"std"),
+                cx.ident_of(~"serialization"),
+                cx.ident_of(~"Deserializer"),
+            ]
+        ),
+        @~[]
+    );
+
+    // Make a path to the std::serialization::Deserializable trait.
+    let path = cx.path_tps(
+        span,
+        ~[
+            cx.ident_of(~"std"),
+            cx.ident_of(~"serialization"),
+            cx.ident_of(~"Deserializable"),
+        ],
+        ~[cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[])]
+    );
+
+    mk_impl(
+        cx,
+        span,
+        ident,
+        ty_param,
+        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"));
-        ~[]
-      }
-
-      ast::ty_box(mt) => {
-        let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) });
-        ~[#ast[stmt]{$(s).emit_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) => {
-        ser_ty(cx, tps, mt.ty, move s, move v)
-      }
-
-      ast::ty_uniq(mt) => {
-        let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) });
-        ~[#ast[stmt]{$(s).emit_uniq($(l));}]
-      }
-
-      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));}]
-      }
-
-      ast::ty_fn(*) => {
-        cx.span_err(ty.span, ~"cannot serialize function types");
-        ~[]
-      }
-
-      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)
+fn mk_ser_method(
+    cx: ext_ctxt,
+    span: span,
+    ser_body: ast::blk
+) -> @ast::method {
+    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
             }
-        } else {
-            ser_path(cx, tps, path, move s, move v)
-        }
-      }
+        ),
+        span: span,
+    };
 
-      ast::ty_mac(_) => {
-        cx.span_err(ty.span, ~"cannot serialize macro types");
-        ~[]
-      }
+    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_infer => {
-        cx.span_err(ty.span, ~"cannot serialize inferred types");
-        ~[]
-      }
+    let ser_decl = {
+        inputs: ser_inputs,
+        output: ser_output,
+        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(~"serialize"),
+        attrs: ~[],
+        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,
     }
 }
 
-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));}]
-            });
-    }
+fn mk_deser_method(
+    cx: ext_ctxt,
+    span: span,
+    ty: @ast::Ty,
+    deser_body: ast::blk
+) -> @ast::method {
+    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
+            }
+        ),
+        span: span,
+    };
 
-    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}
+    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,
+    };
+
+    @{
+        ident: cx.ident_of(~"deserialize"),
+        attrs: ~[],
+        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_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)]
+    );
 
-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.
+    mk_ser_impl(cx, span, ident, tps, body)
+}
 
-    let callee =
-        cx.expr(
-            path.span,
-            ast::expr_path(
-                cx.helper_path(path, ~"deserialize")));
+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)
+                )
+            )
+        ]
+    );
 
-    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))
-    };
+    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 }
-      }
+    }
+}
 
-      ast::ty_vec(mt) => {
-        let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
-        #ast{ std::serialization::read_to_vec($(d), $(l)) }
-      }
+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_fixed_length(_, _) => {
-        cx.span_unimpl(ty.span, ~"deserialization for fixed length types");
-      }
+        {
+            span: field.span,
+            ident: ident,
+            mutbl: match mutbl {
+                ast::class_mutable => ast::m_mutbl,
+                ast::class_immutable => ast::m_imm,
+            },
+        }
     }
 }
 
-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)() }
-            });
+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,
+                ]
+            )
+        )
     }
+}
 
-    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",
         }
+    };
 
-        {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)}
+    // 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),
+        ]
+    )
+}
+
+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
deleted file mode 100644
index 99f837a4c84..00000000000
--- a/src/libsyntax/ext/auto_serialize2.rs
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
-
-The compiler code necessary to implement the #[auto_serialize2] and
-#[auto_deserialize2] extension.  The idea here is that type-defining items may
-be tagged with #[auto_serialize2] and #[auto_deserialize2], which will cause
-us to generate a little companion module with the same name as the item.
-
-For example, a type like:
-
-    #[auto_serialize2]
-    #[auto_deserialize2]
-    struct Node {id: uint}
-
-would generate two implementations like:
-
-    impl Node: Serializable {
-        fn serialize<S: Serializer>(s: &S) {
-            do s.emit_struct("Node") {
-                s.emit_field("id", 0, || s.emit_uint(self))
-            }
-        }
-    }
-
-    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_serialize2]
-    #[auto_deserialize2]
-    type spanned<T> = {node: T, span: span};
-
-would yield functions like:
-
-    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));
-            }
-        }
-    }
-
-    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.
-
-Misc notes:
------------
-
-I use move mode arguments for ast nodes that will get inserted as is
-into the tree.  This is intended to prevent us from inserting the same
-node twice.
-
-*/
-
-use base::*;
-use codemap::span;
-use std::map;
-use std::map::HashMap;
-
-export expand_auto_serialize;
-export expand_auto_deserialize;
-
-// Transitional reexports so qquote can find the paths it is looking for
-mod syntax {
-    pub use ext;
-    pub use parse;
-}
-
-fn expand_auto_serialize(
-    cx: ext_ctxt,
-    span: span,
-    _mitem: ast::meta_item,
-    in_items: ~[@ast::item]
-) -> ~[@ast::item] {
-    fn is_auto_serialize2(a: &ast::attribute) -> bool {
-        attr::get_attr_name(*a) == ~"auto_serialize2"
-    }
-
-    fn filter_attrs(item: @ast::item) -> @ast::item {
-        @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize2(a)),
-          .. *item}
-    }
-
-    do vec::flat_map(in_items) |item| {
-        if item.attrs.any(is_auto_serialize2) {
-            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_serialize2] can only be \
-                                        applied to structs, record types, \
-                                        and enum definitions");
-                    ~[*item]
-                }
-            }
-        } else {
-            ~[*item]
-        }
-    }
-}
-
-fn expand_auto_deserialize(
-    cx: ext_ctxt,
-    span: span,
-    _mitem: ast::meta_item,
-    in_items: ~[@ast::item]
-) -> ~[@ast::item] {
-    fn is_auto_deserialize2(a: &ast::attribute) -> bool {
-        attr::get_attr_name(*a) == ~"auto_deserialize2"
-    }
-
-    fn filter_attrs(item: @ast::item) -> @ast::item {
-        @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize2(a)),
-          .. *item}
-    }
-
-    do vec::flat_map(in_items) |item| {
-        if item.attrs.any(is_auto_deserialize2) {
-            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_deserialize2] can only be \
-                                        applied to structs, record types, \
-                                        and enum definitions");
-                    ~[*item]
-                }
-            }
-        } else {
-            ~[*item]
-        }
-    }
-}
-
-priv impl ext_ctxt {
-    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,
-    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,
-        });
-
-        {
-            ident: tp.ident,
-            id: cx.next_id(),
-            bounds: @vec::append(~[t_bound], *tp.bounds)
-        }
-    };
-
-    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 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::serialization2::Serializable trait.
-    let path = cx.path(
-        span,
-        ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialization2"),
-            cx.ident_of(~"Serializable"),
-        ]
-    );
-
-    mk_impl(
-        cx,
-        span,
-        ident,
-        path,
-        tps,
-        |_ty| mk_ser_method(cx, span, cx.expr_blk(body))
-    )
-}
-
-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::serialization2::Deserializable trait.
-    let path = cx.path(
-        span,
-        ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialization2"),
-            cx.ident_of(~"Deserializable"),
-        ]
-    );
-
-    mk_impl(
-        cx,
-        span,
-        ident,
-        path,
-        tps,
-        |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body))
-    )
-}
-
-fn mk_ser_method(
-    cx: ext_ctxt,
-    span: span,
-    ser_body: ast::blk
-) -> @ast::method {
-    let ser_bound = cx.ty_path(
-        span,
-        ~[
-            cx.ident_of(~"std"),
-            cx.ident_of(~"serialization2"),
-            cx.ident_of(~"Serializer"),
-        ],
-        ~[]
-    );
-
-    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,
-    };
-
-    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,
-    };
-
-    let ser_decl = {
-        inputs: ser_inputs,
-        output: ser_output,
-        cf: ast::return_val,
-    };
-
-    @{
-        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,
-    }
-}
-
-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(~"serialization2"),
-            cx.ident_of(~"Deserializer"),
-        ],
-        ~[]
-    );
-
-    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
-            }
-        ),
-        span: span,
-    };
-
-    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,
-    };
-
-    @{
-        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_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)]
-    );
-
-    mk_ser_impl(cx, span, ident, tps, body)
-}
-
-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)
-}
-
-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 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)
-}
-
-// 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,
-        }
-    }
-}
-
-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_serialize2] does not support \
-                        unnamed fields",
-        };
-
-        {
-            span: field.span,
-            ident: ident,
-            mutbl: match mutbl {
-                ast::class_mutable => ast::m_mutbl,
-                ast::class_immutable => ast::m_imm,
-            },
-        }
-    }
-}
-
-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_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::serialization2::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(~"serialization2"),
-                        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.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 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)
-}
-
-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_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)
-        )
-    };
-
-    let pat = @{
-        id: cx.next_id(),
-        node: pat_node,
-        span: span,
-    };
-
-    let stmts = do args.mapi |a_idx, _arg| {
-        // ast for `__s.emit_enum_variant_arg`
-        let expr_emit = cx.expr_field(
-            span,
-            cx.expr_var(span, ~"__s"),
-            cx.ident_of(~"emit_enum_variant_arg")
-        );
-
-        // ast for `|| $(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]
-            )
-        )
-    };
-
-    // 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) }
-}
-
-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) =>
-                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",
-        }
-    };
-
-    // 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),
-        ]
-    )
-}
-
-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::serialization2::deserialize(__d)`
-        let expr_lambda = cx.lambda_expr(
-            cx.expr_call(
-                span,
-                cx.expr_path(span, ~[
-                    cx.ident_of(~"std"),
-                    cx.ident_of(~"serialization2"),
-                    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]
-        )
-    };
-
-    // ast for `$(name)($(args))`
-    cx.expr_call(span, cx.expr_path(span, ~[name]), args)
-}
-
-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/base.rs b/src/libsyntax/ext/base.rs
index 9a31cc1d8f6..5b4cc23ce09 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1,7 +1,7 @@
 use std::map::HashMap;
 use parse::parser;
 use diagnostic::span_handler;
-use codemap::{codemap, span, expn_info, expanded_from};
+use codemap::{CodeMap, span, expn_info, expanded_from};
 
 // obsolete old-style #macro code:
 //
@@ -80,14 +80,12 @@ 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));
+        ~"auto_serialize",
+        item_decorator(ext::auto_serialize::expand_auto_serialize));
     syntax_expanders.insert(
-        ~"auto_deserialize2",
-        item_decorator(ext::auto_serialize2::expand_auto_deserialize));
+        ~"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));
@@ -122,12 +120,11 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
     return syntax_expanders;
 }
 
-
 // One of these is made during expansion and incrementally updated as we go;
 // when a macro expansion occurs, the resulting nodes have the backtrace()
 // -> expn_info of their expansion context stored into their span.
 trait ext_ctxt {
-    fn codemap() -> codemap;
+    fn codemap() -> CodeMap;
     fn parse_sess() -> parse::parse_sess;
     fn cfg() -> ast::crate_cfg;
     fn print_backtrace();
@@ -159,7 +156,7 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
                       mut mod_path: ~[ast::ident],
                       mut trace_mac: bool};
     impl ctxt_repr: ext_ctxt {
-        fn codemap() -> codemap { self.parse_sess.cm }
+        fn codemap() -> CodeMap { self.parse_sess.cm }
         fn parse_sess() -> parse::parse_sess { self.parse_sess }
         fn cfg() -> ast::crate_cfg { self.cfg }
         fn print_backtrace() { }
@@ -234,7 +231,7 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
         mut mod_path: ~[],
         mut trace_mac: false
     };
-    move (imp as ext_ctxt)
+    move ((move imp) as ext_ctxt)
 }
 
 fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: ~str) -> ~str {
@@ -272,21 +269,21 @@ fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
               match max {
                 Some(max) if ! (min <= elts_len && elts_len <= max) => {
                   cx.span_fatal(sp,
-                                fmt!("#%s takes between %u and %u arguments.",
+                                fmt!("%s! takes between %u and %u arguments.",
                                      name, min, max));
                 }
                 None if ! (min <= elts_len) => {
-                  cx.span_fatal(sp, fmt!("#%s needs at least %u arguments.",
+                  cx.span_fatal(sp, fmt!("%s! needs at least %u arguments.",
                                          name, min));
                 }
                 _ => return elts /* we are good */
               }
           }
         _ => {
-            cx.span_fatal(sp, fmt!("#%s: malformed invocation", name))
+            cx.span_fatal(sp, fmt!("%s!: malformed invocation", name))
         }
       },
-      None => cx.span_fatal(sp, fmt!("#%s: missing arguments", name))
+      None => cx.span_fatal(sp, fmt!("%s!: missing arguments", name))
     }
 }
 
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 8cecceb2e55..37fb0f05cbd 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -1,6 +1,6 @@
 
 /*
- * The compiler code necessary to support the #env extension.  Eventually this
+ * The compiler code necessary to support the env! extension.  Eventually this
  * should all get sucked into either the compiler syntax extension plugin
  * interface.
  */
@@ -15,7 +15,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
     // FIXME (#2248): if this was more thorough it would manufacture an
     // Option<str> rather than just an maybe-empty string.
 
-    let var = expr_to_str(cx, args[0], ~"#env requires a string");
+    let var = expr_to_str(cx, args[0], ~"env! requires a string");
     match os::getenv(var) {
       option::None => return mk_uniq_str(cx, sp, ~""),
       option::Some(s) => return mk_uniq_str(cx, sp, s)
diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs
index ea493eab561..e24575f6cd3 100644
--- a/src/libsyntax/ext/fmt.rs
+++ b/src/libsyntax/ext/fmt.rs
@@ -1,7 +1,7 @@
 
 
 /*
- * The compiler code necessary to support the #fmt extension. Eventually this
+ * The compiler code necessary to support the fmt! extension. Eventually this
  * should all get sucked into either the standard library extfmt module or the
  * compiler syntax extension plugin interface.
  */
@@ -16,7 +16,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
     let args = get_mac_args_no_max(cx, sp, arg, 1u, ~"fmt");
     let fmt =
         expr_to_str(cx, args[0],
-                    ~"first argument to #fmt must be a string literal.");
+                    ~"first argument to fmt! must be a string literal.");
     let fmtspan = args[0].span;
     debug!("Format string:");
     log(debug, fmt);
@@ -76,7 +76,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
                 let count_is_args = ~[count_lit];
                 return mk_call(cx, sp, count_is_path, count_is_args);
               }
-              _ => cx.span_unimpl(sp, ~"unimplemented #fmt conversion")
+              _ => cx.span_unimpl(sp, ~"unimplemented fmt! conversion")
             }
         }
         fn make_ty(cx: ext_ctxt, sp: span, t: Ty) -> @ast::expr {
@@ -133,7 +133,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
               _ => return false
             }
         }
-        let unsupported = ~"conversion not supported in #fmt string";
+        let unsupported = ~"conversion not supported in fmt! string";
         match cnv.param {
           option::None => (),
           _ => cx.span_unimpl(sp, unsupported)
@@ -145,14 +145,14 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
                 if !is_signed_type(cnv) {
                     cx.span_fatal(sp,
                                   ~"+ flag only valid in " +
-                                      ~"signed #fmt conversion");
+                                      ~"signed fmt! conversion");
                 }
               }
               FlagSpaceForSign => {
                 if !is_signed_type(cnv) {
                     cx.span_fatal(sp,
                                   ~"space flag only valid in " +
-                                      ~"signed #fmt conversions");
+                                      ~"signed fmt! conversions");
                 }
               }
               FlagLeftZeroPad => (),
@@ -252,7 +252,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
             n += 1u;
             if n >= nargs {
                 cx.span_fatal(sp,
-                              ~"not enough arguments to #fmt " +
+                              ~"not enough arguments to fmt! " +
                                   ~"for the given format string");
             }
             debug!("Building conversion:");
@@ -267,7 +267,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
 
     if expected_nargs < nargs {
         cx.span_fatal
-            (sp, fmt!("too many arguments to #fmt. found %u, expected %u",
+            (sp, fmt!("too many arguments to fmt!. found %u, expected %u",
                            nargs, expected_nargs));
     }
 
diff --git a/src/libsyntax/ext/pipes.rs b/src/libsyntax/ext/pipes.rs
index ad4984c5558..4d04552bfa1 100644
--- a/src/libsyntax/ext/pipes.rs
+++ b/src/libsyntax/ext/pipes.rs
@@ -37,7 +37,7 @@ use codemap::span;
 use ext::base::ext_ctxt;
 use ast::tt_delim;
 use parse::lexer::{new_tt_reader, reader};
-use parse::parser::{parser, SOURCE_FILE};
+use parse::parser::{Parser, SOURCE_FILE};
 use parse::common::parser_common;
 
 use pipes::parse_proto::proto_parser;
@@ -52,7 +52,7 @@ fn expand_proto(cx: ext_ctxt, _sp: span, id: ast::ident,
     let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
                                cx.parse_sess().interner, None, tt);
     let rdr = tt_rdr as reader;
-    let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
+    let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
 
     let proto = rust_parser.parse_proto(cx.str_of(id));
 
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 4da9992b0dd..f10cbc2a589 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -28,17 +28,17 @@ fn empty_span() -> span {
 }
 
 trait append_types {
-    fn add_ty(ty: @ast::ty) -> @ast::path;
-    fn add_tys(+tys: ~[@ast::ty]) -> @ast::path;
+    fn add_ty(ty: @ast::Ty) -> @ast::path;
+    fn add_tys(+tys: ~[@ast::Ty]) -> @ast::path;
 }
 
 impl @ast::path: append_types {
-    fn add_ty(ty: @ast::ty) -> @ast::path {
+    fn add_ty(ty: @ast::Ty) -> @ast::path {
         @{types: vec::append_one(self.types, ty),
           .. *self}
     }
 
-    fn add_tys(+tys: ~[@ast::ty]) -> @ast::path {
+    fn add_tys(+tys: ~[@ast::Ty]) -> @ast::path {
         @{types: vec::append(self.types, tys),
           .. *self}
     }
@@ -47,18 +47,18 @@ impl @ast::path: append_types {
 trait ext_ctxt_ast_builder {
     fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
         -> ast::ty_param;
-    fn arg(name: ident, ty: @ast::ty) -> ast::arg;
+    fn arg(name: ident, ty: @ast::Ty) -> ast::arg;
     fn expr_block(e: @ast::expr) -> ast::blk;
-    fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl;
+    fn fn_decl(+inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl;
     fn item(name: ident, span: span, +node: ast::item_) -> @ast::item;
     fn item_fn_poly(name: ident,
                     +inputs: ~[ast::arg],
-                    output: @ast::ty,
+                    output: @ast::Ty,
                     +ty_params: ~[ast::ty_param],
                     +body: ast::blk) -> @ast::item;
     fn item_fn(name: ident,
                +inputs: ~[ast::arg],
-               output: @ast::ty,
+               output: @ast::Ty,
                +body: ast::blk) -> @ast::item;
     fn item_enum_poly(name: ident,
                       span: span,
@@ -66,17 +66,17 @@ trait ext_ctxt_ast_builder {
                       +ty_params: ~[ast::ty_param]) -> @ast::item;
     fn item_enum(name: ident, span: span,
                  +enum_definition: ast::enum_def) -> @ast::item;
-    fn variant(name: ident, span: span, +tys: ~[@ast::ty]) -> ast::variant;
+    fn variant(name: ident, span: span, +tys: ~[@ast::Ty]) -> ast::variant;
     fn item_mod(name: ident, span: span, +items: ~[@ast::item]) -> @ast::item;
-    fn ty_path_ast_builder(path: @ast::path) -> @ast::ty;
+    fn ty_path_ast_builder(path: @ast::path) -> @ast::Ty;
     fn item_ty_poly(name: ident,
                     span: span,
-                    ty: @ast::ty,
+                    ty: @ast::Ty,
                     +params: ~[ast::ty_param]) -> @ast::item;
-    fn item_ty(name: ident, span: span, ty: @ast::ty) -> @ast::item;
-    fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty];
-    fn ty_field_imm(name: ident, ty: @ast::ty) -> ast::ty_field;
-    fn ty_rec(+v: ~[ast::ty_field]) -> @ast::ty;
+    fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item;
+    fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty];
+    fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field;
+    fn ty_rec(+v: ~[ast::ty_field]) -> @ast::Ty;
     fn field_imm(name: ident, e: @ast::expr) -> ast::field;
     fn rec(+v: ~[ast::field]) -> @ast::expr;
     fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk;
@@ -84,11 +84,11 @@ trait ext_ctxt_ast_builder {
     fn stmt_expr(e: @ast::expr) -> @ast::stmt;
     fn block_expr(b: ast::blk) -> @ast::expr;
     fn empty_span() -> span;
-    fn ty_option(ty: @ast::ty) -> @ast::ty;
+    fn ty_option(ty: @ast::Ty) -> @ast::Ty;
 }
 
 impl ext_ctxt: ext_ctxt_ast_builder {
-    fn ty_option(ty: @ast::ty) -> @ast::ty {
+    fn ty_option(ty: @ast::Ty) -> @ast::Ty {
         self.ty_path_ast_builder(path(~[self.ident_of(~"Option")],
                                       self.empty_span())
                                  .add_ty(ty))
@@ -146,18 +146,18 @@ impl ext_ctxt: ext_ctxt_ast_builder {
           span: self.empty_span()}
     }
 
-    fn ty_field_imm(name: ident, ty: @ast::ty) -> ast::ty_field {
+    fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field {
         {node: {ident: name, mt: { ty: ty, mutbl: ast::m_imm } },
           span: self.empty_span()}
     }
 
-    fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::ty {
+    fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::Ty {
         @{id: self.next_id(),
           node: ast::ty_rec(fields),
           span: self.empty_span()}
     }
 
-    fn ty_infer() -> @ast::ty {
+    fn ty_infer() -> @ast::Ty {
         @{id: self.next_id(),
           node: ast::ty_infer,
           span: self.empty_span()}
@@ -169,7 +169,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
         {ident: id, id: self.next_id(), bounds: @bounds}
     }
 
-    fn arg(name: ident, ty: @ast::ty) -> ast::arg {
+    fn arg(name: ident, ty: @ast::Ty) -> ast::arg {
         {mode: ast::infer(self.next_id()),
          ty: ty,
          ident: name,
@@ -192,7 +192,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
     }
 
     fn fn_decl(+inputs: ~[ast::arg],
-               output: @ast::ty) -> ast::fn_decl {
+               output: @ast::Ty) -> ast::fn_decl {
         {inputs: inputs,
          output: output,
          cf: ast::return_val}
@@ -224,7 +224,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
 
     fn item_fn_poly(name: ident,
                     +inputs: ~[ast::arg],
-                    output: @ast::ty,
+                    output: @ast::Ty,
                     +ty_params: ~[ast::ty_param],
                     +body: ast::blk) -> @ast::item {
         self.item(name,
@@ -237,7 +237,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
 
     fn item_fn(name: ident,
                +inputs: ~[ast::arg],
-               output: @ast::ty,
+               output: @ast::Ty,
                +body: ast::blk) -> @ast::item {
         self.item_fn_poly(name, inputs, output, ~[], body)
     }
@@ -256,7 +256,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
 
     fn variant(name: ident,
                span: span,
-               +tys: ~[@ast::ty]) -> ast::variant {
+               +tys: ~[@ast::Ty]) -> ast::variant {
         let args = tys.map(|ty| {ty: *ty, id: self.next_id()});
 
         {node: {name: name,
@@ -278,13 +278,13 @@ impl ext_ctxt: ext_ctxt_ast_builder {
                       items: items}))
     }
 
-    fn ty_path_ast_builder(path: @ast::path) -> @ast::ty {
+    fn ty_path_ast_builder(path: @ast::path) -> @ast::Ty {
         @{id: self.next_id(),
           node: ast::ty_path(path, self.next_id()),
           span: path.span}
     }
 
-    fn ty_nil_ast_builder() -> @ast::ty {
+    fn ty_nil_ast_builder() -> @ast::Ty {
         @{id: self.next_id(),
           node: ast::ty_nil,
           span: self.empty_span()}
@@ -292,16 +292,16 @@ impl ext_ctxt: ext_ctxt_ast_builder {
 
     fn item_ty_poly(name: ident,
                     span: span,
-                    ty: @ast::ty,
+                    ty: @ast::Ty,
                     +params: ~[ast::ty_param]) -> @ast::item {
         self.item(name, span, ast::item_ty(ty, params))
     }
 
-    fn item_ty(name: ident, span: span, ty: @ast::ty) -> @ast::item {
+    fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item {
         self.item_ty_poly(name, span, ty, ~[])
     }
 
-    fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] {
+    fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] {
         ty_params.map(|p| self.ty_path_ast_builder(
             path(~[p.ident], self.empty_span())))
     }
diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs
index 5fcc00ef012..fcc0c84a4ff 100644
--- a/src/libsyntax/ext/pipes/check.rs
+++ b/src/libsyntax/ext/pipes/check.rs
@@ -38,7 +38,7 @@ impl ext_ctxt: proto::visitor<(), (), ()>  {
         }
     }
 
-    fn visit_message(name: ~str, _span: span, _tys: &[@ast::ty],
+    fn visit_message(name: ~str, _span: span, _tys: &[@ast::Ty],
                      this: state, next: next_state) {
         match next {
           Some({state: next, tys: next_tys}) => {
@@ -68,4 +68,4 @@ impl ext_ctxt: proto::visitor<(), (), ()>  {
           None => ()
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index 5c15b616b4a..8f2b92a720c 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -10,7 +10,7 @@ trait proto_parser {
     fn parse_state(proto: protocol);
 }
 
-impl parser: proto_parser {
+impl parser::Parser: proto_parser {
     fn parse_proto(id: ~str) -> protocol {
         let proto = protocol(id, self.span);
 
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 874ea01e9b0..7e1cbe9ad0d 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -181,7 +181,7 @@ impl message: gen_send {
           }
         }
 
-    fn to_ty(cx: ext_ctxt) -> @ast::ty {
+    fn to_ty(cx: ext_ctxt) -> @ast::Ty {
         cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
           .add_tys(cx.ty_vars(self.get_params())))
     }
@@ -360,7 +360,7 @@ impl protocol: gen_init {
         }}
     }
 
-    fn buffer_ty_path(cx: ext_ctxt) -> @ast::ty {
+    fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
         let mut params: ~[ast::ty_param] = ~[];
         for (copy self.states).each |s| {
             for s.ty_params.each |tp| {
@@ -444,13 +444,13 @@ impl ~[@ast::item]: to_source {
     }
 }
 
-impl @ast::ty: to_source {
+impl @ast::Ty: to_source {
     fn to_source(cx: ext_ctxt) -> ~str {
         ty_to_str(self, cx.parse_sess().interner)
     }
 }
 
-impl ~[@ast::ty]: to_source {
+impl ~[@ast::Ty]: to_source {
     fn to_source(cx: ext_ctxt) -> ~str {
         str::connect(self.map(|i| i.to_source(cx)), ~", ")
     }
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 6d58d209fcf..229e55fdfcc 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -18,7 +18,7 @@ impl direction : cmp::Eq {
 }
 
 impl direction: ToStr {
-    fn to_str() -> ~str {
+    pure fn to_str() -> ~str {
         match self {
           send => ~"Send",
           recv => ~"Recv"
@@ -35,11 +35,11 @@ impl direction {
     }
 }
 
-type next_state = Option<{state: ~str, tys: ~[@ast::ty]}>;
+type next_state = Option<{state: ~str, tys: ~[@ast::Ty]}>;
 
 enum message {
     // name, span, data, current state, next state
-    message(~str, span, ~[@ast::ty], state, next_state)
+    message(~str, span, ~[@ast::Ty], state, next_state)
 }
 
 impl message {
@@ -78,7 +78,7 @@ enum state {
 
 impl state {
     fn add_message(name: ~str, span: span,
-                   +data: ~[@ast::ty], next: next_state) {
+                   +data: ~[@ast::Ty], next: next_state) {
         self.messages.push(message(name, span, data, self,
                                    next));
     }
@@ -92,7 +92,7 @@ impl state {
     }
 
     /// Returns the type that is used for the messages.
-    fn to_ty(cx: ext_ctxt) -> @ast::ty {
+    fn to_ty(cx: ext_ctxt) -> @ast::Ty {
         cx.ty_path_ast_builder
             (path(~[cx.ident_of(self.name)],self.span).add_tys(
                 cx.ty_vars(self.ty_params)))
@@ -200,7 +200,7 @@ impl protocol {
 trait visitor<Tproto, Tstate, Tmessage> {
     fn visit_proto(proto: protocol, st: &[Tstate]) -> Tproto;
     fn visit_state(state: state, m: &[Tmessage]) -> Tstate;
-    fn visit_message(name: ~str, spane: span, tys: &[@ast::ty],
+    fn visit_message(name: ~str, spane: span, tys: &[@ast::Ty],
                      this: state, next: next_state) -> Tmessage;
 }
 
diff --git a/src/libsyntax/ext/qquote.rs b/src/libsyntax/ext/qquote.rs
index 342743d8c46..af7ffaa73f5 100644
--- a/src/libsyntax/ext/qquote.rs
+++ b/src/libsyntax/ext/qquote.rs
@@ -1,7 +1,7 @@
 use ast::{crate, expr_, mac_invoc,
                      mac_aq, mac_var};
 use parse::parser;
-use parse::parser::parse_from_source_str;
+use parse::parser::{Parser, parse_from_source_str};
 use dvec::DVec;
 use parse::token::ident_interner;
 
@@ -24,7 +24,7 @@ struct gather_item {
 type aq_ctxt = @{lo: uint, gather: DVec<gather_item>};
 enum fragment {
     from_expr(@ast::expr),
-    from_ty(@ast::ty)
+    from_ty(@ast::Ty)
 }
 
 fn ids_ext(cx: ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
@@ -68,7 +68,7 @@ impl @ast::expr: qq_helper {
     }
     fn get_fold_fn() -> ~str {~"fold_expr"}
 }
-impl @ast::ty: qq_helper {
+impl @ast::Ty: qq_helper {
     fn span() -> span {self.span}
     fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
     fn extract_mac() -> Option<ast::mac_> {
@@ -186,13 +186,13 @@ fn expand_ast(ecx: ext_ctxt, _sp: span,
     };
 }
 
-fn parse_crate(p: parser) -> @ast::crate { p.parse_crate_mod(~[]) }
-fn parse_ty(p: parser) -> @ast::ty { p.parse_ty(false) }
-fn parse_stmt(p: parser) -> @ast::stmt { p.parse_stmt(~[]) }
-fn parse_expr(p: parser) -> @ast::expr { p.parse_expr() }
-fn parse_pat(p: parser) -> @ast::pat { p.parse_pat(true) }
+fn parse_crate(p: Parser) -> @ast::crate { p.parse_crate_mod(~[]) }
+fn parse_ty(p: Parser) -> @ast::Ty { p.parse_ty(false) }
+fn parse_stmt(p: Parser) -> @ast::stmt { p.parse_stmt(~[]) }
+fn parse_expr(p: Parser) -> @ast::expr { p.parse_expr() }
+fn parse_pat(p: Parser) -> @ast::pat { p.parse_pat(true) }
 
-fn parse_item(p: parser) -> @ast::item {
+fn parse_item(p: Parser) -> @ast::item {
     match p.parse_item(~[]) {
       Some(item) => item,
       None       => fail ~"parse_item: parsing an item failed"
@@ -200,7 +200,7 @@ fn parse_item(p: parser) -> @ast::item {
 }
 
 fn finish<T: qq_helper>
-    (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: parser) -> T)
+    (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: Parser) -> T)
     -> @ast::expr
 {
     let cm = ecx.codemap();
@@ -309,7 +309,7 @@ fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
     @f.fold_crate(*n)
 }
 fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
-fn fold_ty(f: ast_fold, &&n: @ast::ty) -> @ast::ty {f.fold_ty(n)}
+fn fold_ty(f: ast_fold, &&n: @ast::Ty) -> @ast::Ty {f.fold_ty(n)}
 fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {
     f.fold_item(n).get() //HACK: we know we don't drop items
 }
diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs
index e16e1c55349..bec29c9a835 100644
--- a/src/libsyntax/ext/simplext.rs
+++ b/src/libsyntax/ext/simplext.rs
@@ -6,7 +6,7 @@ use base::*;
 
 use fold::*;
 use ast_util::respan;
-use ast::{ident, path, ty, blk_, expr, expr_path,
+use ast::{ident, path, Ty, blk_, expr, expr_path,
              expr_vec, expr_mac, mac_invoc, node_id, expr_index};
 
 export add_new_extension;
@@ -29,7 +29,7 @@ enum matchable {
     match_expr(@expr),
     match_path(@path),
     match_ident(ast::spanned<ident>),
-    match_ty(@ty),
+    match_ty(@Ty),
     match_block(ast::blk),
     match_exact, /* don't bind anything, just verify the AST traversal */
 }
diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs
index c2d4de1b423..0c7d408db7c 100644
--- a/src/libsyntax/ext/trace_macros.rs
+++ b/src/libsyntax/ext/trace_macros.rs
@@ -2,7 +2,7 @@ use codemap::span;
 use ext::base::ext_ctxt;
 use ast::tt_delim;
 use parse::lexer::{new_tt_reader, reader};
-use parse::parser::{parser, SOURCE_FILE};
+use parse::parser::{Parser, SOURCE_FILE};
 use parse::common::parser_common;
 
 fn expand_trace_macros(cx: ext_ctxt, sp: span,
@@ -13,7 +13,7 @@ fn expand_trace_macros(cx: ext_ctxt, sp: span,
     let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
                                cx.parse_sess().interner, None, tt);
     let rdr = tt_rdr as reader;
-    let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
+    let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
 
     let arg = cx.str_of(rust_parser.parse_ident());
     match arg {
@@ -21,7 +21,7 @@ fn expand_trace_macros(cx: ext_ctxt, sp: span,
       ~"false" => cx.set_trace_macros(false),
       _ => cx.span_fatal(sp, ~"trace_macros! only accepts `true` or `false`")
     }
-    let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
+    let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
     let result = rust_parser.parse_expr();
     base::mr_expr(result)
 }
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 16e3454ca2c..17122b85fb3 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -1,9 +1,9 @@
 // Earley-like parser for macros.
 use parse::token;
-use parse::token::{token, EOF, to_str, nonterminal};
+use parse::token::{Token, EOF, to_str, nonterminal};
 use parse::lexer::*; //resolve bug?
 //import parse::lexer::{reader, tt_reader, tt_reader_as_reader};
-use parse::parser::{parser,SOURCE_FILE};
+use parse::parser::{Parser, SOURCE_FILE};
 //import parse::common::parser_common;
 use parse::common::*; //resolve bug?
 use parse::parse_sess;
@@ -97,7 +97,7 @@ fn is_some(&&mpu: matcher_pos_up) -> bool {
 
 type matcher_pos = ~{
     elts: ~[ast::matcher], // maybe should be /&? Need to understand regions.
-    sep: Option<token>,
+    sep: Option<Token>,
     mut idx: uint,
     mut up: matcher_pos_up, // mutable for swapping only
     matches: ~[DVec<@named_match>],
@@ -122,7 +122,7 @@ fn count_names(ms: &[matcher]) -> uint {
 }
 
 #[allow(non_implicitly_copyable_typarams)]
-fn initial_matcher_pos(ms: ~[matcher], sep: Option<token>, lo: uint)
+fn initial_matcher_pos(ms: ~[matcher], sep: Option<Token>, lo: uint)
     -> matcher_pos {
     let mut match_idx_hi = 0u;
     for ms.each() |elt| {
@@ -345,7 +345,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                      built-in NTs %s or %u other options.",
                     nts, next_eis.len()));
             } else if (bb_eis.len() == 0u && next_eis.len() == 0u) {
-                return failure(sp, ~"No rules expected the token "
+                return failure(sp, ~"No rules expected the token: "
                             + to_str(rdr.interner(), tok));
             } else if (next_eis.len() > 0u) {
                 /* Now process the next token */
@@ -354,7 +354,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                 }
                 rdr.next_token();
             } else /* bb_eis.len() == 1 */ {
-                let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
+                let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
 
                 let ei = bb_eis.pop();
                 match ei.elts[ei.idx].node {
@@ -381,7 +381,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
     }
 }
 
-fn parse_nt(p: parser, name: ~str) -> nonterminal {
+fn parse_nt(p: Parser, name: ~str) -> nonterminal {
     match name {
       ~"item" => match p.parse_item(~[]) {
         Some(i) => token::nt_item(i),
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 52369ad7207..31bc375a76d 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -4,7 +4,7 @@ use ast::{ident, matcher_, matcher, match_tok,
              match_nonterminal, match_seq, tt_delim};
 use parse::lexer::{new_tt_reader, reader};
 use parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt};
-use parse::parser::{parser, SOURCE_FILE};
+use parse::parser::{Parser, SOURCE_FILE};
 use macro_parser::{parse, parse_or_else, success, failure, named_match,
                       matched_seq, matched_nonterminal, error};
 use std::map::HashMap;
@@ -86,7 +86,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
                     // rhs has holes ( `$id` and `$(...)` that need filled)
                     let trncbr = new_tt_reader(s_d, itr, Some(named_matches),
                                                ~[rhs]);
-                    let p = parser(cx.parse_sess(), cx.cfg(),
+                    let p = Parser(cx.parse_sess(), cx.cfg(),
                                    trncbr as reader, SOURCE_FILE);
                     let e = p.parse_expr();
                     return mr_expr(e);
@@ -111,4 +111,4 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
         name: *cx.parse_sess().interner.get(name),
         ext: expr_tt({expander: exp, span: Some(sp)})
     });
-}
\ No newline at end of file
+}
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index a8a41cca6cb..238f9db6ac5 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -2,8 +2,7 @@ use diagnostic::span_handler;
 use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
 use macro_parser::{named_match, matched_seq, matched_nonterminal};
 use codemap::span;
-use parse::token::{EOF, INTERPOLATED, IDENT, token, nt_ident,
-                      ident_interner};
+use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
 use std::map::HashMap;
 
 export tt_reader,  new_tt_reader, dup_tt_reader, tt_next_token;
@@ -19,7 +18,7 @@ type tt_frame = @{
     readme: ~[ast::token_tree],
     mut idx: uint,
     dotdotdoted: bool,
-    sep: Option<token>,
+    sep: Option<Token>,
     up: tt_frame_up,
 };
 
@@ -32,7 +31,7 @@ type tt_reader = @{
     mut repeat_idx: ~[uint],
     mut repeat_len: ~[uint],
     /* cached: */
-    mut cur_tok: token,
+    mut cur_tok: Token,
     mut cur_span: span
 };
 
@@ -134,7 +133,7 @@ fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis {
 }
 
 
-fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
+fn tt_next_token(&&r: tt_reader) -> {tok: Token, sp: span} {
     let ret_val = { tok: r.cur_tok, sp: r.cur_span };
     while r.cur.idx >= r.cur.readme.len() {
         /* done with this set; pop or repeat? */