about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-05-01 17:54:54 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-05-02 17:00:51 -0700
commitdc5df61bc1914224d50d92cdd5599b6337ac68f2 (patch)
tree1365352083cfe8b3d8864b3c3620ae4e7e51d3c9 /src/libsyntax
parent6f2e429041da1990a91477e37316c73729cb6fe2 (diff)
downloadrust-dc5df61bc1914224d50d92cdd5599b6337ac68f2.tar.gz
rust-dc5df61bc1914224d50d92cdd5599b6337ac68f2.zip
librustc: Update the serializer to work properly with INHTWAMA, removing mutable fields in the process
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs38
-rw-r--r--src/libsyntax/codemap.rs17
-rw-r--r--src/libsyntax/ext/auto_encode.rs304
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs49
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs42
-rw-r--r--src/libsyntax/parse/mod.rs3
6 files changed, 332 insertions, 121 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a295952439f..77e79866160 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -70,21 +70,53 @@ pub type Name = uint;
 // with a macro expansion
 pub type Mrk = uint;
 
+#[cfg(stage0)]
 impl<S:Encoder> Encodable<S> for ident {
     fn encode(&self, s: &S) {
+        unsafe {
+            let intr =
+                match task::local_data::local_data_get(interner_key!()) {
+                    None => fail!(~"encode: TLS interner not set up"),
+                    Some(intr) => intr
+                };
+
+            s.emit_str(*(*intr).get(*self));
+        }
+    }
+}
+
+#[cfg(not(stage0))]
+impl<S:Encoder> Encodable<S> for ident {
+    fn encode(&self, s: &mut S) {
+        unsafe {
+            let intr =
+                match task::local_data::local_data_get(interner_key!()) {
+                    None => fail!(~"encode: TLS interner not set up"),
+                    Some(intr) => intr
+                };
+
+            s.emit_str(*(*intr).get(*self));
+        }
+    }
+}
+
+#[cfg(stage0)]
+impl<D:Decoder> Decodable<D> for ident {
+    fn decode(d: &D) -> ident {
         let intr = match unsafe {
             task::local_data::local_data_get(interner_key!())
         } {
-            None => fail!(~"encode: TLS interner not set up"),
+            None => fail!(~"decode: TLS interner not set up"),
             Some(intr) => intr
         };
 
-        s.emit_str(*(*intr).get(*self));
+        (*intr).intern(@d.read_str())
     }
 }
 
