about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs37
-rw-r--r--src/libsyntax/codemap.rs18
-rw-r--r--src/libsyntax/ext/build.rs48
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs30
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs40
-rw-r--r--src/libsyntax/owned_slice.rs20
-rw-r--r--src/libsyntax/parse/mod.rs11
-rw-r--r--src/libsyntax/parse/token.rs17
8 files changed, 205 insertions, 16 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a7d458df0cf..a44fbce421b 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -98,18 +98,35 @@ pub type Name = u32;
 /// A mark represents a unique id associated with a macro expansion
 pub type Mrk = u32;
 
+// FIXME: remove stage0 Encodables after snapshot
+#[cfg(stage0)]
 impl<S: Encoder> Encodable<S> for Ident {
     fn encode(&self, s: &mut S) {
         s.emit_str(token::get_ident(*self).get());
     }
 }
 
+#[cfg(stage0)]
 impl<D:Decoder> Decodable<D> for Ident {
     fn decode(d: &mut D) -> Ident {
         str_to_ident(d.read_str())
     }
 }
 
+#[cfg(not(stage0))]
+impl<S: Encoder<E>, E> Encodable<S, E> for Ident {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        s.emit_str(token::get_ident(*self).get())
+    }
+}
+
+#[cfg(not(stage0))]
+impl<D:Decoder<E>, E> Decodable<D, E> for Ident {
+    fn decode(d: &mut D) -> Result<Ident, E> {
+        Ok(str_to_ident(try!(d.read_str())))
+    }
+}
+
 /// Function name (not all functions have names)
 pub type FnIdent = Option<Ident>;
 
