about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorSimon BD <simon@server>2012-10-03 21:47:09 -0500
committerSimon BD <simon@server>2012-10-03 21:47:09 -0500
commitefcd2385ea2389f270ff8ac8bc256636f647b130 (patch)
tree7e142ef709bc907a34ab1cb252eef6dcc0e83b91 /src/libsyntax/ext
parent44f8a4401ab37a45ba49db56611d77807bcbce35 (diff)
parent3ccf6f5932d8223fd6c5cbf7c6ac429ca9e8912a (diff)
downloadrust-efcd2385ea2389f270ff8ac8bc256636f647b130.tar.gz
rust-efcd2385ea2389f270ff8ac8bc256636f647b130.zip
Merge remote-tracking branch 'original/incoming' into incoming
Conflicts:
	src/libstd/json.rs
	src/libstd/sort.rs
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/auto_serialize.rs14
-rw-r--r--src/libsyntax/ext/auto_serialize2.rs1025
-rw-r--r--src/libsyntax/ext/base.rs36
-rw-r--r--src/libsyntax/ext/build.rs6
-rw-r--r--src/libsyntax/ext/expand.rs4
-rw-r--r--src/libsyntax/ext/fmt.rs11
-rw-r--r--src/libsyntax/ext/pipes/liveness.rs2
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs96
-rw-r--r--src/libsyntax/ext/pipes/proto.rs4
-rw-r--r--src/libsyntax/ext/simplext.rs17
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs30
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs21
12 files changed, 1150 insertions, 116 deletions
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index 4ebb8501041..64915c60742 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -90,8 +90,8 @@ 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 not_auto_serialize(a: &ast::attribute) -> bool {
+        attr::get_attr_name(*a) != ~"auto_serialize"
     }
 
     fn filter_attrs(item: @ast::item) -> @ast::item {
@@ -102,12 +102,12 @@ fn expand(cx: ext_ctxt,
     do vec::flat_map(in_items) |in_item| {
         match in_item.node {
           ast::item_ty(ty, tps) => {
-            vec::append(~[filter_attrs(in_item)],
+            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)],
+            vec::append(~[filter_attrs(*in_item)],
                         enum_fns(cx, in_item.ident,
                                  in_item.span, enum_definition.variants, tps))
           }
@@ -116,7 +116,7 @@ fn expand(cx: ext_ctxt,
             cx.span_err(span, ~"#[auto_serialize] can only be \
                                applied to type and enum \
                                definitions");
-            ~[in_item]
+            ~[*in_item]
           }
         }
     }
@@ -566,7 +566,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident,
                     tp_inputs);
 
     let tps_map = map::HashMap();
