diff options
| author | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2012-10-13 09:11:33 -0700 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-10-15 08:25:23 -0700 |
| commit | ab89b5c294ac511d4d58809f9f20dfe4f2c8fe52 (patch) | |
| tree | e1374cc163794698bda233cdba3b32416820ab7b /src/libsyntax | |
| parent | 07edf9036715bde27cc7bbc0feb3ee6e461130da (diff) | |
| download | rust-ab89b5c294ac511d4d58809f9f20dfe4f2c8fe52.tar.gz rust-ab89b5c294ac511d4d58809f9f20dfe4f2c8fe52.zip | |
libstd: make Serializer a trait-level typaram
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 49 | ||||
| -rw-r--r-- | src/libsyntax/ext/auto_serialize.rs | 143 |
2 files changed, 136 insertions, 56 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 3740557b7f8..cf7b758216b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -7,17 +7,34 @@ use std::serialization::{Serializable, use codemap::{span, filename}; use parse::token; +#[cfg(stage0)] impl span: Serializable { /* Note #1972 -- spans are serialized but not deserialized */ fn serialize<S: Serializer>(&self, _s: &S) { } } +#[cfg(stage0)] impl span: Deserializable { static fn deserialize<D: Deserializer>(_d: &D) -> span { ast_util::dummy_sp() } } +#[cfg(stage1)] +#[cfg(stage2)] +impl<S: Serializer> span: Serializable<S> { + /* Note #1972 -- spans are serialized but not deserialized */ + fn serialize(&self, _s: &S) { } +} + +#[cfg(stage1)] +#[cfg(stage2)] +impl<D: Deserializer> span: Deserializable<D> { + static fn deserialize(_d: &D) -> span { + ast_util::dummy_sp() + } +} + #[auto_serialize] #[auto_deserialize] type spanned<T> = {node: T, span: span}; @@ -34,6 +51,7 @@ macro_rules! interner_key ( // implemented. struct ident { repr: uint } +#[cfg(stage0)] impl ident: Serializable { fn serialize<S: Serializer>(&self, s: &S) { let intr = match unsafe { @@ -47,6 +65,7 @@ impl ident: Serializable { } } +#[cfg(stage0)] impl ident: Deserializable { static fn deserialize<D: Deserializer>(d: &D) -> ident { let intr = match unsafe { @@ -60,6 +79,36 @@ impl ident: Deserializable { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl<S: Serializer> ident: Serializable<S> { + fn serialize(&self, s: &S) { + let intr = match unsafe { + task::local_data::local_data_get(interner_key!()) + } { + None => fail ~"serialization: TLS interner not set up", + Some(intr) => intr + }; + + s.emit_owned_str(*(*intr).get(*self)); + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +impl<D: Deserializer> ident: Deserializable<D> { + static fn deserialize(d: &D) -> ident { + let intr = match unsafe { + task::local_data::local_data_get(interner_key!()) + } { + None => fail ~"deserialization: TLS interner not set up", + Some(intr) => intr + }; + + (*intr).intern(@d.read_owned_str()) + } +} + impl ident: cmp::Eq { pure fn eq(other: &ident) -> bool { self.repr == other.repr } pure fn ne(other: &ident) -> bool { !self.eq(other) } diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index b06536f4e02..452becbe559 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -13,16 +13,16 @@ For example, a type like: would generate two implementations like: - impl Node: Serializable { - fn serialize<S: Serializer>(s: &S) { + impl<S: Serializer> node_id: Serializable<S> { + fn serialize(s: &S) { do s.emit_struct("Node") { s.emit_field("id", 0, || s.emit_uint(self)) } } } - impl node_id: Deserializable { - static fn deserialize<D: Deserializer>(d: &D) -> Node { + impl<D: Deserializer> node_id: Deserializable { + static fn deserialize(d: &D) -> Node { do d.read_struct("Node") { Node { id: d.read_field(~"x", 0, || deserialize(d)) @@ -40,7 +40,10 @@ references other non-built-in types. A type definition like: would yield functions like: - impl<T: Serializable> spanned<T>: Serializable { + impl< + S: Serializer, + T: Serializable<S> + > spanned<T>: Serializable<S> { fn serialize<S: Serializer>(s: &S) { do s.emit_rec { s.emit_field("node", 0, || self.node.serialize(s)); @@ -49,8 +52,11 @@ would yield functions like: } } - impl<T: Deserializable> spanned<T>: Deserializable { - static fn deserialize<D: Deserializer>(d: &D) -> spanned<T> { + impl< + D: Deserializer, + T: Deserializable<D> + > spanned<T>: Deserializable<D> { + static fn deserialize(d: &D) -> spanned<T> { do d.read_rec { { node: d.read_field(~"node", 0, || deserialize(d)), @@ -215,6 +221,25 @@ fn expand_auto_deserialize( } priv impl ext_ctxt { + fn bind_path( + span: span, + ident: ast::ident, + path: @ast::path, + bounds: @~[ast::ty_param_bound] + ) -> ast::ty_param { + let bound = ast::bound_trait(@{ + id: self.next_id(), + node: ast::ty_path(path, self.next_id()), + span: span, + }); + + { + ident: ident, + id: self.next_id(), + bounds: @vec::append(~[bound], *bounds) + } + } + fn expr(span: span, node: ast::expr_) -> @ast::expr { @{id: self.next_id(), callee_id: self.next_id(), node: node, span: span} @@ -332,24 +357,28 @@ fn mk_impl( cx: ext_ctxt, span: span, ident: ast::ident, + ty_param: ast::ty_param, path: @ast::path, tps: ~[ast::ty_param], f: fn(@ast::ty) -> @ast::method ) -> @ast::item { // All the type parameters need to bound to the trait. - let trait_tps = do tps.map |tp| { - let t_bound = ast::bound_trait(@{ - id: cx.next_id(), - node: ast::ty_path(path, cx.next_id()), - span: span, - }); + let mut trait_tps = vec::append( + ~[ty_param], + do tps.map |tp| { + let t_bound = ast::bound_trait(@{ + id: cx.next_id(), + node: ast::ty_path(path, cx.next_id()), + span: span, + }); - { - ident: tp.ident, - id: cx.next_id(), - bounds: @vec::append(~[t_bound], *tp.bounds) + { + ident: tp.ident, + id: cx.next_id(), + bounds: @vec::append(~[t_bound], *tp.bounds) + } } - }; + ); let opt_trait = Some(@{ path: path, @@ -382,20 +411,37 @@ fn mk_ser_impl( tps: ~[ast::ty_param], body: @ast::expr ) -> @ast::item { + // Make a path to the std::serialization::Serializable typaram. + let ty_param = cx.bind_path( + span, + cx.ident_of(~"__S"), + cx.path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"Serializer"), + ] + ), + @~[] + ); + // Make a path to the std::serialization::Serializable trait. - let path = cx.path( + let path = cx.path_tps( span, ~[ cx.ident_of(~"std"), cx.ident_of(~"serialization"), cx.ident_of(~"Serializable"), - ] + ], + ~[cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[])] ); mk_impl( cx, span, ident, + ty_param, path, tps, |_ty| mk_ser_method(cx, span, cx.expr_blk(body)) @@ -409,20 +455,37 @@ fn mk_deser_impl( tps: ~[ast::ty_param], body: @ast::expr ) -> @ast::item { + // Make a path to the std::serialization::Deserializable typaram. + let ty_param = cx.bind_path( + span, + cx.ident_of(~"__D"), + cx.path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"Deserializer"), + ] + ), + @~[] + ); + // Make a path to the std::serialization::Deserializable trait. - let path = cx.path( + let path = cx.path_tps( span, ~[ cx.ident_of(~"std"), cx.ident_of(~"serialization"), cx.ident_of(~"Deserializable"), - ] + ], + ~[cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[])] ); mk_impl( cx, span, ident, + ty_param, path, tps, |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body)) @@ -434,22 +497,6 @@ fn mk_ser_method( span: span, ser_body: ast::blk ) -> @ast::method { - let ser_bound = cx.ty_path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Serializer"), - ], - ~[] - ); - - let ser_tps = ~[{ - ident: cx.ident_of(~"__S"), - id: cx.next_id(), - bounds: @~[ast::bound_trait(ser_bound)], - }]; - let ty_s = @{ id: cx.next_id(), node: ast::ty_rptr( @@ -487,7 +534,7 @@ fn mk_ser_method( @{ ident: cx.ident_of(~"serialize"), attrs: ~[], - tps: ser_tps, + tps: ~[], self_ty: { node: ast::sty_region(ast::m_imm), span: span }, purity: ast::impure_fn, decl: ser_decl, @@ -505,22 +552,6 @@ fn mk_deser_method( ty: @ast::ty, deser_body: ast::blk ) -> @ast::method { - let deser_bound = cx.ty_path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Deserializer"), - ], - ~[] - ); - - let deser_tps = ~[{ - ident: cx.ident_of(~"__D"), - id: cx.next_id(), - bounds: @~[ast::bound_trait(deser_bound)], - }]; - let ty_d = @{ id: cx.next_id(), node: ast::ty_rptr( @@ -552,7 +583,7 @@ fn mk_deser_method( @{ ident: cx.ident_of(~"deserialize"), attrs: ~[], - tps: deser_tps, + tps: ~[], self_ty: { node: ast::sty_static, span: span }, purity: ast::impure_fn, decl: deser_decl, |