@@ -1166,7 +1183,9 @@ mod test {
     use super::*;
 
     // are ASTs encodable?
+    // FIXME: remove stage0 test after snapshot
     #[test]
+    #[cfg(stage0)]
     fn check_asts_encodable() {
         let e = Crate {
             module: Mod {view_items: Vec::new(), items: Vec::new()},
@@ -1181,4 +1200,22 @@ mod test {
         // doesn't matter which encoder we use....
         let _f = &e as &serialize::Encodable<json::Encoder>;
     }
+
+    #[test]
+    #[cfg(not(stage0))]
+    fn check_asts_encodable() {
+        use std::io;
+        let e = Crate {
+            module: Mod {view_items: Vec::new(), items: Vec::new()},
+            attrs: Vec::new(),
+            config: Vec::new(),
+            span: Span {
+                lo: BytePos(10),
+                hi: BytePos(20),
+                expn_info: None,
+            },
+        };
+        // doesn't matter which encoder we use....
+        let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
+    }
 }
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 4a9e53c63e7..f3ff7f97ee2 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -110,6 +110,8 @@ impl Eq for Span {
 
 impl TotalEq for Span {}
 
+// FIXME: remove stage0 Encodables/Decodables after snapshot
+#[cfg(stage0)]
 impl<S:Encoder> Encodable<S> for Span {
     /* Note #1972 -- spans are encoded but not decoded */
     fn encode(&self, s: &mut S) {
@@ -117,12 +119,28 @@ impl<S:Encoder> Encodable<S> for Span {
     }
 }
 
+#[cfg(stage0)]
 impl<D:Decoder> Decodable<D> for Span {
     fn decode(_d: &mut D) -> Span {
         DUMMY_SP
     }
 }
 
+#[cfg(not(stage0))]
+impl<S:Encoder<E>, E> Encodable<S, E> for Span {
+    /* Note #1972 -- spans are encoded but not decoded */
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        s.emit_nil()
+    }
+}
+
+#[cfg(not(stage0))]
+impl<D:Decoder<E>, E> Decodable<D, E> for Span {
+    fn decode(_d: &mut D) -> Result<Span, E> {
+        Ok(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/build.rs b/src/libsyntax/ext/build.rs
index bdb16f176c0..1c2c63cd919 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -142,6 +142,10 @@ pub trait AstBuilder {
     fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr;
     fn expr_unreachable(&self, span: Span) -> @ast::Expr;
 
+    fn expr_ok(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
+    fn expr_err(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
+    fn expr_try(&self, span: Span, head: @ast::Expr) -> @ast::Expr;
+
     fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat;
     fn pat_wild(&self, span: Span) -> @ast::Pat;
     fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat;
@@ -638,6 +642,50 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                            "internal error: entered unreachable code"))
     }
 
+    fn expr_ok(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr {
+        let ok = vec!(
+            self.ident_of("std"),
+            self.ident_of("result"),
+            self.ident_of("Ok"));
+        self.expr_call_global(sp, ok, vec!(expr))
+    }
+
+    fn expr_err(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr {
+        let err = vec!(
+            self.ident_of("std"),
+            self.ident_of("result"),
+            self.ident_of("Err"));
+        self.expr_call_global(sp, err, vec!(expr))
+    }
+
+    fn expr_try(&self, sp: Span, head: @ast::Expr) -> @ast::Expr {
+        let ok = self.ident_of("Ok");
+        let ok_path = self.path_ident(sp, ok);
+        let err = self.ident_of("Err");
+        let err_path = self.path_ident(sp, err);
+
+        let binding_variable = self.ident_of("__try_var");
+        let binding_pat = self.pat_ident(sp, binding_variable);
+        let binding_expr = self.expr_ident(sp, binding_variable);
+
+        // Ok(__try_var) pattern
+        let ok_pat = self.pat_enum(sp, ok_path, vec!(binding_pat));
+
+        // Err(__try_var)  (pattern and expression resp.)
+        let err_pat = self.pat_enum(sp, err_path, vec!(binding_pat));
+        let err_inner_expr = self.expr_call_ident(sp, err, vec!(binding_expr));
+        // return Err(__try_var)
+        let err_expr = self.expr(sp, ast::ExprRet(Some(err_inner_expr)));
+
+        // Ok(__try_var) => __try_var
+        let ok_arm = self.arm(sp, vec!(ok_pat), binding_expr);
+        // Err(__try_var) => return Err(__try_var)
+        let err_arm = self.arm(sp, vec!(err_pat), err_expr);
+
+        // match head { Ok() => ..., Err() => ... }
+        self.expr_match(sp, head, vec!(ok_arm, err_arm))
+    }
+
 
     fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat {
         @ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 4c9a58c46f7..579de82c8db 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -30,11 +30,15 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
         span: span,
         attributes: Vec::new(),
         path: Path::new_(vec!("serialize", "Decodable"), None,
-                         vec!(~Literal(Path::new_local("__D"))), true),
+                         vec!(~Literal(Path::new_local("__D")),
+                              ~Literal(Path::new_local("__E"))), true),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds {
             lifetimes: Vec::new(),
-            bounds: vec!(("__D", vec!(Path::new(vec!("serialize", "Decoder"))))),
+            bounds: vec!(("__D", vec!(Path::new_(
+                            vec!("serialize", "Decoder"), None,
+                            vec!(~Literal(Path::new_local("__E"))), true))),
+                         ("__E", vec!()))
         },
         methods: vec!(
             MethodDef {
@@ -43,7 +47,8 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                 explicit_self: None,
                 args: vec!(Ptr(~Literal(Path::new_local("__D")),
                             Borrowed(None, MutMutable))),
-                ret_ty: Self,
+                ret_ty: Literal(Path::new_(vec!("std", "result", "Result"), None,
+                                          vec!(~Self, ~Literal(Path::new_local("__E"))), true)),
                 inline: false,
                 const_nonmatching: true,
                 combine_substructure: decodable_substructure,
@@ -78,11 +83,13 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                               substr.type_ident,
                                               summary,
                                               |cx, span, name, field| {
-                cx.expr_method_call(span, blkdecoder, read_struct_field,
-                                    vec!(cx.expr_str(span, name),
-                                      cx.expr_uint(span, field),
-                                      lambdadecode))
+                cx.expr_try(span,
+                    cx.expr_method_call(span, blkdecoder, read_struct_field,
+                                        vec!(cx.expr_str(span, name),
+                                          cx.expr_uint(span, field),
+                                          lambdadecode)))
             });
+            let result = cx.expr_ok(trait_span, result);
             cx.expr_method_call(trait_span,
                                 decoder,
                                 cx.ident_of("read_struct"),
@@ -108,8 +115,9 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                    parts,
                                                    |cx, span, _, field| {
                     let idx = cx.expr_uint(span, field);
-                    cx.expr_method_call(span, blkdecoder, rvariant_arg,
-                                        vec!(idx, lambdadecode))
+                    cx.expr_try(span,
+                        cx.expr_method_call(span, blkdecoder, rvariant_arg,
+                                            vec!(idx, lambdadecode)))
                 });
 
                 arms.push(cx.arm(v_span,
@@ -119,7 +127,9 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
 
             arms.push(cx.arm_unreachable(trait_span));
 
-            let result = cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms);
+            let result = cx.expr_ok(trait_span,
+                                    cx.expr_match(trait_span,
+                                                  cx.expr_ident(trait_span, variant), arms));
             let lambda = cx.lambda_expr(trait_span, vec!(blkarg, variant), result);
             let variant_vec = cx.expr_vec(trait_span, variants);
             let result = cx.expr_method_call(trait_span, blkdecoder,
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 2fa6ec6888b..90ea8701562 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -82,7 +82,7 @@ would yield functions like:
 ```
 */
 
-use ast::{MetaItem, Item, Expr, MutMutable};
+use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
@@ -98,20 +98,28 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
         span: span,
         attributes: Vec::new(),
         path: Path::new_(vec!("serialize", "Encodable"), None,
-                         vec!(~Literal(Path::new_local("__E"))), true),
+                         vec!(~Literal(Path::new_local("__S")),
+                              ~Literal(Path::new_local("__E"))), true),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds {
             lifetimes: Vec::new(),
-            bounds: vec!(("__E", vec!(Path::new(vec!("serialize", "Encoder"))))),
+            bounds: vec!(("__S", vec!(Path::new_(
+                            vec!("serialize", "Encoder"), None,
+                            vec!(~Literal(Path::new_local("__E"))), true))),
+                         ("__E", vec!()))
         },
         methods: vec!(
             MethodDef {
                 name: "encode",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
-                args: vec!(Ptr(~Literal(Path::new_local("__E")),
+                args: vec!(Ptr(~Literal(Path::new_local("__S")),
                             Borrowed(None, MutMutable))),
-                ret_ty: nil_ty(),
+                ret_ty: Literal(Path::new_(vec!("std", "result", "Result"),
+                                           None,
+                                           vec!(~Tuple(Vec::new()),
+                                                ~Literal(Path::new_local("__E"))),
+                                           true)),
                 inline: false,
                 const_nonmatching: true,
                 combine_substructure: encodable_substructure,
@@ -133,6 +141,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
         Struct(ref fields) => {
             let emit_struct_field = cx.ident_of("emit_struct_field");
             let mut stmts = Vec::new();
+            let last = fields.len() - 1;
             for (i, &FieldInfo {
                     name,
                     self_,
@@ -152,6 +161,13 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                vec!(cx.expr_str(span, name),
                                                  cx.expr_uint(span, i),
                                                  lambda));
+
+                // last call doesn't need a try!
+                let call = if i != last {
+                    cx.expr_try(span, call)
+                } else {
+                    cx.expr(span, ExprRet(Some(call)))
+                };
                 stmts.push(cx.stmt_expr(call));
             }
 
@@ -175,6 +191,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             let encoder = cx.expr_ident(trait_span, blkarg);
             let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
             let mut stmts = Vec::new();
+            let last = fields.len() - 1;
             for (i, &FieldInfo { self_, span, .. }) in fields.iter().enumerate() {
                 let enc = cx.expr_method_call(span, self_, encode, vec!(blkencoder));
                 let lambda = cx.lambda_expr_1(span, enc, blkarg);
@@ -182,9 +199,22 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                emit_variant_arg,
                                                vec!(cx.expr_uint(span, i),
                                                  lambda));
+                let call = if i != last {
+                    cx.expr_try(span, call)
+                } else {
+                    cx.expr(span, ExprRet(Some(call)))
+                };
                 stmts.push(cx.stmt_expr(call));
             }
 
+            // enums with no fields need to return Ok()
+            if stmts.len() == 0 {
+                let ret_ok = cx.expr(trait_span,
+                                     ExprRet(Some(cx.expr_ok(trait_span,
+                                                             cx.expr_lit(trait_span, LitNil)))));
+                stmts.push(cx.stmt_expr(ret_ok));
+            }
+
             let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
             let name = cx.expr_str(trait_span, token::get_ident(variant.node.name));
             let call = cx.expr_method_call(trait_span, blkencoder,
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 57051e78667..c4ce3c5cb55 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -131,14 +131,34 @@ impl<T> FromIterator<T> for OwnedSlice<T> {
     }
 }
 
+// FIXME: remove stage0 Encodables/Decodables after snapshot
+#[cfg(stage0)]
 impl<S: Encoder, T: Encodable<S>> Encodable<S> for OwnedSlice<T> {
     fn encode(&self, s: &mut S) {
        self.as_slice().encode(s)
     }
 }
 
+#[cfg(stage0)]
 impl<D: Decoder, T: Decodable<D>> Decodable<D> for OwnedSlice<T> {
     fn decode(d: &mut D) -> OwnedSlice<T> {
         OwnedSlice::from_vec(Decodable::decode(d))
     }
 }
+
+#[cfg(not(stage0))]
+impl<S: Encoder<E>, T: Encodable<S, E>, E> Encodable<S, E> for OwnedSlice<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+       self.as_slice().encode(s)
+    }
+}
+
+#[cfg(not(stage0))]
+impl<D: Decoder<E>, T: Decodable<D, E>, E> Decodable<D, E> for OwnedSlice<T> {
+    fn decode(d: &mut D) -> Result<OwnedSlice<T>, E> {
+        Ok(OwnedSlice::from_vec(match Decodable::decode(d) {
+            Ok(t) => t,
+            Err(e) => return Err(e)
+        }))
+    }
+}
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index eb6b462fb94..2df93deea14 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -288,7 +288,8 @@ mod test {
     use util::parser_testing::{string_to_expr, string_to_item};
     use util::parser_testing::string_to_stmt;
 
-    #[cfg(test)]
+    // FIXME: remove stage0 to_json_str after snapshot
+    #[cfg(stage0)]
     fn to_json_str<'a, E: Encodable<json::Encoder<'a>>>(val: &E) -> ~str {
         let mut writer = MemWriter::new();
         let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
@@ -296,6 +297,14 @@ mod test {
         str::from_utf8_owned(writer.unwrap()).unwrap()
     }
 
+    #[cfg(not(stage0))]
+    fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> ~str {
+        let mut writer = MemWriter::new();
+        let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
+        let _ = val.encode(&mut encoder);
+        str::from_utf8_owned(writer.unwrap()).unwrap()
+    }
+
     // produce a codemap::span
     fn sp(a: u32, b: u32) -> Span {
         Span{lo:BytePos(a),hi:BytePos(b),expn_info:None}
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 15525912955..7bb920bdf56 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -602,18 +602,35 @@ impl<'a> Equiv<&'a str> for InternedString {
     }
 }
 
+// FIXME: remove stage0 Encodables/Decodables after snapshot
+#[cfg(stage0)]
 impl<D:Decoder> Decodable<D> for InternedString {
     fn decode(d: &mut D) -> InternedString {
         get_name(get_ident_interner().intern(d.read_str()))
     }
 }
 
+#[cfg(stage0)]
 impl<E:Encoder> Encodable<E> for InternedString {
     fn encode(&self, e: &mut E) {
         e.emit_str(self.string.as_slice())
     }
 }
 
+#[cfg(not(stage0))]
+impl<D:Decoder<E>, E> Decodable<D, E> for InternedString {
+    fn decode(d: &mut D) -> Result<InternedString, E> {
+        Ok(get_name(get_ident_interner().intern(try!(d.read_str()))))
+    }
+}
+
+#[cfg(not(stage0))]
+impl<S:Encoder<E>, E> Encodable<S, E> for InternedString {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        s.emit_str(self.string.as_slice())
+    }
+}
+
 /// Returns the string contents of a name, using the task-local interner.
 #[inline]
 pub fn get_name(name: Name) -> InternedString {