-    do vec::iter2(tps, tp_inputs) |tp, arg| {
+    for vec::each2(tps, tp_inputs) |tp, arg| {
         let arg_ident = arg.ident;
         tps_map.insert(
             tp.ident,
@@ -773,7 +773,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span,
                     tp_inputs);
 
     let tps_map = map::HashMap();
-    do vec::iter2(tps, tp_inputs) |tp, arg| {
+    for vec::each2(tps, tp_inputs) |tp, arg| {
         let arg_ident = arg.ident;
         tps_map.insert(
             tp.ident,
diff --git a/src/libsyntax/ext/auto_serialize2.rs b/src/libsyntax/ext/auto_serialize2.rs
new file mode 100644
index 00000000000..99f837a4c84
--- /dev/null
+++ b/src/libsyntax/ext/auto_serialize2.rs
@@ -0,0 +1,1025 @@
+/*
+
+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 a3ab35d77f0..9a31cc1d8f6 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -73,7 +73,7 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
     fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension {
         item_tt({expander: f, span: None})
     }
-    let syntax_expanders = HashMap::<~str,syntax_extension>();
+    let syntax_expanders = HashMap();
     syntax_expanders.insert(~"macro",
                             macro_defining(ext::simplext::add_new_extension));
     syntax_expanders.insert(~"macro_rules",
@@ -82,6 +82,12 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
     syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext));
     syntax_expanders.insert(~"auto_serialize",
                             item_decorator(ext::auto_serialize::expand));
+    syntax_expanders.insert(
+        ~"auto_serialize2",
+        item_decorator(ext::auto_serialize2::expand_auto_serialize));
+    syntax_expanders.insert(
+        ~"auto_deserialize2",
+        item_decorator(ext::auto_serialize2::expand_auto_deserialize));
     syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext));
     syntax_expanders.insert(~"concat_idents",
                             builtin(ext::concat_idents::expand_syntax_ext));
@@ -131,12 +137,12 @@ trait ext_ctxt {
     fn mod_path() -> ~[ast::ident];
     fn bt_push(ei: codemap::expn_info_);
     fn bt_pop();
-    fn span_fatal(sp: span, msg: ~str) -> !;
-    fn span_err(sp: span, msg: ~str);
-    fn span_warn(sp: span, msg: ~str);
-    fn span_unimpl(sp: span, msg: ~str) -> !;
-    fn span_bug(sp: span, msg: ~str) -> !;
-    fn bug(msg: ~str) -> !;
+    fn span_fatal(sp: span, msg: &str) -> !;
+    fn span_err(sp: span, msg: &str);
+    fn span_warn(sp: span, msg: &str);
+    fn span_unimpl(sp: span, msg: &str) -> !;
+    fn span_bug(sp: span, msg: &str) -> !;
+    fn bug(msg: &str) -> !;
     fn next_id() -> ast::node_id;
     pure fn trace_macros() -> bool;
     fn set_trace_macros(x: bool);
@@ -158,8 +164,8 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
         fn cfg() -> ast::crate_cfg { self.cfg }
         fn print_backtrace() { }
         fn backtrace() -> expn_info { self.backtrace }
-        fn mod_push(i: ast::ident) { vec::push(self.mod_path, i); }
-        fn mod_pop() { vec::pop(self.mod_path); }
+        fn mod_push(i: ast::ident) { self.mod_path.push(i); }
+        fn mod_pop() { self.mod_path.pop(); }
         fn mod_path() -> ~[ast::ident] { return self.mod_path; }
         fn bt_push(ei: codemap::expn_info_) {
             match ei {
@@ -180,27 +186,27 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
               _ => self.bug(~"tried to pop without a push")
             }
         }
-        fn span_fatal(sp: span, msg: ~str) -> ! {
+        fn span_fatal(sp: span, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_fatal(sp, msg);
         }
-        fn span_err(sp: span, msg: ~str) {
+        fn span_err(sp: span, msg: &str) {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_err(sp, msg);
         }
-        fn span_warn(sp: span, msg: ~str) {
+        fn span_warn(sp: span, msg: &str) {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_warn(sp, msg);
         }
-        fn span_unimpl(sp: span, msg: ~str) -> ! {
+        fn span_unimpl(sp: span, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
         }
-        fn span_bug(sp: span, msg: ~str) -> ! {
+        fn span_bug(sp: span, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_bug(sp, msg);
         }
-        fn bug(msg: ~str) -> ! {
+        fn bug(msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.handler().bug(msg);
         }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 8574c0c9082..a43b0cb69f4 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -50,6 +50,10 @@ fn mk_access(cx: ext_ctxt, sp: span, p: ~[ast::ident], m: ast::ident)
     let pathexpr = mk_path(cx, sp, p);
     return mk_access_(cx, sp, pathexpr, m);
 }
+fn mk_addr_of(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
+    return mk_expr(cx, sp, ast::expr_addr_of(ast::m_imm, e));
+}
+
 fn mk_call_(cx: ext_ctxt, sp: span, fn_expr: @ast::expr,
             args: ~[@ast::expr]) -> @ast::expr {
     mk_expr(cx, sp, ast::expr_call(fn_expr, args, false))
@@ -96,7 +100,7 @@ fn mk_rec_e(cx: ext_ctxt, sp: span,
         let val = field.ex;
         let astfield =
             {node: {mutbl: ast::m_imm, ident: ident, expr: val}, span: sp};
-        vec::push(astfields, astfield);
+        astfields.push(astfield);
     }
     let recexpr = ast::expr_rec(astfields, option::None::<@ast::expr>);
     mk_expr(cx, sp, recexpr)
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index dbe475c1b50..22e2cfcde6b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -144,7 +144,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
     // decorated with "item decorators", then use that function to transform
     // the item into a new set of items.
     let new_items = do vec::flat_map(module_.items) |item| {
-        do vec::foldr(item.attrs, ~[item]) |attr, items| {
+        do vec::foldr(item.attrs, ~[*item]) |attr, items| {
             let mname = match attr.node.value.node {
               ast::meta_word(n) => n,
               ast::meta_name_value(n, _) => n,
@@ -160,7 +160,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
         }
     };
 
-    return {items: new_items,.. module_};
+    return {items: new_items, ..module_};
 }
 
 
diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs
index 3ea0493239f..ea493eab561 100644
--- a/src/libsyntax/ext/fmt.rs
+++ b/src/libsyntax/ext/fmt.rs
@@ -20,10 +20,10 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
     let fmtspan = args[0].span;
     debug!("Format string:");
     log(debug, fmt);
-    fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: ~str) -> ! {
+    fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: &str) -> ! {
         cx.span_fatal(sp, msg);
     }
-    let parse_fmt_err = fn@(s: ~str) -> ! {
+    let parse_fmt_err = fn@(s: &str) -> ! {
         parse_fmt_err_(cx, fmtspan, s)
     };
     let pieces = parse_fmt_string(fmt, parse_fmt_err);
@@ -187,7 +187,8 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
           TyFloat => {
             return make_conv_call(cx, arg.span, ~"float", cnv, arg);
           }
-          TyPoly => return make_conv_call(cx, arg.span, ~"poly", cnv, arg)
+          TyPoly => return make_conv_call(cx, arg.span, ~"poly", cnv,
+                       mk_addr_of(cx, sp, arg))
         }
     }
     fn log_conv(c: Conv) {
@@ -245,7 +246,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
     for pieces.each |pc| {
         match *pc {
           PieceString(s) => {
-            vec::push(piece_exprs, mk_uniq_str(cx, fmt_sp, s))
+            piece_exprs.push(mk_uniq_str(cx, fmt_sp, s))
           }
           PieceConv(conv) => {
             n += 1u;
@@ -258,7 +259,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
             log_conv(conv);
             let arg_expr = args[n];
             let c_expr = make_new_conv(cx, fmt_sp, conv, arg_expr);
-            vec::push(piece_exprs, c_expr);
+            piece_exprs.push(c_expr);
           }
         }
     }
diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs
index 8b17ffc1104..a9bfd87ab0e 100644
--- a/src/libsyntax/ext/pipes/liveness.rs
+++ b/src/libsyntax/ext/pipes/liveness.rs
@@ -65,7 +65,7 @@ fn analyze(proto: protocol, _cx: ext_ctxt) {
     let mut self_live = ~[];
     for colive.eachi |i, bv| {
         if bv.get(i) {
-            vec::push(self_live, proto.get_state_by_id(i))
+            self_live.push(proto.get_state_by_id(i))
         }
     }
 
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 11250cfbf38..9c10d228a23 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -47,7 +47,7 @@ impl message: gen_send {
             let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
 
             let args_ast = (arg_names, tys).map(
-                |n, t| cx.arg_mode(n, t, ast::by_copy)
+                |n, t| cx.arg_mode(*n, *t, ast::by_copy)
             );
 
             let pipe_ty = cx.ty_path_ast_builder(
@@ -71,10 +71,10 @@ impl message: gen_send {
 
                 body += ~"let b = pipe.reuse_buffer();\n";
                 body += fmt!("let %s = pipes::SendPacketBuffered(\
-                              ptr::addr_of(b.buffer.data.%s));\n",
+                              ptr::addr_of(&(b.buffer.data.%s)));\n",
                              sp, next.name);
                 body += fmt!("let %s = pipes::RecvPacketBuffered(\
-                              ptr::addr_of(b.buffer.data.%s));\n",
+                              ptr::addr_of(&(b.buffer.data.%s)));\n",
                              rp, next.name);
             }
             else {
@@ -129,7 +129,7 @@ impl message: gen_send {
                 let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
 
                 let args_ast = (arg_names, tys).map(
-                    |n, t| cx.arg_mode(cx.ident_of(n), t, ast::by_copy)
+                    |n, t| cx.arg_mode(cx.ident_of(*n), *t, ast::by_copy)
                 );
 
                 let args_ast = vec::append(
@@ -226,7 +226,7 @@ impl state: to_type_decls {
 
             let v = cx.variant(cx.ident_of(name), span, tys);
 
-            vec::push(items_msg, v);
+            items_msg.push(v);
         }
 
         ~[cx.item_enum_poly(name,
@@ -245,44 +245,44 @@ impl state: to_type_decls {
         let mut items = ~[];
         for self.messages.each |m| {
             if dir == send {
-                vec::push(items, m.gen_send(cx, true));
-                vec::push(items, m.gen_send(cx, false));
+                items.push(m.gen_send(cx, true));
+                items.push(m.gen_send(cx, false));
             }
         }
 
         if !self.proto.is_bounded() {
-            vec::push(items,
-                      cx.item_ty_poly(
-                          self.data_name(),
-                          self.span,
-                          cx.ty_path_ast_builder(
-                              path(~[cx.ident_of(~"pipes"),
-                                     cx.ident_of(dir.to_str() + ~"Packet")],
-                                   empty_span())
-                              .add_ty(cx.ty_path_ast_builder(
-                                  path(~[cx.ident_of(self.proto.name),
-                                         self.data_name()],
-                                       empty_span())
-                                  .add_tys(cx.ty_vars(self.ty_params))))),
-                          self.ty_params));
+            items.push(
+                cx.item_ty_poly(
+                    self.data_name(),
+                    self.span,
+                    cx.ty_path_ast_builder(
+                        path(~[cx.ident_of(~"pipes"),
+                               cx.ident_of(dir.to_str() + ~"Packet")],
+                             empty_span())
+                        .add_ty(cx.ty_path_ast_builder(
+                            path(~[cx.ident_of(self.proto.name),
+                                   self.data_name()],
+                                 empty_span())
+                            .add_tys(cx.ty_vars(self.ty_params))))),
+                    self.ty_params));
         }
         else {
-            vec::push(items,
-                      cx.item_ty_poly(
-                          self.data_name(),
-                          self.span,
-                          cx.ty_path_ast_builder(
-                              path(~[cx.ident_of(~"pipes"),
-                                     cx.ident_of(dir.to_str()
-                                                 + ~"PacketBuffered")],
-                                  empty_span())
-                              .add_tys(~[cx.ty_path_ast_builder(
-                                  path(~[cx.ident_of(self.proto.name),
-                                         self.data_name()],
-                                       empty_span())
-                                  .add_tys(cx.ty_vars(self.ty_params))),
-                                         self.proto.buffer_ty_path(cx)])),
-                          self.ty_params));
+            items.push(
+                cx.item_ty_poly(
+                    self.data_name(),
+                    self.span,
+                    cx.ty_path_ast_builder(
+                        path(~[cx.ident_of(~"pipes"),
+                               cx.ident_of(dir.to_str()
+                                           + ~"PacketBuffered")],
+                             empty_span())
+                        .add_tys(~[cx.ty_path_ast_builder(
+                            path(~[cx.ident_of(self.proto.name),
+                                   self.data_name()],
+                                 empty_span())
+                            .add_tys(cx.ty_vars(self.ty_params))),
+                                   self.proto.buffer_ty_path(cx)])),
+                    self.ty_params));
         };
         items
     }
@@ -351,7 +351,7 @@ impl protocol: gen_init {
                         fmt!("data.%s.set_buffer_(buffer)",
                              s.name))),
                 ext_cx.parse_expr(
-                    fmt!("ptr::addr_of(data.%s)",
+                    fmt!("ptr::addr_of(&(data.%s))",
                          self.states[0].name))));
 
         #ast {{
@@ -367,7 +367,7 @@ impl protocol: gen_init {
         for (copy self.states).each |s| {
             for s.ty_params.each |tp| {
                 match params.find(|tpp| tp.ident == tpp.ident) {
-                  None => vec::push(params, *tp),
+                  None => params.push(*tp),
                   _ => ()
                 }
             }
@@ -383,7 +383,7 @@ impl protocol: gen_init {
         let fields = do (copy self.states).map_to_vec |s| {
             for s.ty_params.each |tp| {
                 match params.find(|tpp| tp.ident == tpp.ident) {
-                  None => vec::push(params, *tp),
+                  None => params.push(*tp),
                   _ => ()
                 }
             }
@@ -415,17 +415,15 @@ impl protocol: gen_init {
         }
 
         if self.is_bounded() {
-            vec::push(items, self.gen_buffer_type(cx))
+            items.push(self.gen_buffer_type(cx))
         }
 
-        vec::push(items,
-                  cx.item_mod(cx.ident_of(~"client"),
-                              self.span,
-                              client_states));
-        vec::push(items,
-                  cx.item_mod(cx.ident_of(~"server"),
-                              self.span,
-                              server_states));
+        items.push(cx.item_mod(cx.ident_of(~"client"),
+                               self.span,
+                               client_states));
+        items.push(cx.item_mod(cx.ident_of(~"server"),
+                               self.span,
+                               server_states));
 
         cx.item_mod(cx.ident_of(self.name), self.span, items)
     }
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 70b38e83ad5..6d58d209fcf 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -210,10 +210,10 @@ fn visit<Tproto, Tstate, Tmessage, V: visitor<Tproto, Tstate, Tmessage>>(
     // the copy keywords prevent recursive use of dvec
     let states = do (copy proto.states).map_to_vec |s| {
         let messages = do (copy s.messages).map_to_vec |m| {
-            let message(name, span, tys, this, next) = *m;
+            let message(name, span, tys, this, next) = m;
             visitor.visit_message(name, span, tys, this, next)
         };
-        visitor.visit_state(*s, messages)
+        visitor.visit_state(s, messages)
     };
     visitor.visit_proto(proto, states)
 }
diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs
index 3af9cfe852d..e16e1c55349 100644
--- a/src/libsyntax/ext/simplext.rs
+++ b/src/libsyntax/ext/simplext.rs
@@ -94,7 +94,7 @@ fn option_flatten_map<T: Copy, U: Copy>(f: fn@(T) -> Option<U>, v: ~[T]) ->
     for v.each |elem| {
         match f(*elem) {
           None => return None,
-          Some(fv) => vec::push(res, fv)
+          Some(fv) => res.push(fv)
         }
     }
     return Some(res);
@@ -237,7 +237,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: Option<arb_depth<matchable>>,
 
 /* helper for transcribe_exprs: what vars from `b` occur in `e`? */
 fn free_vars(b: bindings, e: @expr, it: fn(ident)) {
-    let idents: HashMap<ident, ()> = HashMap();
+    let idents = HashMap();
     fn mark_ident(&&i: ident, _fld: ast_fold, b: bindings,
                   idents: HashMap<ident, ()>) -> ident {
         if b.contains_key(i) { idents.insert(i, ()); }
@@ -305,9 +305,9 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint],
                 /* Whew, we now know how how many times to repeat */
                 let mut idx: uint = 0u;
                 while idx < rc {
-                    vec::push(*idx_path, idx);
-                    vec::push(res, recur(repeat_me)); // whew!
-                    vec::pop(*idx_path);
+                    idx_path.push(idx);
+                    res.push(recur(repeat_me)); // whew!
+                    idx_path.pop();
                     idx += 1u;
                 }
               }
@@ -567,7 +567,7 @@ fn p_t_s_r_ellipses(cx: ext_ctxt, repeat_me: @expr, offset: uint, s: selector,
                     let mut elts = ~[];
                     let mut idx = offset;
                     while idx < vec::len(arg_elts) {
-                        vec::push(elts, leaf(match_expr(arg_elts[idx])));
+                        elts.push(leaf(match_expr(arg_elts[idx])));
                         idx += 1u;
                     }
 
@@ -672,9 +672,8 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
                       None => cx.span_fatal(mac.span,
                                            ~"macro must have arguments")
                     };
-                    vec::push(clauses,
-                              @{params: pattern_to_selectors(cx, arg),
-                                body: elts[1u]});
+                    clauses.push(@{params: pattern_to_selectors(cx, arg),
+                                   body: elts[1u]});
 
                     // FIXME (#2251): check duplicates (or just simplify
                     // the macro arg situation)
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 74c36dcf1b7..16e3454ca2c 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -185,7 +185,7 @@ fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match])
           }
         }
     }
