fix auto_serialize for enums with type parameters

This commit is contained in:
Niko Matsakis
2012-03-14 17:18:53 -04:00
parent 715d1995d7
commit 1600be2c3b
4 changed files with 355 additions and 34 deletions

View File

@@ -120,3 +120,151 @@ fn serialize_uint<S: serializer>(s: S, v: uint) {
fn deserialize_uint<D: deserializer>(d: D) -> uint {
d.read_uint()
}
fn serialize_u8<S: serializer>(s: S, v: u8) {
s.emit_u8(v);
}
fn deserialize_u8<D: deserializer>(d: D) -> u8 {
d.read_u8()
}
fn serialize_u16<S: serializer>(s: S, v: u16) {
s.emit_u16(v);
}
fn deserialize_u16<D: deserializer>(d: D) -> u16 {
d.read_u16()
}
fn serialize_u32<S: serializer>(s: S, v: u32) {
s.emit_u32(v);
}
fn deserialize_u32<D: deserializer>(d: D) -> u32 {
d.read_u32()
}
fn serialize_u64<S: serializer>(s: S, v: u64) {
s.emit_u64(v);
}
fn deserialize_u64<D: deserializer>(d: D) -> u64 {
d.read_u64()
}
fn serialize_int<S: serializer>(s: S, v: int) {
s.emit_int(v);
}
fn deserialize_int<D: deserializer>(d: D) -> int {
d.read_int()
}
fn serialize_i8<S: serializer>(s: S, v: i8) {
s.emit_i8(v);
}
fn deserialize_i8<D: deserializer>(d: D) -> i8 {
d.read_i8()
}
fn serialize_i16<S: serializer>(s: S, v: i16) {
s.emit_i16(v);
}
fn deserialize_i16<D: deserializer>(d: D) -> i16 {
d.read_i16()
}
fn serialize_i32<S: serializer>(s: S, v: i32) {
s.emit_i32(v);
}
fn deserialize_i32<D: deserializer>(d: D) -> i32 {
d.read_i32()
}
fn serialize_i64<S: serializer>(s: S, v: i64) {
s.emit_i64(v);
}
fn deserialize_i64<D: deserializer>(d: D) -> i64 {
d.read_i64()
}
fn serialize_str<S: serializer>(s: S, v: str) {
s.emit_str(v);
}
fn deserialize_str<D: deserializer>(d: D) -> str {
d.read_str()
}
fn serialize_float<S: serializer>(s: S, v: float) {
s.emit_float(v);
}
fn deserialize_float<D: deserializer>(d: D) -> float {
d.read_float()
}
fn serialize_f32<S: serializer>(s: S, v: f32) {
s.emit_f32(v);
}
fn deserialize_f32<D: deserializer>(d: D) -> f32 {
d.read_f32()
}
fn serialize_f64<S: serializer>(s: S, v: f64) {
s.emit_f64(v);
}
fn deserialize_f64<D: deserializer>(d: D) -> f64 {
d.read_f64()
}
fn serialize_bool<S: serializer>(s: S, v: bool) {
s.emit_bool(v);
}
fn deserialize_bool<D: deserializer>(d: D) -> bool {
d.read_bool()
}
fn serialize_option<S: serializer,T>(s: S, v: option<T>, 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: deserializer,T>(d: D, st: fn() -> T) -> option<T> {
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()
})
}
}
}
}
}

View File

@@ -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: S, _v: span) {
// FIXME-- serialize some span info
}
fn deserialize_span<D>(_d: D) -> span {
ast_util::dummy_sp()
}
/*#[auto_serialize]*/
type spanned<T> = {node: T, span: span};
/*#[auto_serialize]*/
type ident = str;
// Functions may or may not have names.
/*#[auto_serialize]*/
type fn_ident = option<ident>;
/*#[auto_serialize]*/
type path_ = {global: bool, idents: [ident], types: [@ty]};
/*#[auto_serialize]*/
type path = spanned<path_>;
/*#[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<crate_directive_>;
/*#[auto_serialize]*/
type meta_item = spanned<meta_item_>;
/*#[auto_serialize]*/
enum meta_item_ {
meta_word(ident),
meta_list(ident, [@meta_item]),
meta_name_value(ident, lit),
}
/*#[auto_serialize]*/
type blk = spanned<blk_>;
/*#[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<T> {
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<rmode>;
/*#[auto_serialize]*/
type stmt = spanned<stmt_>;
/*#[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<initializer>, id: node_id};
/*#[auto_serialize]*/
type local = spanned<local_>;
/*#[auto_serialize]*/
type decl = spanned<decl_>;
/*#[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<field_>;
/*#[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<mac_>;
/*#[auto_serialize]*/
type mac_arg = option<@expr>;
/*#[auto_serialize]*/
type mac_body_ = {span: span};
/*#[auto_serialize]*/
type mac_body = option<mac_body_>;
/*#[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<lit_>;
/*#[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<ty_field_>;
/*#[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_<T> { carg_base, carg_ident(T), carg_lit(@lit), }
/*#[auto_serialize]*/
type fn_constr_arg = constr_arg_general_<uint>;
/*#[auto_serialize]*/
type sp_constr_arg<T> = spanned<constr_arg_general_<T>>;
/*#[auto_serialize]*/
type ty_constr_arg = sp_constr_arg<@path>;
/*#[auto_serialize]*/
type constr_arg = spanned<fn_constr_arg>;
// Constrained types' args are parameterized by paths, since
@@ -394,22 +492,34 @@ type constr_arg = spanned<fn_constr_arg>;
// 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_<ARG, ID> =
{path: @path, args: [@spanned<constr_arg_general_<ARG>>], 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<ARG> = spanned<constr_general_<ARG, node_id>>;
/*#[auto_serialize]*/
type constr_ = constr_general_<uint, node_id>;
/*#[auto_serialize]*/
type constr = spanned<constr_general_<uint, node_id>>;
/*#[auto_serialize]*/
type ty_constr_ = constr_general_<@path, node_id>;
/*#[auto_serialize]*/
type ty_constr = spanned<ty_constr_>;
/* 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<variant_>;
// 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<path_list_ident_>;
/*#[auto_serialize]*/
type view_path = spanned<view_path_>;
/*#[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<view_item_>;
/*#[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<attribute_>;
// 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<class_item_>;
/*#[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<class_ctor_>;
/*#[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)

View File

@@ -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, _))
]
}

View File

@@ -63,6 +63,15 @@ type uint_vec = [uint];
#[auto_serialize]
type point = {x: uint, y: uint};
#[auto_serialize]
enum quark<T> {
top(T),
bottom(T)
}
#[auto_serialize]
type uint_quark = quark<uint>;
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(_, _));
}