+#[cfg(not(stage0))]
 impl<D:Decoder> Decodable<D> for ident {
-    fn decode(d: &D) -> ident {
+    fn decode(d: &mut D) -> ident {
         let intr = match unsafe {
             task::local_data::local_data_get(interner_key!())
         } {
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 5f4967351e1..bbb390e9dc9 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -125,17 +125,34 @@ impl cmp::Eq for span {
     fn ne(&self, other: &span) -> bool { !(*self).eq(other) }
 }
 
+#[cfg(stage0)]
 impl<S:Encoder> Encodable<S> for span {
     /* Note #1972 -- spans are encoded but not decoded */
     fn encode(&self, _s: &S) { _s.emit_nil() }
 }
 
+#[cfg(not(stage0))]
+impl<S:Encoder> Encodable<S> for span {
+    /* Note #1972 -- spans are encoded but not decoded */
+    fn encode(&self, s: &mut S) {
+        s.emit_nil()
+    }
+}
+
+#[cfg(stage0)]
 impl<D:Decoder> Decodable<D> for span {
     fn decode(_d: &D) -> span {
         dummy_sp()
     }
 }
 
+#[cfg(not(stage0))]
+impl<D:Decoder> Decodable<D> for span {
+    fn decode(_d: &mut D) -> span {
+        dummy_sp()
+    }
+}
+
 pub fn spanned<T>(lo: BytePos, hi: BytePos, t: T) -> spanned<T> {
     respan(mk_sp(lo, hi), t)
 }
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 2ceb6f0c4bb..bdf0a2a1dd0 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -238,7 +238,8 @@ trait ExtCtxtMethods {
     fn stmt(&self, expr: @ast::expr) -> @ast::stmt;
     fn lit_str(&self, span: span, s: @~str) -> @ast::expr;
     fn lit_uint(&self, span: span, i: uint) -> @ast::expr;
-    fn lambda(&self, blk: ast::blk) -> @ast::expr;
+    fn lambda0(&self, blk: ast::blk) -> @ast::expr;
+    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr;
     fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk;
     fn expr_blk(&self, expr: @ast::expr) -> ast::blk;
     fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
@@ -254,8 +255,15 @@ trait ExtCtxtMethods {
                         ident: ast::ident,
                         args: ~[@ast::expr])
                         -> @ast::expr;
-    fn lambda_expr(&self, expr: @ast::expr) -> @ast::expr;
-    fn lambda_stmts(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr;
+    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr;
+    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
+                    -> @ast::expr;
+    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr;
+    fn lambda_stmts_1(&self,
+                      span: span,
+                      stmts: ~[@ast::stmt],
+                      ident: ast::ident)
+                      -> @ast::expr;
 }
 
 impl ExtCtxtMethods for @ext_ctxt {
@@ -388,12 +396,18 @@ impl ExtCtxtMethods for @ext_ctxt {
                                 span: span}))
     }
 
-    fn lambda(&self, blk: ast::blk) -> @ast::expr {
+    fn lambda0(&self, blk: ast::blk) -> @ast::expr {
         let ext_cx = *self;
         let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
         quote_expr!( || $blk_e )
     }
 
+    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr {
+        let ext_cx = *self;
+        let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
+        quote_expr!( |$ident| $blk_e )
+    }
+
     fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk {
         codemap::spanned {
             node: ast::blk_ {
@@ -461,15 +475,29 @@ impl ExtCtxtMethods for @ext_ctxt {
         ident: ast::ident,
         args: ~[@ast::expr]
     ) -> @ast::expr {
-        self.expr(span, ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar))
+        self.expr(span,
+                  ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar))
+    }
+
+    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr {
+        self.lambda0(self.expr_blk(expr))
+    }
+
+    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
+                    -> @ast::expr {
+        self.lambda1(self.expr_blk(expr), ident)
     }
 
-    fn lambda_expr(&self, expr: @ast::expr) -> @ast::expr {
-        self.lambda(self.expr_blk(expr))
+    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
+        self.lambda0(self.blk(span, stmts))
     }
 
-    fn lambda_stmts(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
-        self.lambda(self.blk(span, stmts))
+    fn lambda_stmts_1(&self,
+                      span: span,
+                      stmts: ~[@ast::stmt],
+                      ident: ast::ident)
+                      -> @ast::expr {
+        self.lambda1(self.blk(span, stmts), ident)
     }
 }
 
@@ -644,7 +672,7 @@ fn mk_ser_method(
             None,
             ast::mt {
                 ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]),
-                mutbl: ast::m_imm
+                mutbl: ast::m_mutbl
             }
         ),
         span: span,
@@ -706,7 +734,7 @@ fn mk_deser_method(
             None,
             ast::mt {
                 ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]),
-                mutbl: ast::m_imm
+                mutbl: ast::m_mutbl
             }
         ),
         span: span,
@@ -758,8 +786,8 @@ fn mk_struct_ser_impl(
     generics: &ast::Generics
 ) -> @ast::item {
     let fields = do mk_struct_fields(fields).mapi |idx, field| {
-        // ast for `|| self.$(name).encode(__s)`
-        let expr_lambda = cx.lambda_expr(
+        // ast for `|__s| self.$(name).encode(__s)`
+        let expr_lambda = cx.lambda_expr_1(
             cx.expr_method_call(
                 span,
                 cx.expr_field(
@@ -769,7 +797,8 @@ fn mk_struct_ser_impl(
                 ),
                 cx.ident_of(~"encode"),
                 ~[cx.expr_var(span, ~"__s")]
-            )
+            ),
+            cx.ident_of(~"__s")
         );
 
         // ast for `__s.emit_struct_field($(name), $(idx), $(expr_lambda))`
@@ -787,7 +816,7 @@ fn mk_struct_ser_impl(
         )
     };
 
-    // ast for `__s.emit_struct($(name), || $(fields))`
+    // ast for `__s.emit_struct($(name), |__s| $(fields))`
     let ser_body = cx.expr_method_call(
         span,
         cx.expr_var(span, ~"__s"),
@@ -795,7 +824,7 @@ fn mk_struct_ser_impl(
         ~[
             cx.lit_str(span, @cx.str_of(ident)),
             cx.lit_uint(span, vec::len(fields)),
-            cx.lambda_stmts(span, fields),
+            cx.lambda_stmts_1(span, fields, cx.ident_of(~"__s")),
         ]
     );
 
@@ -810,8 +839,8 @@ fn mk_struct_deser_impl(
     generics: &ast::Generics
 ) -> @ast::item {
     let fields = do mk_struct_fields(fields).mapi |idx, field| {
-        // ast for `|| std::serialize::decode(__d)`
-        let expr_lambda = cx.lambda(
+        // ast for `|__d| std::serialize::decode(__d)`
+        let expr_lambda = cx.lambda1(
             cx.expr_blk(
                 cx.expr_call(
                     span,
@@ -823,7 +852,8 @@ fn mk_struct_deser_impl(
                     ]),
                     ~[cx.expr_var(span, ~"__d")]
                 )
-            )
+            ),
+            cx.ident_of(~"__d")
         );
 
         // ast for `__d.read_struct_field($(name), $(idx), $(expr_lambda))`
@@ -848,7 +878,7 @@ fn mk_struct_deser_impl(
         }
     };
 
-    // ast for `read_struct($(name), || $(fields))`
+    // ast for `read_struct($(name), |__d| $(fields))`
     let body = cx.expr_method_call(
         span,
         cx.expr_var(span, ~"__d"),
@@ -856,7 +886,7 @@ fn mk_struct_deser_impl(
         ~[
             cx.lit_str(span, @cx.str_of(ident)),
             cx.lit_uint(span, vec::len(fields)),
-            cx.lambda_expr(
+            cx.lambda_expr_1(
                 cx.expr(
                     span,
                     ast::expr_struct(
@@ -864,7 +894,8 @@ fn mk_struct_deser_impl(
                         fields,
                         None
                     )
-                )
+                ),
+                cx.ident_of(~"__d")
             ),
         ]
     );
@@ -974,14 +1005,15 @@ fn ser_variant(
             cx.ident_of(~"emit_enum_variant_arg")
         );
 
-        // ast for `|| $(v).encode(__s)`
-        let expr_encode = cx.lambda_expr(
-             cx.expr_method_call(
+        // ast for `|__s| $(v).encode(__s)`
+        let expr_encode = cx.lambda_expr_1(
+            cx.expr_method_call(
                 span,
                  cx.expr_path(span, ~[names[a_idx]]),
                  cx.ident_of(~"encode"),
                 ~[cx.expr_var(span, ~"__s")]
-            )
+            ),
+            cx.ident_of(~"__s")
         );
 
         // ast for `$(expr_emit)($(a_idx), $(expr_encode))`
@@ -1003,7 +1035,7 @@ fn ser_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),
+            cx.lambda_stmts_1(span, stmts, cx.ident_of(~"__s")),
         ]
     );
 
@@ -1050,7 +1082,7 @@ fn mk_enum_ser_body(
         cx.ident_of(~"emit_enum"),
         ~[
             cx.lit_str(span, @cx.str_of(name)),
-            cx.lambda_expr(match_expr),
+            cx.lambda_expr_1(match_expr, cx.ident_of(~"__s")),
         ]
     )
 }
@@ -1062,8 +1094,8 @@ fn mk_enum_deser_variant_nary(
     args: ~[ast::variant_arg]
 ) -> @ast::expr {
     let args = do args.mapi |idx, _arg| {
-        // ast for `|| std::serialize::decode(__d)`
-        let expr_lambda = cx.lambda_expr(
+        // ast for `|__s| std::serialize::decode(__d)`
+        let expr_lambda = cx.lambda_expr_1(
             cx.expr_call(
                 span,
                 cx.expr_path_global(span, ~[
@@ -1073,7 +1105,8 @@ fn mk_enum_deser_variant_nary(
                     cx.ident_of(~"decode"),
                 ]),
                 ~[cx.expr_var(span, ~"__d")]
-            )
+            ),
+            cx.ident_of(~"__d")
         );
 
         // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))`
@@ -1163,24 +1196,44 @@ fn mk_enum_deser_body(
         span,
         ast::expr_fn_block(
             ast::fn_decl {
-                inputs: ~[ast::arg {
-                    is_mutbl: false,
-                    ty: @ast::Ty {
+                inputs: ~[
+                    ast::arg {
+                        is_mutbl: false,
+                        ty: @ast::Ty {
+                            id: ext_cx.next_id(),
+                            node: ast::ty_infer,
+                            span: span
+                        },
+                        pat: @ast::pat {
+                            id: ext_cx.next_id(),
+                            node: ast::pat_ident(
+                                ast::bind_by_copy,
+                                ast_util::ident_to_path(span,
+                                    ext_cx.ident_of(~"__d")),
+                                None),
+                            span: span,
+                        },
                         id: ext_cx.next_id(),
-                        node: ast::ty_infer,
-                        span: span
                     },
-                    pat: @ast::pat {
+                    ast::arg {
+                        is_mutbl: false,
+                        ty: @ast::Ty {
+                            id: ext_cx.next_id(),
+                            node: ast::ty_infer,
+                            span: span
+                        },
+                        pat: @ast::pat {
+                            id: ext_cx.next_id(),
+                            node: ast::pat_ident(
+                                ast::bind_by_copy,
+                                ast_util::ident_to_path(span,
+                                    ext_cx.ident_of(~"i")),
+                                None),
+                            span: span,
+                        },
                         id: ext_cx.next_id(),
-                        node: ast::pat_ident(
-                            ast::bind_by_copy,
-                            ast_util::ident_to_path(span,
-                                ext_cx.ident_of(~"i")),
-                            None),
-                        span: span,
-                    },
-                    id: ext_cx.next_id(),
-                }],
+                    }
+                ],
                 output: @ast::Ty {
                     id: ext_cx.next_id(),
                     node: ast::ty_infer,
@@ -1198,13 +1251,14 @@ fn mk_enum_deser_body(
     );
 
     // ast for `__d.read_enum_variant($expr_arm_names, $(expr_lambda))`
-    let expr_lambda = ext_cx.lambda_expr(
+    let expr_lambda = ext_cx.lambda_expr_1(
         ext_cx.expr_method_call(
             span,
             ext_cx.expr_var(span, ~"__d"),
             ext_cx.ident_of(~"read_enum_variant"),
             ~[expr_arm_names, expr_lambda]
-        )
+        ),
+        ext_cx.ident_of(~"__d")
     );
 
     // ast for `__d.read_enum($(e_name), $(expr_lambda))`
@@ -1256,105 +1310,147 @@ mod test {
     }
 
     impl Encoder for TestEncoder {
-        fn emit_nil(&self) { self.add_to_log(CallToEmitNil) }
+        fn emit_nil(&mut self) { self.add_to_log(CallToEmitNil) }
 
-        fn emit_uint(&self, v: uint) {self.add_to_log(CallToEmitUint(v)); }
-        fn emit_u64(&self, _v: u64) { self.add_unknown_to_log(); }
-        fn emit_u32(&self, _v: u32) { self.add_unknown_to_log(); }
-        fn emit_u16(&self, _v: u16) { self.add_unknown_to_log(); }
-        fn emit_u8(&self, _v: u8)   { self.add_unknown_to_log(); }
+        fn emit_uint(&mut self, v: uint) {
+            self.add_to_log(CallToEmitUint(v));
+        }
+        fn emit_u64(&mut self, _v: u64) { self.add_unknown_to_log(); }
+        fn emit_u32(&mut self, _v: u32) { self.add_unknown_to_log(); }
+        fn emit_u16(&mut self, _v: u16) { self.add_unknown_to_log(); }
+        fn emit_u8(&mut self, _v: u8)   { self.add_unknown_to_log(); }
 
-        fn emit_int(&self, _v: int) { self.add_unknown_to_log(); }
-        fn emit_i64(&self, _v: i64) { self.add_unknown_to_log(); }
-        fn emit_i32(&self, _v: i32) { self.add_unknown_to_log(); }
-        fn emit_i16(&self, _v: i16) { self.add_unknown_to_log(); }
-        fn emit_i8(&self, _v: i8)   { self.add_unknown_to_log(); }
+        fn emit_int(&mut self, _v: int) { self.add_unknown_to_log(); }
+        fn emit_i64(&mut self, _v: i64) { self.add_unknown_to_log(); }
+        fn emit_i32(&mut self, _v: i32) { self.add_unknown_to_log(); }
+        fn emit_i16(&mut self, _v: i16) { self.add_unknown_to_log(); }
+        fn emit_i8(&mut self, _v: i8)   { self.add_unknown_to_log(); }
 
-        fn emit_bool(&self, _v: bool) { self.add_unknown_to_log(); }
+        fn emit_bool(&mut self, _v: bool) { self.add_unknown_to_log(); }
 
-        fn emit_f64(&self, _v: f64) { self.add_unknown_to_log(); }
-        fn emit_f32(&self, _v: f32) { self.add_unknown_to_log(); }
-        fn emit_float(&self, _v: float) { self.add_unknown_to_log(); }
+        fn emit_f64(&mut self, _v: f64) { self.add_unknown_to_log(); }
+        fn emit_f32(&mut self, _v: f32) { self.add_unknown_to_log(); }
+        fn emit_float(&mut self, _v: float) { self.add_unknown_to_log(); }
 
-        fn emit_char(&self, _v: char) { self.add_unknown_to_log(); }
-        fn emit_str(&self, _v: &str) { self.add_unknown_to_log(); }
+        fn emit_char(&mut self, _v: char) { self.add_unknown_to_log(); }
+        fn emit_str(&mut self, _v: &str) { self.add_unknown_to_log(); }
 
-        fn emit_enum(&self, name: &str, f: &fn()) {
-            self.add_to_log(CallToEmitEnum(name.to_str())); f(); }
+        fn emit_enum(&mut self, name: &str, f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitEnum(name.to_str()));
+            f(self);
+        }
 
-        fn emit_enum_variant(&self, name: &str, id: uint,
-                             cnt: uint, f: &fn()) {
-            self.add_to_log(CallToEmitEnumVariant (name.to_str(),id,cnt));
-            f();
+        fn emit_enum_variant(&mut self,
+                             name: &str,
+                             id: uint,
+                             cnt: uint,
+                             f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitEnumVariant(name.to_str(), id, cnt));
+            f(self);
         }
 
-        fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) {
-            self.add_to_log(CallToEmitEnumVariantArg (idx)); f();
+        fn emit_enum_variant_arg(&mut self,
+                                 idx: uint,
+                                 f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitEnumVariantArg(idx));
+            f(self);
         }
 
-        fn emit_enum_struct_variant(&self, name: &str, id: uint, cnt: uint, f: &fn()) {
+        fn emit_enum_struct_variant(&mut self,
+                                    name: &str,
+                                    id: uint,
+                                    cnt: uint,
+                                    f: &fn(&mut TestEncoder)) {
             self.emit_enum_variant(name, id, cnt, f)
         }
 
-        fn emit_enum_struct_variant_field(&self, _name: &str, idx: uint, f: &fn()) {
+        fn emit_enum_struct_variant_field(&mut self,
+                                          _name: &str,
+                                          idx: uint,
+                                          f: &fn(&mut TestEncoder)) {
             self.emit_enum_variant_arg(idx, f)
         }
 
-        fn emit_struct(&self, name: &str, len: uint, f: &fn()) {
-            self.add_to_log(CallToEmitStruct (name.to_str(),len)); f();
+        fn emit_struct(&mut self,
+                       name: &str,
+                       len: uint,
+                       f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitStruct (name.to_str(),len));
+            f(self);
         }
-        fn emit_struct_field(&self, name: &str, idx: uint, f: &fn()) {
-            self.add_to_log(CallToEmitField (name.to_str(),idx)); f();
+        fn emit_struct_field(&mut self,
+                             name: &str,
+                             idx: uint,
+                             f: &fn(&mut TestEncoder)) {
+            self.add_to_log(CallToEmitField (name.to_str(),idx));
+            f(self);
         }
 
-        fn emit_tuple(&self, _len: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_tuple(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
-        fn emit_tuple_arg(&self, _idx: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_tuple_arg(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
 
-        fn emit_tuple_struct(&self, _name: &str, _len: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_tuple_struct(&mut self,
+                             _name: &str,
+                             _len: uint,
+                             f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
-        fn emit_tuple_struct_arg(&self, _idx: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+
+        fn emit_tuple_struct_arg(&mut self,
+                                 _idx: uint,
+                                 f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
 
-        fn emit_option(&self, f: &fn()) {
+        fn emit_option(&mut self, f: &fn(&mut TestEncoder)) {
             self.add_to_log(CallToEmitOption);
-            f();
+            f(self);
         }
-        fn emit_option_none(&self) {
+        fn emit_option_none(&mut self) {
             self.add_to_log(CallToEmitOptionNone);
         }
-        fn emit_option_some(&self, f: &fn()) {
+        fn emit_option_some(&mut self, f: &fn(&mut TestEncoder)) {
             self.add_to_log(CallToEmitOptionSome);
-            f();
+            f(self);
         }
 
-        fn emit_seq(&self, _len: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_seq(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
-        fn emit_seq_elt(&self, _idx: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_seq_elt(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
 
-        fn emit_map(&self, _len: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_map(&mut self, _len: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
-        fn emit_map_elt_key(&self, _idx: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
-        fn emit_map_elt_val(&self, _idx: uint, f: &fn()) {
-            self.add_unknown_to_log(); f();
+        fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut TestEncoder)) {
+            self.add_unknown_to_log();
+            f(self);
         }
     }
 
 
     fn to_call_log<E:Encodable<TestEncoder>>(val: E) -> ~[call] {
-        let mut te = TestEncoder {call_log: @mut ~[]};
-        val.encode(&te);
+        let mut te = TestEncoder {
+            call_log: @mut ~[]
+        };
+        val.encode(&mut te);
         copy *te.call_log
     }
 
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 48f6d5baa8b..fe270abc2e4 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -96,7 +96,7 @@ fn create_decode_method(
         cx,
         span,
         build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D")),
-        ast::m_imm
+        ast::m_mutbl
     );
     let d_ident = cx.ident_of(~"__d");
     let d_arg = build::mk_arg(cx, span, d_ident, d_arg_type);
@@ -219,6 +219,11 @@ fn create_read_struct_field(
     // Call the substructure method.
     let decode_expr = call_substructure_decode_method(cx, span);
 
+    let d_arg = build::mk_arg(cx,
+                              span,
+                              cx.ident_of(~"__d"),
+                              build::mk_ty_infer(cx, span));
+
     let call_expr = build::mk_method_call(
         cx,
         span,
@@ -227,7 +232,11 @@ fn create_read_struct_field(
         ~[
             build::mk_base_str(cx, span, cx.str_of(ident)),
             build::mk_uint(cx, span, idx),
-            build::mk_lambda_no_args(cx, span, decode_expr),
+            build::mk_lambda(cx,
+                             span,
+                             build::mk_fn_decl(~[d_arg],
+                                               build::mk_ty_infer(cx, span)),
+                             decode_expr),
         ]
     );
 
@@ -282,6 +291,11 @@ fn expand_deriving_decodable_struct_method(
         i += 1;
     }
 
+    let d_arg = build::mk_arg(cx,
+                              span,
+                              cx.ident_of(~"__d"),
+                              build::mk_ty_infer(cx, span));
+
     let read_struct_expr = build::mk_method_call(
         cx,
         span,
@@ -294,9 +308,10 @@ fn expand_deriving_decodable_struct_method(
         ~[
             build::mk_base_str(cx, span, cx.str_of(type_ident)),
             build::mk_uint(cx, span, fields.len()),
-            build::mk_lambda_no_args(
+            build::mk_lambda(
                 cx,
                 span,
+                build::mk_fn_decl(~[d_arg], build::mk_ty_infer(cx, span)),
                 build::mk_struct_e(
                     cx,
                     span,
@@ -334,6 +349,12 @@ fn create_read_variant_arg(
             // Call the substructure method.
             let expr = call_substructure_decode_method(cx, span);
 
+            let d_arg = build::mk_arg(cx,
+                                      span,
+                                      cx.ident_of(~"__d"),
+                                      build::mk_ty_infer(cx, span));
+            let t_infer = build::mk_ty_infer(cx, span);
+
             let call_expr = build::mk_method_call(
                 cx,
                 span,
@@ -341,7 +362,10 @@ fn create_read_variant_arg(
                 cx.ident_of(~"read_enum_variant_arg"),
                 ~[
                     build::mk_uint(cx, span, j),
-                    build::mk_lambda_no_args(cx, span, expr),
+                    build::mk_lambda(cx,
+                                     span,
+                                     build::mk_fn_decl(~[d_arg], t_infer),
+                                     expr),
                 ]
             );
 
@@ -402,6 +426,12 @@ fn create_read_enum_variant(
                         build::mk_arg(
                             cx,
                             span,
+                            cx.ident_of(~"__d"),
+                            build::mk_ty_infer(cx, span)
+                        ),
+                        build::mk_arg(
+                            cx,
+                            span,
                             cx.ident_of(~"__i"),
                             build::mk_ty_infer(cx, span)
                         )
@@ -434,6 +464,11 @@ fn expand_deriving_decodable_enum_method(
         enum_definition
     );
 
+    let d_arg = build::mk_arg(cx,
+                              span,
+                              cx.ident_of(~"__d"),
+                              build::mk_ty_infer(cx, span));
+
     // Create the read_enum expression
     let read_enum_expr = build::mk_method_call(
         cx,
@@ -442,7 +477,11 @@ fn expand_deriving_decodable_enum_method(
         cx.ident_of(~"read_enum"),
         ~[
             build::mk_base_str(cx, span, cx.str_of(type_ident)),
-            build::mk_lambda_no_args(cx, span, read_enum_variant_expr),
+            build::mk_lambda(cx,
+                             span,
+                             build::mk_fn_decl(~[d_arg],
+                                               build::mk_ty_infer(cx, span)),
+                             read_enum_variant_expr),
         ]
     );
 
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 640d0d0ff2d..8f8139790ad 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -94,10 +94,9 @@ fn create_encode_method(
         cx,
         span,
         build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E")),
-        ast::m_imm
+        ast::m_mutbl
     );
-    let e_ident = cx.ident_of(~"__e");
-    let e_arg = build::mk_arg(cx, span, e_ident, e_arg_type);
+    let e_arg = build::mk_arg(cx, span, cx.ident_of(~"__e"), e_arg_type);
 
     // Create the type of the return value.
     let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
@@ -226,10 +225,16 @@ fn expand_deriving_encodable_struct_method(
                     self_field
                 );
 
+                let e_ident = cx.ident_of(~"__e");
+                let e_arg = build::mk_arg(cx,
+                                          span,
+                                          e_ident,
+                                          build::mk_ty_infer(cx, span));
+
                 let blk_expr = build::mk_lambda(
                     cx,
                     span,
-                    build::mk_fn_decl(~[], build::mk_ty_infer(cx, span)),
+                    build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
                     encode_expr
                 );
 
@@ -257,6 +262,11 @@ fn expand_deriving_encodable_struct_method(
         idx += 1;
     }
 
+    let e_arg = build::mk_arg(cx,
+                              span,
+                              cx.ident_of(~"__e"),
+                              build::mk_ty_infer(cx, span));
+
     let emit_struct_stmt = build::mk_method_call(
         cx,
         span,
@@ -272,7 +282,7 @@ fn expand_deriving_encodable_struct_method(
             build::mk_lambda_stmts(
                 cx,
                 span,
-                build::mk_fn_decl(~[], build::mk_ty_infer(cx, span)),
+                build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
                 statements
             ),
         ]
@@ -309,10 +319,16 @@ fn expand_deriving_encodable_enum_method(
             // Call the substructure method.
             let expr = call_substructure_encode_method(cx, span, field);
 
+            let e_ident = cx.ident_of(~"__e");
+            let e_arg = build::mk_arg(cx,
+                                      span,
+                                      e_ident,
+                                      build::mk_ty_infer(cx, span));
+
             let blk_expr = build::mk_lambda(
                 cx,
                 span,
-                build::mk_fn_decl(~[], build::mk_ty_infer(cx, span)),
+                build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
                 expr
             );
 
@@ -331,6 +347,10 @@ fn expand_deriving_encodable_enum_method(
         }
 
         // Create the pattern body.
+        let e_arg = build::mk_arg(cx,
+                                  span,
+                                  cx.ident_of(~"__e"),
+                                  build::mk_ty_infer(cx, span));
         let call_expr = build::mk_method_call(
             cx,
             span,
@@ -343,7 +363,7 @@ fn expand_deriving_encodable_enum_method(
                 build::mk_lambda_stmts(
                     cx,
                     span,
-                    build::mk_fn_decl(~[], build::mk_ty_infer(cx, span)),
+                    build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
                     stmts
                 )
             ]
@@ -359,11 +379,17 @@ fn expand_deriving_encodable_enum_method(
         }
     };
 
+    let e_ident = cx.ident_of(~"__e");
+    let e_arg = build::mk_arg(cx,
+                              span,
+                              e_ident,
+                              build::mk_ty_infer(cx, span));
+
     // Create the method body.
     let lambda_expr = build::mk_lambda(
         cx,
         span,
-        build::mk_fn_decl(~[], build::mk_ty_infer(cx, span)),
+        build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
         expand_enum_or_struct_match(cx, span, arms)
     );
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 4f1d41a4a7a..0c024958a24 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -420,7 +420,8 @@ mod test {
 
     #[cfg(test)] fn to_json_str<E : Encodable<std::json::Encoder>>(val: @E) -> ~str {
         do io::with_str_writer |writer| {
-            val.encode(~std::json::Encoder(writer));
+            let mut encoder = std::json::Encoder(writer);
+            val.encode(&mut encoder);
         }
     }