-    let ret_val = HashMap::<uint,@named_match>();
+    let ret_val = HashMap();
     for ms.each() |m| { n_rec(p_s, *m, res, ret_val) }
     return ret_val;
 }
@@ -208,7 +208,7 @@ fn parse_or_else(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader,
 fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
     -> parse_result {
     let mut cur_eis = ~[];
-    vec::push(cur_eis, initial_matcher_pos(ms, None, rdr.peek().sp.lo));
+    cur_eis.push(initial_matcher_pos(ms, None, rdr.peek().sp.lo));
 
     loop {
         let mut bb_eis = ~[]; // black-box parsed by parser.rs
@@ -219,7 +219,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
 
         /* we append new items to this while we go */
         while cur_eis.len() > 0u { /* for each Earley Item */
-            let mut ei = vec::pop(cur_eis);
+            let mut ei = cur_eis.pop();
 
             let idx = ei.idx;
             let len = ei.elts.len();
@@ -256,7 +256,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                         }
 
                         new_pos.idx += 1;
-                        vec::push(cur_eis, move new_pos);
+                        cur_eis.push(move new_pos);
                     }
 
                     // can we go around again?
@@ -267,17 +267,17 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                         if tok == t { //pass the separator
                             let ei_t <- ei;
                             ei_t.idx += 1;
-                            vec::push(next_eis, move ei_t);
+                            next_eis.push(move ei_t);
                         }
                       }
                       _ => { // we don't need a separator
                         let ei_t <- ei;
                         ei_t.idx = 0;
-                        vec::push(cur_eis, move ei_t);
+                        cur_eis.push(move ei_t);
                       }
                     }
                 } else {
-                    vec::push(eof_eis, move ei);
+                    eof_eis.push(move ei);
                 }
             } else {
                 match copy ei.elts[idx].node {
@@ -292,13 +292,13 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                             new_ei.matches[idx].push(@matched_seq(~[], sp));
                         }
 
-                        vec::push(cur_eis, move new_ei);
+                        cur_eis.push(move new_ei);
                     }
 
                     let matches = vec::map(ei.matches, // fresh, same size:
                                            |_m| DVec::<@named_match>());
                     let ei_t <- ei;
