diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/codemap.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 48 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/decodable.rs | 30 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/owned_slice.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 17 |
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 { |
