diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index 64208c0af48e..3734b8db2c03 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -120,3 +120,151 @@ fn serialize_uint(s: S, v: uint) { fn deserialize_uint(d: D) -> uint { d.read_uint() } + +fn serialize_u8(s: S, v: u8) { + s.emit_u8(v); +} + +fn deserialize_u8(d: D) -> u8 { + d.read_u8() +} + +fn serialize_u16(s: S, v: u16) { + s.emit_u16(v); +} + +fn deserialize_u16(d: D) -> u16 { + d.read_u16() +} + +fn serialize_u32(s: S, v: u32) { + s.emit_u32(v); +} + +fn deserialize_u32(d: D) -> u32 { + d.read_u32() +} + +fn serialize_u64(s: S, v: u64) { + s.emit_u64(v); +} + +fn deserialize_u64(d: D) -> u64 { + d.read_u64() +} + +fn serialize_int(s: S, v: int) { + s.emit_int(v); +} + +fn deserialize_int(d: D) -> int { + d.read_int() +} + +fn serialize_i8(s: S, v: i8) { + s.emit_i8(v); +} + +fn deserialize_i8(d: D) -> i8 { + d.read_i8() +} + +fn serialize_i16(s: S, v: i16) { + s.emit_i16(v); +} + +fn deserialize_i16(d: D) -> i16 { + d.read_i16() +} + +fn serialize_i32(s: S, v: i32) { + s.emit_i32(v); +} + +fn deserialize_i32(d: D) -> i32 { + d.read_i32() +} + +fn serialize_i64(s: S, v: i64) { + s.emit_i64(v); +} + +fn deserialize_i64(d: D) -> i64 { + d.read_i64() +} + +fn serialize_str(s: S, v: str) { + s.emit_str(v); +} + +fn deserialize_str(d: D) -> str { + d.read_str() +} + +fn serialize_float(s: S, v: float) { + s.emit_float(v); +} + +fn deserialize_float(d: D) -> float { + d.read_float() +} + +fn serialize_f32(s: S, v: f32) { + s.emit_f32(v); +} + +fn deserialize_f32(d: D) -> f32 { + d.read_f32() +} + +fn serialize_f64(s: S, v: f64) { + s.emit_f64(v); +} + +fn deserialize_f64(d: D) -> f64 { + d.read_f64() +} + +fn serialize_bool(s: S, v: bool) { + s.emit_bool(v); +} + +fn deserialize_bool(d: D) -> bool { + d.read_bool() +} + +fn serialize_option(s: S, v: option, st: fn(T)) { + s.emit_enum("option") {|| + alt v { + none { + s.emit_enum_variant("none", 0u, 0u) {|| + } + } + + some(v) { + s.emit_enum_variant("some", 1u, 1u) {|| + s.emit_enum_variant_arg(0u) {|| + st(v) + } + } + } + } + } +} + +fn deserialize_option(d: D, st: fn() -> T) -> option { + d.read_enum("option") {|| + d.read_enum_variant {|i| + alt check i { + 0u { // none + none + } + 1u { // some(v) + some(d.read_enum_variant_arg(0u) {|| + st() + }) + } + } + } + } +} diff --git a/src/rustc/syntax/ast.rs b/src/rustc/syntax/ast.rs index 91a884ce57ce..a925514b8fb0 100644 --- a/src/rustc/syntax/ast.rs +++ b/src/rustc/syntax/ast.rs @@ -1,33 +1,70 @@ // The Rust abstract syntax tree. import codemap::{span, filename}; +import std::serialization::{serializer, + deserializer, + serialize_option, + deserialize_option, + serialize_uint, + deserialize_uint, + serialize_int, + deserialize_int, + serialize_i64, + deserialize_i64, + serialize_u64, + deserialize_u64, + serialize_str, + deserialize_str, + serialize_bool, + deserialize_bool}; +fn serialize_span(_s: S, _v: span) { + // FIXME-- serialize some span info +} + +fn deserialize_span(_d: D) -> span { + ast_util::dummy_sp() +} + +/*#[auto_serialize]*/ type spanned = {node: T, span: span}; +/*#[auto_serialize]*/ type ident = str; // Functions may or may not have names. +/*#[auto_serialize]*/ type fn_ident = option; +/*#[auto_serialize]*/ type path_ = {global: bool, idents: [ident], types: [@ty]}; +/*#[auto_serialize]*/ type path = spanned; +/*#[auto_serialize]*/ type crate_num = int; + +/*#[auto_serialize]*/ type node_id = int; + +/*#[auto_serialize]*/ type def_id = {crate: crate_num, node: node_id}; const local_crate: crate_num = 0; const crate_node_id: node_id = 0; +/*#[auto_serialize]*/ enum ty_param_bound { bound_copy, bound_send, bound_iface(@ty), } +/*#[auto_serialize]*/ type ty_param = {ident: ident, id: node_id, bounds: @[ty_param_bound]}; +/*#[auto_serialize]*/ enum def { def_fn(def_id, purity), def_self(node_id), @@ -82,23 +119,30 @@ enum crate_directive_ { type crate_directive = spanned; +/*#[auto_serialize]*/ type meta_item = spanned; +/*#[auto_serialize]*/ enum meta_item_ { meta_word(ident), meta_list(ident, [@meta_item]), meta_name_value(ident, lit), } +/*#[auto_serialize]*/ type blk = spanned; +/*#[auto_serialize]*/ type blk_ = {view_items: [@view_item], stmts: [@stmt], expr: option<@expr>, id: node_id, rules: blk_check_mode}; +/*#[auto_serialize]*/ type pat = {id: node_id, node: pat_, span: span}; +/*#[auto_serialize]*/ type field_pat = {ident: ident, pat: @pat}; +/*#[auto_serialize]*/ enum pat_ { pat_wild, // A pat_ident may either be a new bound variable, @@ -118,8 +162,10 @@ enum pat_ { pat_range(@expr, @expr), } +/*#[auto_serialize]*/ enum mutability { m_mutbl, m_imm, m_const, } +/*#[auto_serialize]*/ enum proto { proto_bare, // native fn proto_any, // fn @@ -135,6 +181,7 @@ pure fn is_blockish(p: ast::proto) -> bool { } } +/*#[auto_serialize]*/ enum binop { add, subtract, @@ -157,6 +204,7 @@ enum binop { gt, } +/*#[auto_serialize]*/ enum unop { box(mutability), uniq(mutability), @@ -165,18 +213,23 @@ enum unop { // Generally, after typeck you can get the inferred value // using ty::resolved_T(...). +/*#[auto_serialize]*/ enum inferable { expl(T), infer(node_id) } // "resolved" mode: the real modes. +/*#[auto_serialize]*/ enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy } // inferable mode. +/*#[auto_serialize]*/ type mode = inferable; +/*#[auto_serialize]*/ type stmt = spanned; +/*#[auto_serialize]*/ enum stmt_ { stmt_decl(@decl, node_id), @@ -187,34 +240,48 @@ enum stmt_ { stmt_semi(@expr, node_id), } +/*#[auto_serialize]*/ enum init_op { init_assign, init_move, } +/*#[auto_serialize]*/ type initializer = {op: init_op, expr: @expr}; +/*#[auto_serialize]*/ type local_ = // FIXME: should really be a refinement on pat {is_mutbl: bool, ty: @ty, pat: @pat, init: option, id: node_id}; +/*#[auto_serialize]*/ type local = spanned; +/*#[auto_serialize]*/ type decl = spanned; +/*#[auto_serialize]*/ enum decl_ { decl_local([@local]), decl_item(@item), } +/*#[auto_serialize]*/ type arm = {pats: [@pat], guard: option<@expr>, body: blk}; +/*#[auto_serialize]*/ type field_ = {mutbl: mutability, ident: ident, expr: @expr}; +/*#[auto_serialize]*/ type field = spanned; +/*#[auto_serialize]*/ enum blk_check_mode { default_blk, unchecked_blk, unsafe_blk, } +/*#[auto_serialize]*/ enum expr_check_mode { claimed_expr, checked_expr, } +/*#[auto_serialize]*/ type expr = {id: node_id, node: expr_, span: span}; +/*#[auto_serialize]*/ enum alt_mode { alt_check, alt_exhaustive, } +/*#[auto_serialize]*/ enum expr_ { expr_vec([@expr], mutability), expr_rec([field], option<@expr>), @@ -270,11 +337,14 @@ enum expr_ { expr_mac(mac), } +/*#[auto_serialize]*/ type capture_item = { id: int, name: ident, // Currently, can only capture a local var. span: span }; + +/*#[auto_serialize]*/ type capture_clause = { copies: [@capture_item], moves: [@capture_item] @@ -289,13 +359,19 @@ enum blk_sort { } */ +/*#[auto_serialize]*/ type mac = spanned; +/*#[auto_serialize]*/ type mac_arg = option<@expr>; +/*#[auto_serialize]*/ type mac_body_ = {span: span}; + +/*#[auto_serialize]*/ type mac_body = option; +/*#[auto_serialize]*/ enum mac_ { mac_invoc(@path, mac_arg, mac_body), mac_embed_type(@ty), @@ -306,8 +382,10 @@ enum mac_ { mac_var(uint) } +/*#[auto_serialize]*/ type lit = spanned; +/*#[auto_serialize]*/ enum lit_ { lit_str(str), lit_int(i64, int_ty), @@ -319,24 +397,33 @@ enum lit_ { // NB: If you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. +/*#[auto_serialize]*/ type mt = {ty: @ty, mutbl: mutability}; +/*#[auto_serialize]*/ type ty_field_ = {ident: ident, mt: mt}; +/*#[auto_serialize]*/ type ty_field = spanned; +/*#[auto_serialize]*/ type ty_method = {ident: ident, attrs: [attribute], decl: fn_decl, tps: [ty_param], span: span}; +/*#[auto_serialize]*/ enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } +/*#[auto_serialize]*/ enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } +/*#[auto_serialize]*/ enum float_ty { ty_f, ty_f32, ty_f64, } +/*#[auto_serialize]*/ type ty = {id: node_id, node: ty_, span: span}; // Not represented directly in the AST, referred to by name through a ty_path. +/*#[auto_serialize]*/ enum prim_ty { ty_int(int_ty), ty_uint(uint_ty), @@ -345,14 +432,17 @@ enum prim_ty { ty_bool, } +/*#[auto_serialize]*/ type region = {id: node_id, node: region_}; +/*#[auto_serialize]*/ enum region_ { re_inferred, re_named(ident), re_self } +/*#[auto_serialize]*/ enum ty_ { ty_nil, ty_bot, /* bottom type */ @@ -382,11 +472,19 @@ so that the typestate pass doesn't have to map a function name onto its decl. So, the constr_arg type is parameterized: it's instantiated with uint for declarations, and ident for uses. */ +/*#[auto_serialize]*/ enum constr_arg_general_ { carg_base, carg_ident(T), carg_lit(@lit), } +/*#[auto_serialize]*/ type fn_constr_arg = constr_arg_general_; + +/*#[auto_serialize]*/ type sp_constr_arg = spanned>; + +/*#[auto_serialize]*/ type ty_constr_arg = sp_constr_arg<@path>; + +/*#[auto_serialize]*/ type constr_arg = spanned; // Constrained types' args are parameterized by paths, since @@ -394,22 +492,34 @@ type constr_arg = spanned; // The implicit root of such path, in the constraint-list for a // constrained type, is * (referring to the base record) +/*#[auto_serialize]*/ type constr_general_ = {path: @path, args: [@spanned>], id: ID}; // In the front end, constraints have a node ID attached. // Typeck turns this to a def_id, using the output of resolve. +/*#[auto_serialize]*/ type constr_general = spanned>; + +/*#[auto_serialize]*/ type constr_ = constr_general_; + +/*#[auto_serialize]*/ type constr = spanned>; + +/*#[auto_serialize]*/ type ty_constr_ = constr_general_<@path, node_id>; + +/*#[auto_serialize]*/ type ty_constr = spanned; /* The parser generates ast::constrs; resolve generates a mapping from each function to a list of ty::constr_defs, corresponding to these. */ +/*#[auto_serialize]*/ type arg = {mode: mode, ty: @ty, ident: ident, id: node_id}; +/*#[auto_serialize]*/ type fn_decl = {inputs: [arg], output: @ty, @@ -417,6 +527,7 @@ type fn_decl = cf: ret_style, constraints: [@constr]}; +/*#[auto_serialize]*/ enum purity { pure_fn, // declared with "pure fn" unsafe_fn, // declared with "unsafe fn" @@ -424,44 +535,58 @@ enum purity { crust_fn, // declared with "crust fn" } +/*#[auto_serialize]*/ enum ret_style { noreturn, // functions with return type _|_ that always // raise an error or exit (i.e. never return to the caller) return_val, // everything else } +/*#[auto_serialize]*/ type method = {ident: ident, attrs: [attribute], tps: [ty_param], decl: fn_decl, body: blk, id: node_id, span: span, self_id: node_id}; +/*#[auto_serialize]*/ type _mod = {view_items: [@view_item], items: [@item]}; +/*#[auto_serialize]*/ enum native_abi { native_abi_rust_intrinsic, native_abi_cdecl, native_abi_stdcall, } +/*#[auto_serialize]*/ type native_mod = {view_items: [@view_item], items: [@native_item]}; +/*#[auto_serialize]*/ type variant_arg = {ty: @ty, id: node_id}; +/*#[auto_serialize]*/ type variant_ = {name: ident, attrs: [attribute], args: [variant_arg], id: node_id, disr_expr: option<@expr>}; +/*#[auto_serialize]*/ type variant = spanned; - // FIXME: May want to just use path here, which would allow things like // 'import ::foo' +/*#[auto_serialize]*/ type simple_path = [ident]; +/*#[auto_serialize]*/ type path_list_ident_ = {name: ident, id: node_id}; + +/*#[auto_serialize]*/ type path_list_ident = spanned; +/*#[auto_serialize]*/ type view_path = spanned; + +/*#[auto_serialize]*/ enum view_path_ { // quux = foo::bar::baz @@ -478,7 +603,10 @@ enum view_path_ { view_path_list(@simple_path, [path_list_ident], node_id) } +/*#[auto_serialize]*/ type view_item = spanned; + +/*#[auto_serialize]*/ enum view_item_ { view_item_use(ident, [@meta_item], node_id), view_item_import([@view_path]), @@ -486,19 +614,23 @@ enum view_item_ { } // Meta-data associated with an item +/*#[auto_serialize]*/ type attribute = spanned; - // Distinguishes between attributes that decorate items and attributes that // are contained as statements within items. These two cases need to be // distinguished for pretty-printing. +/*#[auto_serialize]*/ enum attr_style { attr_outer, attr_inner, } +/*#[auto_serialize]*/ type attribute_ = {style: attr_style, value: meta_item}; +/*#[auto_serialize]*/ type item = {ident: ident, attrs: [attribute], id: node_id, node: item_, span: span}; +/*#[auto_serialize]*/ enum item_ { item_const(@ty, @expr), item_fn(fn_decl, [ty_param], blk), @@ -518,9 +650,13 @@ enum item_ { @ty /* self */, [@method]), } +/*#[auto_serialize]*/ type class_item_ = {privacy: privacy, decl: class_member}; + +/*#[auto_serialize]*/ type class_item = spanned; +/*#[auto_serialize]*/ enum class_member { instance_var(ident, @ty, class_mutability, node_id), class_method(@item) // FIXME: methods aren't allowed to be @@ -529,15 +665,21 @@ enum class_member { // item to separate out things with type params? } +/*#[auto_serialize]*/ enum class_mutability { class_mutable, class_immutable } +/*#[auto_serialize]*/ enum privacy { priv, pub } +/*#[auto_serialize]*/ type class_ctor = spanned; + +/*#[auto_serialize]*/ type class_ctor_ = {id: node_id, dec: fn_decl, body: blk}; +/*#[auto_serialize]*/ type native_item = {ident: ident, attrs: [attribute], @@ -545,6 +687,7 @@ type native_item = id: node_id, span: span}; +/*#[auto_serialize]*/ enum native_item_ { native_item_fn(fn_decl, [ty_param]), } @@ -552,6 +695,7 @@ enum native_item_ { // The data we save and restore about an inlined item or method. This is not // part of the AST that we parse from a file, but it becomes part of the tree // that we trans. +/*#[auto_serialize]*/ enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method) diff --git a/src/rustc/syntax/ext/auto_serialize.rs b/src/rustc/syntax/ext/auto_serialize.rs index 698b962eba7d..44db1b1e1018 100644 --- a/src/rustc/syntax/ext/auto_serialize.rs +++ b/src/rustc/syntax/ext/auto_serialize.rs @@ -130,9 +130,14 @@ impl helpers for ext_ctxt { span: span} } - fn ty_path(span: span, strs: [str]) -> @ast::ty { + fn path_tps(span: span, strs: [str], tps: [@ast::ty]) -> @ast::path { + @{node: {global: false, idents: strs, types: tps}, + span: span} + } + + fn ty_path(span: span, strs: [str], tps: [@ast::ty]) -> @ast::ty { @{id: self.next_id(), - node: ast::ty_path(self.path(span, strs), self.next_id()), + node: ast::ty_path(self.path_tps(span, strs, tps), self.next_id()), span: span} } @@ -469,27 +474,30 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map, } } -fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, - -v_ty: @ast::ty, tps: [ast::ty_param], - f: fn(ext_ctxt, ser_tps_map, @ast::ty, +fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param], + f: fn(ext_ctxt, ser_tps_map, -@ast::expr, -@ast::expr) -> [@ast::stmt]) -> @ast::item { let ext_cx = cx; // required for #ast + let tp_types = vec::map(tps, {|tp| cx.ty_path(span, [tp.ident], [])}); + let v_ty = cx.ty_path(span, [name], tp_types); + let tp_inputs = vec::map(tps, {|tp| {mode: ast::expl(ast::by_ref), ty: cx.ty_fn(span, - [cx.ty_path(span, [tp.ident])], + [cx.ty_path(span, [tp.ident], [])], cx.ty_nil(span)), ident: "__s" + tp.ident, id: cx.next_id()}}); #debug["tp_inputs = %?", tp_inputs]; + let ser_inputs: [ast::arg] = [{mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, ["__S"]), + ty: cx.ty_path(span, ["__S"], []), ident: "__s", id: cx.next_id()}, {mode: ast::expl(ast::by_ref), @@ -510,10 +518,10 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, }); } - let ser_bnds = @[ast::bound_iface(cx.ty_path(span, - ["std", - "serialization", - "serializer"]))]; + let ser_bnds = @[ + ast::bound_iface(cx.ty_path(span, + ["std", "serialization", "serializer"], + []))]; let ser_tps: [ast::ty_param] = [{ident: "__S", @@ -526,7 +534,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: str, span: span}; let ser_blk = cx.blk(span, - f(cx, tps_map, v_ty, #ast{ __s }, #ast{ __v })); + f(cx, tps_map, #ast{ __s }, #ast{ __v })); @{ident: "serialize_" + name, attrs: [], @@ -670,19 +678,20 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map, } } -fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, - -v_ty: @ast::ty, tps: [ast::ty_param], - f: fn(ext_ctxt, deser_tps_map, - @ast::ty, -@ast::expr) -> @ast::expr) +fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, tps: [ast::ty_param], + f: fn(ext_ctxt, deser_tps_map, -@ast::expr) -> @ast::expr) -> @ast::item { let ext_cx = cx; // required for #ast + let tp_types = vec::map(tps, {|tp| cx.ty_path(span, [tp.ident], [])}); + let v_ty = cx.ty_path(span, [name], tp_types); + let tp_inputs = vec::map(tps, {|tp| {mode: ast::expl(ast::by_ref), ty: cx.ty_fn(span, [], - cx.ty_path(span, [tp.ident])), + cx.ty_path(span, [tp.ident], [])), ident: "__d" + tp.ident, id: cx.next_id()}}); @@ -690,7 +699,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, let deser_inputs: [ast::arg] = [{mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, ["__D"]), + ty: cx.ty_path(span, ["__D"], []), ident: "__d", id: cx.next_id()}] + tp_inputs; @@ -706,10 +715,10 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, }); } - let deser_bnds = @[ast::bound_iface(cx.ty_path(span, - ["std", - "serialization", - "deserializer"]))]; + let deser_bnds = @[ + ast::bound_iface(cx.ty_path(span, + ["std", "serialization", "deserializer"], + []))]; let deser_tps: [ast::ty_param] = [{ident: "__D", @@ -717,7 +726,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, name: str, bounds: deser_bnds}] + vec::map(tps) {|tp| cx.clone_ty_param(tp) }; - let deser_blk = cx.expr_blk(f(cx, tps_map, v_ty, #ast(expr){__d})); + let deser_blk = cx.expr_blk(f(cx, tps_map, #ast(expr){__d})); @{ident: "deserialize_" + name, attrs: [], @@ -737,14 +746,14 @@ fn ty_fns(cx: ext_ctxt, name: str, ty: @ast::ty, tps: [ast::ty_param]) let span = ty.span; [ - mk_ser_fn(cx, span, name, cx.clone_ty(ty), tps, ser_ty), - mk_deser_fn(cx, span, name, cx.clone_ty(ty), tps, deser_ty) + mk_ser_fn(cx, span, name, tps, ser_ty(_, _, ty, _, _)), + mk_deser_fn(cx, span, name, tps, deser_ty(_, _, ty, _)) ] } fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: str, e_span: span, variants: [ast::variant], - _ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) -> [@ast::stmt] { + -s: @ast::expr, -v: @ast::expr) -> [@ast::stmt] { let ext_cx = cx; let arms = vec::from_fn(vec::len(variants)) {|vidx| let variant = variants[vidx]; @@ -793,7 +802,7 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: str, fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: str, e_span: span, variants: [ast::variant], - _ty: @ast::ty, -d: @ast::expr) -> @ast::expr { + -d: @ast::expr) -> @ast::expr { let ext_cx = cx; let arms: [ast::arm] = vec::from_fn(vec::len(variants)) {|vidx| let variant = variants[vidx]; @@ -831,11 +840,10 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: str, fn enum_fns(cx: ext_ctxt, e_name: str, e_span: span, variants: [ast::variant], tps: [ast::ty_param]) -> [@ast::item] { - let ty = cx.ty_path(e_span, [e_name]); [ - mk_ser_fn(cx, e_span, e_name, cx.clone_ty(ty), tps, - ser_enum(_, _, e_name, e_span, variants, _, _, _)), - mk_deser_fn(cx, e_span, e_name, ty, tps, - deser_enum(_, _, e_name, e_span, variants, _, _)) + mk_ser_fn(cx, e_span, e_name, tps, + ser_enum(_, _, e_name, e_span, variants, _, _)), + mk_deser_fn(cx, e_span, e_name, tps, + deser_enum(_, _, e_name, e_span, variants, _)) ] } diff --git a/src/test/run-pass/auto_serialize.rs b/src/test/run-pass/auto_serialize.rs index 72e8cc238c20..eabe25697d94 100644 --- a/src/test/run-pass/auto_serialize.rs +++ b/src/test/run-pass/auto_serialize.rs @@ -63,6 +63,15 @@ type uint_vec = [uint]; #[auto_serialize] type point = {x: uint, y: uint}; +#[auto_serialize] +enum quark { + top(T), + bottom(T) +} + +#[auto_serialize] +type uint_quark = quark; + fn main() { test_ser_and_deser(plus(@minus(@val(3u), @val(10u)), @@ -96,4 +105,16 @@ fn main() { serialize_uint_vec(_, _), deserialize_uint_vec(_), serialize_uint_vec(_, _)); + + test_ser_and_deser(top(22u), + "top(22u)", + serialize_uint_quark(_, _), + deserialize_uint_quark(_), + serialize_uint_quark(_, _)); + + test_ser_and_deser(bottom(222u), + "bottom(222u)", + serialize_uint_quark(_, _), + deserialize_uint_quark(_), + serialize_uint_quark(_, _)); } \ No newline at end of file