-                    vec::push(cur_eis, ~{
+                    cur_eis.push(~{
                         elts: matchers, sep: sep, mut idx: 0u,
                         mut up: matcher_pos_up(Some(move ei_t)),
                         matches: move matches,
@@ -306,12 +306,12 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                         sp_lo: sp.lo
                     });
                   }
-                  match_nonterminal(_,_,_) => { vec::push(bb_eis, move ei) }
+                  match_nonterminal(_,_,_) => { bb_eis.push(move ei) }
                   match_tok(t) => {
                     let ei_t <- ei;
                     if t == tok {
                         ei_t.idx += 1;
-                        vec::push(next_eis, move ei_t);
+                        next_eis.push(move ei_t);
                     }
                   }
                 }
@@ -323,7 +323,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
             if eof_eis.len() == 1u {
                 return success(
                     nameize(sess, ms,
-                            vec::map(eof_eis[0u].matches, |dv| dv.pop())));
+                            eof_eis[0u].matches.map(|dv| dv.pop())));
             } else if eof_eis.len() > 1u {
                 return error(sp, ~"Ambiguity: multiple successful parses");
             } else {
@@ -350,13 +350,13 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
             } else if (next_eis.len() > 0u) {
                 /* Now process the next token */
                 while(next_eis.len() > 0u) {
-                    vec::push(cur_eis, vec::pop(next_eis));
+                    cur_eis.push(next_eis.pop());
                 }
                 rdr.next_token();
             } else /* bb_eis.len() == 1 */ {
                 let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
 
-                let ei = vec::pop(bb_eis);
+                let ei = bb_eis.pop();
                 match ei.elts[ei.idx].node {
                   match_nonterminal(_, name, idx) => {
                     ei.matches[idx].push(@matched_nonterminal(
@@ -365,7 +365,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                   }
                   _ => fail
                 }
-                vec::push(cur_eis, move ei);
+                cur_eis.push(move ei);
 
                 /* this would fail if zero-length tokens existed */
                 while rdr.peek().sp.lo < rust_parser.span.lo {
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 7fb910cd4b6..a8a41cca6cb 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -25,7 +25,7 @@ type tt_frame = @{
 
 type tt_reader = @{
     sp_diag: span_handler,
-    interner: ident_interner,
+    interner: @ident_interner,
     mut cur: tt_frame,
     /* for MBE-style macro transcription */
     interpolations: std::map::HashMap<ident, @named_match>,
@@ -39,7 +39,7 @@ type tt_reader = @{
 /** This can do Macro-By-Example transcription. On the other hand, if
  *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
  *  should) be none. */
-fn new_tt_reader(sp_diag: span_handler, itr: ident_interner,
+fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner,
                  interp: Option<std::map::HashMap<ident,@named_match>>,
                  src: ~[ast::token_tree])
     -> tt_reader {
@@ -47,7 +47,7 @@ fn new_tt_reader(sp_diag: span_handler, itr: ident_interner,
               mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false,
                          sep: None, up: tt_frame_up(option::None)},
               interpolations: match interp { /* just a convienience */
-                None => std::map::HashMap::<uint,@named_match>(),
+                None => std::map::HashMap(),
                 Some(x) => x
               },
               mut repeat_idx: ~[],
@@ -82,13 +82,13 @@ pure fn dup_tt_reader(&&r: tt_reader) -> tt_reader {
 
 pure fn lookup_cur_matched_by_matched(r: tt_reader,
                                       start: @named_match) -> @named_match {
-    pure fn red(&&ad: @named_match, &&idx: uint) -> @named_match {
+    pure fn red(+ad: @named_match, idx: &uint) -> @named_match {
         match *ad {
           matched_nonterminal(_) => {
             // end of the line; duplicate henceforth
             ad
           }
-          matched_seq(ads, _) => ads[idx]
+          matched_seq(ads, _) => ads[*idx]
         }
     }
     vec::foldl(start, r.repeat_idx, red)
@@ -122,8 +122,8 @@ fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis {
     }
     match t {
       tt_delim(tts) | tt_seq(_, tts, _, _) => {
-        vec::foldl(lis_unconstrained, tts, {|lis, tt|
-            lis_merge(lis, lockstep_iter_size(tt, r), r) })
+        vec::foldl(lis_unconstrained, tts, |lis, tt|
+            lis_merge(lis, lockstep_iter_size(*tt, r), r))
       }
       tt_tok(*) => lis_unconstrained,
       tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) {
@@ -148,7 +148,8 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
               }
               tt_frame_up(Some(tt_f)) => {
                 if r.cur.dotdotdoted {
-                    vec::pop(r.repeat_idx); vec::pop(r.repeat_len);
+                    r.repeat_idx.pop();
+                    r.repeat_len.pop();
                 }
 
                 r.cur = tt_f;
@@ -205,8 +206,8 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
                     r.cur.idx += 1u;
                     return tt_next_token(r);
                 } else {
-                    vec::push(r.repeat_len, len);
-                    vec::push(r.repeat_idx, 0u);
+                    r.repeat_len.push(len);
+                    r.repeat_idx.push(0u);
                     r.cur = @{readme: tts, mut idx: 0u, dotdotdoted: true,
                               sep: sep, up: tt_frame_up(option::Some(r.cur))};
                 }