auto merge of #5141 : nikomatsakis/rust/region-syntax-expl-lifetimes, r=nikomatsakis
Major changes are: - replace ~[ty_param] with Generics structure, which includes both OptVec<TyParam> and OptVec<Lifetime>; - the use of syntax::opt_vec to avoid allocation for empty lists; cc #4846 r? @graydon
This commit is contained in:
commit
d0a12347de
34 changed files with 1070 additions and 722 deletions
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*
|
||||
/*!
|
||||
|
||||
The compiler code necessary to implement the #[auto_encode] and
|
||||
#[auto_decode] extension. The idea here is that type-defining items may
|
||||
|
|
@ -96,6 +96,9 @@ use attr;
|
|||
use codemap::span;
|
||||
use ext::base::*;
|
||||
use parse;
|
||||
use opt_vec;
|
||||
use opt_vec::OptVec;
|
||||
use ext::build;
|
||||
|
||||
use core::vec;
|
||||
use std::oldmap;
|
||||
|
|
@ -127,24 +130,24 @@ pub fn expand_auto_encode(
|
|||
do vec::flat_map(in_items) |item| {
|
||||
if item.attrs.any(is_auto_encode) {
|
||||
match item.node {
|
||||
ast::item_struct(ref struct_def, ref tps) => {
|
||||
ast::item_struct(ref struct_def, ref generics) => {
|
||||
let ser_impl = mk_struct_ser_impl(
|
||||
cx,
|
||||
item.span,
|
||||
item.ident,
|
||||
struct_def.fields,
|
||||
*tps
|
||||
generics
|
||||
);
|
||||
|
||||
~[filter_attrs(*item), ser_impl]
|
||||
},
|
||||
ast::item_enum(ref enum_def, ref tps) => {
|
||||
ast::item_enum(ref enum_def, ref generics) => {
|
||||
let ser_impl = mk_enum_ser_impl(
|
||||
cx,
|
||||
item.span,
|
||||
item.ident,
|
||||
*enum_def,
|
||||
*tps
|
||||
generics
|
||||
);
|
||||
|
||||
~[filter_attrs(*item), ser_impl]
|
||||
|
|
@ -182,24 +185,24 @@ pub fn expand_auto_decode(
|
|||
do vec::flat_map(in_items) |item| {
|
||||
if item.attrs.any(is_auto_decode) {
|
||||
match item.node {
|
||||
ast::item_struct(ref struct_def, ref tps) => {
|
||||
ast::item_struct(ref struct_def, ref generics) => {
|
||||
let deser_impl = mk_struct_deser_impl(
|
||||
cx,
|
||||
item.span,
|
||||
item.ident,
|
||||
struct_def.fields,
|
||||
*tps
|
||||
generics
|
||||
);
|
||||
|
||||
~[filter_attrs(*item), deser_impl]
|
||||
},
|
||||
ast::item_enum(ref enum_def, ref tps) => {
|
||||
ast::item_enum(ref enum_def, ref generics) => {
|
||||
let deser_impl = mk_enum_deser_impl(
|
||||
cx,
|
||||
item.span,
|
||||
item.ident,
|
||||
*enum_def,
|
||||
*tps
|
||||
generics
|
||||
);
|
||||
|
||||
~[filter_attrs(*item), deser_impl]
|
||||
|
|
@ -222,18 +225,18 @@ priv impl ext_ctxt {
|
|||
span: span,
|
||||
ident: ast::ident,
|
||||
path: @ast::path,
|
||||
bounds: @~[ast::ty_param_bound]
|
||||
) -> ast::ty_param {
|
||||
bounds: @OptVec<ast::TyParamBound>
|
||||
) -> ast::TyParam {
|
||||
let bound = ast::TraitTyParamBound(@ast::Ty {
|
||||
id: self.next_id(),
|
||||
node: ast::ty_path(path, self.next_id()),
|
||||
span: span,
|
||||
});
|
||||
|
||||
ast::ty_param {
|
||||
ast::TyParam {
|
||||
ident: ident,
|
||||
id: self.next_id(),
|
||||
bounds: @vec::append(~[bound], *bounds)
|
||||
bounds: @bounds.prepend(bound)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -408,28 +411,45 @@ fn mk_impl(
|
|||
cx: ext_ctxt,
|
||||
span: span,
|
||||
ident: ast::ident,
|
||||
ty_param: ast::ty_param,
|
||||
ty_param: ast::TyParam,
|
||||
path: @ast::path,
|
||||
tps: &[ast::ty_param],
|
||||
generics: &ast::Generics,
|
||||
f: fn(@ast::Ty) -> @ast::method
|
||||
) -> @ast::item {
|
||||
// All the type parameters need to bound to the trait.
|
||||
let mut trait_tps = vec::append(
|
||||
~[ty_param],
|
||||
do tps.map |tp| {
|
||||
let t_bound = ast::TraitTyParamBound(@ast::Ty {
|
||||
id: cx.next_id(),
|
||||
node: ast::ty_path(path, cx.next_id()),
|
||||
span: span,
|
||||
});
|
||||
/*!
|
||||
*
|
||||
* Given that we are deriving auto-encode a type `T<'a, ...,
|
||||
* 'z, A, ..., Z>`, creates an impl like:
|
||||
*
|
||||
* impl<'a, ..., 'z, A:Tr, ..., Z:Tr> Tr for T<A, ..., Z> { ... }
|
||||
*
|
||||
* where Tr is either Serializable and Deserialize.
|
||||
*
|
||||
* FIXME(#5090): Remove code duplication between this and the code
|
||||
* in deriving.rs
|
||||
*/
|
||||
|
||||
ast::ty_param {
|
||||
ident: tp.ident,
|
||||
id: cx.next_id(),
|
||||
bounds: @vec::append(~[t_bound], *tp.bounds)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Copy the lifetimes
|
||||
let impl_lifetimes = generics.lifetimes.map(|l| {
|
||||
build::mk_lifetime(cx, l.span, l.ident)
|
||||
});
|
||||
|
||||
// All the type parameters need to bound to the trait.
|
||||
let mut impl_tps = opt_vec::with(ty_param);
|
||||
for generics.ty_params.each |tp| {
|
||||
let t_bound = ast::TraitTyParamBound(@ast::Ty {
|
||||
id: cx.next_id(),
|
||||
node: ast::ty_path(path, cx.next_id()),
|
||||
span: span,
|
||||
});
|
||||
|
||||
impl_tps.push(ast::TyParam {
|
||||
ident: tp.ident,
|
||||
id: cx.next_id(),
|
||||
bounds: @tp.bounds.prepend(t_bound)
|
||||
})
|
||||
}
|
||||
|
||||
let opt_trait = Some(@ast::trait_ref {
|
||||
path: path,
|
||||
|
|
@ -439,16 +459,22 @@ fn mk_impl(
|
|||
let ty = cx.ty_path(
|
||||
span,
|
||||
~[ident],
|
||||
tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[]))
|
||||
generics.ty_params.map(
|
||||
|tp| cx.ty_path(span, ~[tp.ident], ~[])).to_vec()
|
||||
);
|
||||
|
||||
let generics = ast::Generics {
|
||||
lifetimes: impl_lifetimes,
|
||||
ty_params: impl_tps
|
||||
};
|
||||
|
||||
@ast::item {
|
||||
// This is a new-style impl declaration.
|
||||
// XXX: clownshoes
|
||||
ident: parse::token::special_idents::clownshoes_extensions,
|
||||
attrs: ~[],
|
||||
id: cx.next_id(),
|
||||
node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]),
|
||||
node: ast::item_impl(generics, opt_trait, ty, ~[f(ty)]),
|
||||
vis: ast::public,
|
||||
span: span,
|
||||
}
|
||||
|
|
@ -458,7 +484,7 @@ fn mk_ser_impl(
|
|||
cx: ext_ctxt,
|
||||
span: span,
|
||||
ident: ast::ident,
|
||||
tps: &[ast::ty_param],
|
||||
generics: &ast::Generics,
|
||||
body: @ast::expr
|
||||
) -> @ast::item {
|
||||
// Make a path to the std::serialize::Encodable typaram.
|
||||
|
|
@ -473,7 +499,7 @@ fn mk_ser_impl(
|
|||
cx.ident_of(~"Encoder"),
|
||||
]
|
||||
),
|
||||
@~[]
|
||||
@opt_vec::Empty
|
||||
);
|
||||
|
||||
// Make a path to the std::serialize::Encodable trait.
|
||||
|
|
@ -493,7 +519,7 @@ fn mk_ser_impl(
|
|||
ident,
|
||||
ty_param,
|
||||
path,
|
||||
tps,
|
||||
generics,
|
||||
|_ty| mk_ser_method(cx, span, cx.expr_blk(body))
|
||||
)
|
||||
}
|
||||
|
|
@ -502,7 +528,7 @@ fn mk_deser_impl(
|
|||
cx: ext_ctxt,
|
||||
span: span,
|
||||
ident: ast::ident,
|
||||
tps: ~[ast::ty_param],
|
||||
generics: &ast::Generics,
|
||||
body: @ast::expr
|
||||
) -> @ast::item {
|
||||
// Make a path to the std::serialize::Decodable typaram.
|
||||
|
|
@ -517,7 +543,7 @@ fn mk_deser_impl(
|
|||
cx.ident_of(~"Decoder"),
|
||||
]
|
||||
),
|
||||
@~[]
|
||||
@opt_vec::Empty
|
||||
);
|
||||
|
||||
// Make a path to the std::serialize::Decodable trait.
|
||||
|
|
@ -537,7 +563,7 @@ fn mk_deser_impl(
|
|||
ident,
|
||||
ty_param,
|
||||
path,
|
||||
tps,
|
||||
generics,
|
||||
|ty| mk_deser_method(cx, span, ty, cx.expr_blk(body))
|
||||
)
|
||||
}
|
||||
|
|
@ -592,7 +618,7 @@ fn mk_ser_method(
|
|||
@ast::method {
|
||||
ident: cx.ident_of(~"encode"),
|
||||
attrs: ~[],
|
||||
tps: ~[],
|
||||
generics: ast_util::empty_generics(),
|
||||
self_ty: codemap::spanned { node: ast::sty_region(ast::m_imm),
|
||||
span: span },
|
||||
purity: ast::impure_fn,
|
||||
|
|
@ -650,7 +676,7 @@ fn mk_deser_method(
|
|||
@ast::method {
|
||||
ident: cx.ident_of(~"decode"),
|
||||
attrs: ~[],
|
||||
tps: ~[],
|
||||
generics: ast_util::empty_generics(),
|
||||
self_ty: codemap::spanned { node: ast::sty_static, span: span },
|
||||
purity: ast::impure_fn,
|
||||
decl: deser_decl,
|
||||
|
|
@ -667,7 +693,7 @@ fn mk_struct_ser_impl(
|
|||
span: span,
|
||||
ident: ast::ident,
|
||||
fields: &[@ast::struct_field],
|
||||
tps: &[ast::ty_param]
|
||||
generics: &ast::Generics
|
||||
) -> @ast::item {
|
||||
let fields = do mk_struct_fields(fields).mapi |idx, field| {
|
||||
// ast for `|| self.$(name).encode(__s)`
|
||||
|
|
@ -720,7 +746,7 @@ fn mk_struct_ser_impl(
|
|||
]
|
||||
);
|
||||
|
||||
mk_ser_impl(cx, span, ident, tps, ser_body)
|
||||
mk_ser_impl(cx, span, ident, generics, ser_body)
|
||||
}
|
||||
|
||||
fn mk_struct_deser_impl(
|
||||
|
|
@ -728,7 +754,7 @@ fn mk_struct_deser_impl(
|
|||
span: span,
|
||||
ident: ast::ident,
|
||||
fields: ~[@ast::struct_field],
|
||||
tps: ~[ast::ty_param]
|
||||
generics: &ast::Generics
|
||||
) -> @ast::item {
|
||||
let fields = do mk_struct_fields(fields).mapi |idx, field| {
|
||||
// ast for `|| std::serialize::decode(__d)`
|
||||
|
|
@ -796,7 +822,7 @@ fn mk_struct_deser_impl(
|
|||
]
|
||||
);
|
||||
|
||||
mk_deser_impl(cx, span, ident, tps, body)
|
||||
mk_deser_impl(cx, span, ident, generics, body)
|
||||
}
|
||||
|
||||
// Records and structs don't have the same fields types, but they share enough
|
||||
|
|
@ -832,7 +858,7 @@ fn mk_enum_ser_impl(
|
|||
span: span,
|
||||
ident: ast::ident,
|
||||
enum_def: ast::enum_def,
|
||||
tps: ~[ast::ty_param]
|
||||
generics: &ast::Generics
|
||||
) -> @ast::item {
|
||||
let body = mk_enum_ser_body(
|
||||
cx,
|
||||
|
|
@ -841,7 +867,7 @@ fn mk_enum_ser_impl(
|
|||
enum_def.variants
|
||||
);
|
||||
|
||||
mk_ser_impl(cx, span, ident, tps, body)
|
||||
mk_ser_impl(cx, span, ident, generics, body)
|
||||
}
|
||||
|
||||
fn mk_enum_deser_impl(
|
||||
|
|
@ -849,7 +875,7 @@ fn mk_enum_deser_impl(
|
|||
span: span,
|
||||
ident: ast::ident,
|
||||
enum_def: ast::enum_def,
|
||||
tps: ~[ast::ty_param]
|
||||
generics: &ast::Generics
|
||||
) -> @ast::item {
|
||||
let body = mk_enum_deser_body(
|
||||
cx,
|
||||
|
|
@ -858,7 +884,7 @@ fn mk_enum_deser_impl(
|
|||
enum_def.variants
|
||||
);
|
||||
|
||||
mk_deser_impl(cx, span, ident, tps, body)
|
||||
mk_deser_impl(cx, span, ident, generics, body)
|
||||
}
|
||||
|
||||
fn ser_variant(
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ use codemap::span;
|
|||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
|
||||
use opt_vec;
|
||||
use opt_vec::OptVec;
|
||||
|
||||
use core::dvec;
|
||||
use core::option;
|
||||
|
||||
|
|
@ -354,8 +357,14 @@ pub fn mk_fn_decl(+inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl {
|
|||
}
|
||||
pub fn mk_ty_param(cx: ext_ctxt,
|
||||
ident: ast::ident,
|
||||
bounds: @~[ast::ty_param_bound])
|
||||
-> ast::ty_param {
|
||||
ast::ty_param { ident: ident, id: cx.next_id(), bounds: bounds }
|
||||
bounds: @OptVec<ast::TyParamBound>)
|
||||
-> ast::TyParam {
|
||||
ast::TyParam { ident: ident, id: cx.next_id(), bounds: bounds }
|
||||
}
|
||||
pub fn mk_lifetime(cx: ext_ctxt,
|
||||
span: span,
|
||||
ident: ast::ident) -> ast::Lifetime
|
||||
{
|
||||
ast::Lifetime { id: cx.next_id(), span: span, ident: ident }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,15 +16,19 @@ use core::prelude::*;
|
|||
use ast;
|
||||
use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
|
||||
use ast::{enum_variant_kind, expr, expr_match, ident, item, item_};
|
||||
use ast::{item_enum, item_impl, item_struct, m_imm, meta_item, method};
|
||||
use ast::{item_enum, item_impl, item_struct, Generics};
|
||||
use ast::{m_imm, meta_item, method};
|
||||
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
||||
use ast::{re_anon, stmt, struct_def, struct_variant_kind};
|
||||
use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, ty_param};
|
||||
use ast::{ty_param_bound, ty_path, ty_rptr, unnamed_field, variant};
|
||||
use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam};
|
||||
use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
|
||||
use ext::base::ext_ctxt;
|
||||
use ext::build;
|
||||
use codemap::{span, spanned};
|
||||
use parse::token::special_idents::clownshoes_extensions;
|
||||
use ast_util;
|
||||
use opt_vec;
|
||||
use opt_vec::OptVec;
|
||||
|
||||
use core::dvec;
|
||||
use core::uint;
|
||||
|
|
@ -47,13 +51,13 @@ type ExpandDerivingStructDefFn = &fn(ext_ctxt,
|
|||
span,
|
||||
x: &struct_def,
|
||||
ident,
|
||||
+y: ~[ty_param])
|
||||
y: &Generics)
|
||||
-> @item;
|
||||
type ExpandDerivingEnumDefFn = &fn(ext_ctxt,
|
||||
span,
|
||||
x: &enum_def,
|
||||
ident,
|
||||
+y: ~[ty_param])
|
||||
y: &Generics)
|
||||
-> @item;
|
||||
|
||||
pub fn expand_deriving_eq(cx: ext_ctxt,
|
||||
|
|
@ -90,19 +94,19 @@ fn expand_deriving(cx: ext_ctxt,
|
|||
for in_items.each |item| {
|
||||
result.push(copy *item);
|
||||
match item.node {
|
||||
item_struct(struct_def, copy ty_params) => {
|
||||
item_struct(struct_def, ref generics) => {
|
||||
result.push(expand_deriving_struct_def(cx,
|
||||
span,
|
||||
struct_def,
|
||||
item.ident,
|
||||
ty_params));
|
||||
generics));
|
||||
}
|
||||
item_enum(ref enum_definition, copy ty_params) => {
|
||||
item_enum(ref enum_definition, ref generics) => {
|
||||
result.push(expand_deriving_enum_def(cx,
|
||||
span,
|
||||
enum_definition,
|
||||
item.ident,
|
||||
ty_params));
|
||||
generics));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
|
@ -127,14 +131,14 @@ fn create_eq_method(cx: ext_ctxt,
|
|||
span: span,
|
||||
method_ident: ident,
|
||||
type_ident: ident,
|
||||
ty_params: &[ty_param],
|
||||
generics: &Generics,
|
||||
body: @expr)
|
||||
-> @method {
|
||||
// Create the type of the `other` parameter.
|
||||
let arg_path_type = create_self_type_with_params(cx,
|
||||
span,
|
||||
type_ident,
|
||||
ty_params);
|
||||
generics);
|
||||
let arg_region = @ast::region { id: cx.next_id(), node: re_anon };
|
||||
let arg_type = ty_rptr(
|
||||
arg_region,
|
||||
|
|
@ -171,7 +175,7 @@ fn create_eq_method(cx: ext_ctxt,
|
|||
@ast::method {
|
||||
ident: method_ident,
|
||||
attrs: ~[],
|
||||
tps: ~[],
|
||||
generics: ast_util::empty_generics(),
|
||||
self_ty: self_ty,
|
||||
purity: pure_fn,
|
||||
decl: fn_decl,
|
||||
|
|
@ -186,11 +190,11 @@ fn create_eq_method(cx: ext_ctxt,
|
|||
fn create_self_type_with_params(cx: ext_ctxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
ty_params: &[ty_param])
|
||||
generics: &Generics)
|
||||
-> @Ty {
|
||||
// Create the type parameters on the `self` path.
|
||||
let self_ty_params = dvec::DVec();
|
||||
for ty_params.each |ty_param| {
|
||||
for generics.ty_params.each |ty_param| {
|
||||
let self_ty_param = build::mk_simple_ty_path(cx,
|
||||
span,
|
||||
ty_param.ident);
|
||||
|
|
@ -209,21 +213,34 @@ fn create_self_type_with_params(cx: ext_ctxt,
|
|||
fn create_derived_impl(cx: ext_ctxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param],
|
||||
generics: &Generics,
|
||||
methods: &[@method],
|
||||
trait_path: &[ident])
|
||||
-> @item {
|
||||
/*!
|
||||
*
|
||||
* Given that we are deriving a trait `Tr` for a type `T<'a, ...,
|
||||
* 'z, A, ..., Z>`, creates an impl like:
|
||||
*
|
||||
* impl<'a, ..., 'z, A:Tr, ..., Z: Tr> Tr for T<A, ..., Z> { ... }
|
||||
*
|
||||
* FIXME(#5090): Remove code duplication between this and the
|
||||
* code in auto_encode.rs
|
||||
*/
|
||||
|
||||
// Copy the lifetimes
|
||||
let impl_lifetimes = generics.lifetimes.map(|l| {
|
||||
build::mk_lifetime(cx, l.span, l.ident)
|
||||
});
|
||||
|
||||
// Create the type parameters.
|
||||
let impl_ty_params = dvec::DVec();
|
||||
for ty_params.each |ty_param| {
|
||||
let impl_ty_params = generics.ty_params.map(|ty_param| {
|
||||
let bound = build::mk_ty_path_global(cx,
|
||||
span,
|
||||
trait_path.map(|x| *x));
|
||||
let bounds = @~[ TraitTyParamBound(bound) ];
|
||||
let impl_ty_param = build::mk_ty_param(cx, ty_param.ident, bounds);
|
||||
impl_ty_params.push(impl_ty_param);
|
||||
}
|
||||
let impl_ty_params = dvec::unwrap(impl_ty_params);
|
||||
let bounds = @opt_vec::with(TraitTyParamBound(bound));
|
||||
build::mk_ty_param(cx, ty_param.ident, bounds)
|
||||
});
|
||||
|
||||
// Create the reference to the trait.
|
||||
let trait_path = ast::path {
|
||||
|
|
@ -244,10 +261,11 @@ fn create_derived_impl(cx: ext_ctxt,
|
|||
let self_type = create_self_type_with_params(cx,
|
||||
span,
|
||||
type_ident,
|
||||
ty_params);
|
||||
generics);
|
||||
|
||||
// Create the impl item.
|
||||
let impl_item = item_impl(impl_ty_params,
|
||||
let impl_item = item_impl(Generics {lifetimes: impl_lifetimes,
|
||||
ty_params: impl_ty_params},
|
||||
Some(trait_ref),
|
||||
self_type,
|
||||
methods.map(|x| *x));
|
||||
|
|
@ -257,7 +275,7 @@ fn create_derived_impl(cx: ext_ctxt,
|
|||
fn create_derived_eq_impl(cx: ext_ctxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param],
|
||||
generics: &Generics,
|
||||
eq_method: @method,
|
||||
ne_method: @method)
|
||||
-> @item {
|
||||
|
|
@ -267,13 +285,13 @@ fn create_derived_eq_impl(cx: ext_ctxt,
|
|||
cx.ident_of(~"cmp"),
|
||||
cx.ident_of(~"Eq")
|
||||
];
|
||||
create_derived_impl(cx, span, type_ident, ty_params, methods, trait_path)
|
||||
create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
|
||||
}
|
||||
|
||||
fn create_derived_iter_bytes_impl(cx: ext_ctxt,
|
||||
span: span,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param],
|
||||
generics: &Generics,
|
||||
method: @method)
|
||||
-> @item {
|
||||
let methods = [ method ];
|
||||
|
|
@ -282,7 +300,7 @@ fn create_derived_iter_bytes_impl(cx: ext_ctxt,
|
|||
cx.ident_of(~"to_bytes"),
|
||||
cx.ident_of(~"IterBytes")
|
||||
];
|
||||
create_derived_impl(cx, span, type_ident, ty_params, methods, trait_path)
|
||||
create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
|
||||
}
|
||||
|
||||
// Creates a method from the given set of statements conforming to the
|
||||
|
|
@ -322,7 +340,7 @@ fn create_iter_bytes_method(cx: ext_ctxt,
|
|||
@ast::method {
|
||||
ident: method_ident,
|
||||
attrs: ~[],
|
||||
tps: ~[],
|
||||
generics: ast_util::empty_generics(),
|
||||
self_ty: self_ty,
|
||||
purity: pure_fn,
|
||||
decl: fn_decl,
|
||||
|
|
@ -484,7 +502,7 @@ fn expand_deriving_eq_struct_def(cx: ext_ctxt,
|
|||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param])
|
||||
generics: &Generics)
|
||||
-> @item {
|
||||
// Create the methods.
|
||||
let eq_ident = cx.ident_of(~"eq");
|
||||
|
|
@ -510,21 +528,21 @@ fn expand_deriving_eq_struct_def(cx: ext_ctxt,
|
|||
struct_def,
|
||||
eq_ident,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
Conjunction);
|
||||
let ne_method = derive_struct_fn(cx,
|
||||
span,
|
||||
struct_def,
|
||||
ne_ident,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
Disjunction);
|
||||
|
||||
// Create the implementation.
|
||||
return create_derived_eq_impl(cx,
|
||||
span,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
eq_method,
|
||||
ne_method);
|
||||
}
|
||||
|
|
@ -533,7 +551,7 @@ fn expand_deriving_eq_enum_def(cx: ext_ctxt,
|
|||
span: span,
|
||||
enum_definition: &enum_def,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param])
|
||||
generics: &Generics)
|
||||
-> @item {
|
||||
// Create the methods.
|
||||
let eq_ident = cx.ident_of(~"eq");
|
||||
|
|
@ -543,21 +561,21 @@ fn expand_deriving_eq_enum_def(cx: ext_ctxt,
|
|||
enum_definition,
|
||||
eq_ident,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
Conjunction);
|
||||
let ne_method = expand_deriving_eq_enum_method(cx,
|
||||
span,
|
||||
enum_definition,
|
||||
ne_ident,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
Disjunction);
|
||||
|
||||
// Create the implementation.
|
||||
return create_derived_eq_impl(cx,
|
||||
span,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
eq_method,
|
||||
ne_method);
|
||||
}
|
||||
|
|
@ -566,7 +584,7 @@ fn expand_deriving_iter_bytes_struct_def(cx: ext_ctxt,
|
|||
span: span,
|
||||
struct_def: &struct_def,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param])
|
||||
generics: &Generics)
|
||||
-> @item {
|
||||
// Create the method.
|
||||
let method = expand_deriving_iter_bytes_struct_method(cx,
|
||||
|
|
@ -577,7 +595,7 @@ fn expand_deriving_iter_bytes_struct_def(cx: ext_ctxt,
|
|||
return create_derived_iter_bytes_impl(cx,
|
||||
span,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
method);
|
||||
}
|
||||
|
||||
|
|
@ -585,7 +603,7 @@ fn expand_deriving_iter_bytes_enum_def(cx: ext_ctxt,
|
|||
span: span,
|
||||
enum_definition: &enum_def,
|
||||
type_ident: ident,
|
||||
+ty_params: ~[ty_param])
|
||||
generics: &Generics)
|
||||
-> @item {
|
||||
// Create the method.
|
||||
let method = expand_deriving_iter_bytes_enum_method(cx,
|
||||
|
|
@ -596,7 +614,7 @@ fn expand_deriving_iter_bytes_enum_def(cx: ext_ctxt,
|
|||
return create_derived_iter_bytes_impl(cx,
|
||||
span,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
method);
|
||||
}
|
||||
|
||||
|
|
@ -605,7 +623,7 @@ fn expand_deriving_eq_struct_method(cx: ext_ctxt,
|
|||
struct_def: &struct_def,
|
||||
method_ident: ident,
|
||||
type_ident: ident,
|
||||
ty_params: &[ty_param],
|
||||
generics: &Generics,
|
||||
junction: Junction)
|
||||
-> @method {
|
||||
let self_ident = cx.ident_of(~"self");
|
||||
|
|
@ -652,7 +670,7 @@ fn expand_deriving_eq_struct_method(cx: ext_ctxt,
|
|||
span,
|
||||
method_ident,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
body);
|
||||
}
|
||||
|
||||
|
|
@ -696,7 +714,7 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt,
|
|||
enum_definition: &enum_def,
|
||||
method_ident: ident,
|
||||
type_ident: ident,
|
||||
ty_params: &[ty_param],
|
||||
generics: &Generics,
|
||||
junction: Junction)
|
||||
-> @method {
|
||||
let self_ident = cx.ident_of(~"self");
|
||||
|
|
@ -823,7 +841,7 @@ fn expand_deriving_eq_enum_method(cx: ext_ctxt,
|
|||
span,
|
||||
method_ident,
|
||||
type_ident,
|
||||
ty_params,
|
||||
generics,
|
||||
self_match_expr);
|
||||
}
|
||||
|
||||
|
|
@ -832,7 +850,7 @@ fn expand_deriving_eq_struct_tuple_method(cx: ext_ctxt,
|
|||
struct_def: &struct_def,
|
||||
method_ident: ident,
|
||||
type_ident: ident,
|
||||
ty_params: &[ty_param],
|
||||
generics: &Generics,
|
||||
junction: Junction)
|
||||
-> @method {
|
||||
let self_str = ~"self";
|
||||
|
|
@ -883,7 +901,7 @@ fn expand_deriving_eq_struct_tuple_method(cx: ext_ctxt,
|
|||
let self_match_expr = build::mk_expr(cx, span, self_match_expr);
|
||||
|
||||
create_eq_method(cx, span, method_ident,
|
||||
type_ident, ty_params, self_match_expr)
|
||||
type_ident, generics, self_match_expr)
|
||||
}
|
||||
|
||||
fn expand_deriving_iter_bytes_enum_method(cx: ext_ctxt,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ use codemap::{span, respan, dummy_sp};
|
|||
use codemap;
|
||||
use ext::base::{ext_ctxt, mk_ctxt};
|
||||
use ext::quote::rt::*;
|
||||
use opt_vec;
|
||||
use opt_vec::OptVec;
|
||||
|
||||
use core::vec;
|
||||
|
||||
|
|
@ -67,8 +69,8 @@ impl append_types for @ast::path {
|
|||
}
|
||||
|
||||
pub trait ext_ctxt_ast_builder {
|
||||
fn ty_param(&self, id: ast::ident, +bounds: ~[ast::ty_param_bound])
|
||||
-> ast::ty_param;
|
||||
fn ty_param(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>)
|
||||
-> ast::TyParam;
|
||||
fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg;
|
||||
fn expr_block(&self, e: @ast::expr) -> ast::blk;
|
||||
fn fn_decl(&self, +inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl;
|
||||
|
|
@ -76,7 +78,7 @@ pub trait ext_ctxt_ast_builder {
|
|||
fn item_fn_poly(&self, name: ident,
|
||||
+inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
+ty_params: ~[ast::ty_param],
|
||||
+generics: Generics,
|
||||
+body: ast::blk) -> @ast::item;
|
||||
fn item_fn(&self, name: ident,
|
||||
+inputs: ~[ast::arg],
|
||||
|
|
@ -85,12 +87,12 @@ pub trait ext_ctxt_ast_builder {
|
|||
fn item_enum_poly(&self, name: ident,
|
||||
span: span,
|
||||
+enum_definition: ast::enum_def,
|
||||
+ty_params: ~[ast::ty_param]) -> @ast::item;
|
||||
+generics: Generics) -> @ast::item;
|
||||
fn item_enum(&self, name: ident, span: span,
|
||||
+enum_definition: ast::enum_def) -> @ast::item;
|
||||
fn item_struct_poly(&self, name: ident, span: span,
|
||||
struct_def: ast::struct_def,
|
||||
ty_params: ~[ast::ty_param]) -> @ast::item;
|
||||
+generics: Generics) -> @ast::item;
|
||||
fn item_struct(&self, name: ident, span: span,
|
||||
struct_def: ast::struct_def) -> @ast::item;
|
||||
fn struct_expr(&self, path: @ast::path,
|
||||
|
|
@ -103,10 +105,10 @@ pub trait ext_ctxt_ast_builder {
|
|||
fn item_ty_poly(&self, name: ident,
|
||||
span: span,
|
||||
ty: @ast::Ty,
|
||||
+params: ~[ast::ty_param]) -> @ast::item;
|
||||
+generics: Generics) -> @ast::item;
|
||||
fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item;
|
||||
fn ty_vars(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty];
|
||||
fn ty_vars_global(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty];
|
||||
fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
|
||||
fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
|
||||
fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field;
|
||||
fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field;
|
||||
fn block(&self, +stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk;
|
||||
|
|
@ -116,7 +118,7 @@ pub trait ext_ctxt_ast_builder {
|
|||
fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty;
|
||||
fn ty_infer(&self) -> @ast::Ty;
|
||||
fn ty_nil_ast_builder(&self) -> @ast::Ty;
|
||||
fn strip_bounds(&self, bounds: &[ast::ty_param]) -> ~[ast::ty_param];
|
||||
fn strip_bounds(&self, bounds: &Generics) -> Generics;
|
||||
}
|
||||
|
||||
impl ext_ctxt_ast_builder for ext_ctxt {
|
||||
|
|
@ -172,10 +174,10 @@ impl ext_ctxt_ast_builder for ext_ctxt {
|
|||
}
|
||||
}
|
||||
|
||||
fn ty_param(&self, id: ast::ident, +bounds: ~[ast::ty_param_bound])
|
||||
-> ast::ty_param
|
||||
fn ty_param(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>)
|
||||
-> ast::TyParam
|
||||
{
|
||||
ast::ty_param { ident: id, id: self.next_id(), bounds: @bounds }
|
||||
ast::TyParam { ident: id, id: self.next_id(), bounds: bounds }
|
||||
}
|
||||
|
||||
fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg {
|
||||
|
|
@ -247,13 +249,13 @@ impl ext_ctxt_ast_builder for ext_ctxt {
|
|||
fn item_fn_poly(&self, name: ident,
|
||||
+inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
+ty_params: ~[ast::ty_param],
|
||||
+generics: Generics,
|
||||
+body: ast::blk) -> @ast::item {
|
||||
self.item(name,
|
||||
dummy_sp(),
|
||||
ast::item_fn(self.fn_decl(inputs, output),
|
||||
ast::impure_fn,
|
||||
ty_params,
|
||||
generics,
|
||||
body))
|
||||
}
|
||||
|
||||
|
|
@ -261,29 +263,32 @@ impl ext_ctxt_ast_builder for ext_ctxt {
|
|||
+inputs: ~[ast::arg],
|
||||
output: @ast::Ty,
|
||||
+body: ast::blk) -> @ast::item {
|
||||
self.item_fn_poly(name, inputs, output, ~[], body)
|
||||
self.item_fn_poly(name, inputs, output,
|
||||
ast_util::empty_generics(), body)
|
||||
}
|
||||
|
||||
fn item_enum_poly(&self, name: ident, span: span,
|
||||
+enum_definition: ast::enum_def,
|
||||
+ty_params: ~[ast::ty_param]) -> @ast::item {
|
||||
self.item(name, span, ast::item_enum(enum_definition, ty_params))
|
||||
+generics: Generics) -> @ast::item {
|
||||
self.item(name, span, ast::item_enum(enum_definition, generics))
|
||||
}
|
||||
|
||||
fn item_enum(&self, name: ident, span: span,
|
||||
+enum_definition: ast::enum_def) -> @ast::item {
|
||||
self.item_enum_poly(name, span, enum_definition, ~[])
|
||||
self.item_enum_poly(name, span, enum_definition,
|
||||
ast_util::empty_generics())
|
||||
}
|
||||
|
||||
fn item_struct(&self, name: ident, span: span,
|
||||
struct_def: ast::struct_def) -> @ast::item {
|
||||
self.item_struct_poly(name, span, struct_def, ~[])
|
||||
self.item_struct_poly(name, span, struct_def,
|
||||
ast_util::empty_generics())
|
||||
}
|
||||
|
||||
fn item_struct_poly(&self, name: ident, span: span,
|
||||
struct_def: ast::struct_def,
|
||||
ty_params: ~[ast::ty_param]) -> @ast::item {
|
||||
self.item(name, span, ast::item_struct(@struct_def, ty_params))
|
||||
+generics: Generics) -> @ast::item {
|
||||
self.item(name, span, ast::item_struct(@struct_def, generics))
|
||||
}
|
||||
|
||||
fn struct_expr(&self, path: @ast::path,
|
||||
|
|
@ -371,28 +376,31 @@ impl ext_ctxt_ast_builder for ext_ctxt {
|
|||
}
|
||||
}
|
||||
|
||||
fn strip_bounds(&self, bounds: &[ast::ty_param]) -> ~[ast::ty_param] {
|
||||
do bounds.map |ty_param| {
|
||||
ast::ty_param { bounds: @~[], ..copy *ty_param }
|
||||
}
|
||||
fn strip_bounds(&self, generics: &Generics) -> Generics {
|
||||
let no_bounds = @opt_vec::Empty;
|
||||
let new_params = do generics.ty_params.map |ty_param| {
|
||||
ast::TyParam { bounds: no_bounds, ..copy *ty_param }
|
||||
};
|
||||
Generics { ty_params: new_params, ..*generics }
|
||||
}
|
||||
|
||||
fn item_ty_poly(&self, name: ident, span: span, ty: @ast::Ty,
|
||||
+params: ~[ast::ty_param]) -> @ast::item {
|
||||
self.item(name, span, ast::item_ty(ty, params))
|
||||
+generics: Generics) -> @ast::item {
|
||||
self.item(name, span, ast::item_ty(ty, generics))
|
||||
}
|
||||
|
||||
fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item {
|
||||
self.item_ty_poly(name, span, ty, ~[])
|
||||
self.item_ty_poly(name, span, ty, ast_util::empty_generics())
|
||||
}
|
||||
|
||||
fn ty_vars(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] {
|
||||
fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
|
||||
ty_params.map(|p| self.ty_path_ast_builder(
|
||||
path(~[p.ident], dummy_sp())))
|
||||
path(~[p.ident], dummy_sp()))).to_vec()
|
||||
}
|
||||
|
||||
fn ty_vars_global(&self, +ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] {
|
||||
fn ty_vars_global(&self,
|
||||
ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
|
||||
ty_params.map(|p| self.ty_path_ast_builder(
|
||||
path(~[p.ident], dummy_sp())))
|
||||
path(~[p.ident], dummy_sp()))).to_vec()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,13 +67,13 @@ impl proto::visitor<(), (), ()> for ext_ctxt {
|
|||
else {
|
||||
let next = proto.get_state(next_state.state);
|
||||
|
||||
if next.ty_params.len() != next_state.tys.len() {
|
||||
if next.generics.ty_params.len() != next_state.tys.len() {
|
||||
self.span_err(
|
||||
next.span, // use a real span
|
||||
fmt!("message %s target (%s) \
|
||||
needs %u type parameters, but got %u",
|
||||
name, next.name,
|
||||
next.ty_params.len(),
|
||||
next.generics.ty_params.len(),
|
||||
next_state.tys.len()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,13 +51,13 @@ impl proto_parser for parser::Parser {
|
|||
_ => fail!()
|
||||
};
|
||||
|
||||
let typarms = if *self.token == token::LT {
|
||||
self.parse_ty_params()
|
||||
let generics = if *self.token == token::LT {
|
||||
self.parse_generics()
|
||||
} else {
|
||||
~[]
|
||||
ast_util::empty_generics()
|
||||
};
|
||||
|
||||
let state = proto.add_state_poly(name, id, dir, typarms);
|
||||
let state = proto.add_state_poly(name, id, dir, generics);
|
||||
|
||||
// parse the messages
|
||||
self.parse_unspanned_seq(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ use ext::pipes::proto::*;
|
|||
use ext::quote::rt::*;
|
||||
use parse::*;
|
||||
use util::interner;
|
||||
use opt_vec;
|
||||
use opt_vec::OptVec;
|
||||
|
||||
use core::dvec::DVec;
|
||||
use core::prelude::*;
|
||||
|
|
@ -50,20 +52,19 @@ impl gen_send for message {
|
|||
fn gen_send(&mut self, cx: ext_ctxt, try: bool) -> @ast::item {
|
||||
debug!("pipec: gen_send");
|
||||
let name = self.name();
|
||||
let params = self.get_params();
|
||||
|
||||
match *self {
|
||||
message(ref _id, span, ref tys, this, Some(ref next_state)) => {
|
||||
debug!("pipec: next state exists");
|
||||
let next = this.proto.get_state(next_state.state);
|
||||
assert next_state.tys.len() == next.ty_params.len();
|
||||
assert next_state.tys.len() == next.generics.ty_params.len();
|
||||
let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
|
||||
|
||||
let args_ast = (arg_names, *tys).map(|n, t| cx.arg(*n, *t));
|
||||
|
||||
let pipe_ty = cx.ty_path_ast_builder(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars_global(this.ty_params)));
|
||||
.add_tys(cx.ty_vars_global(&this.generics.ty_params)));
|
||||
let args_ast = vec::append(
|
||||
~[cx.arg(cx.ident_of(~"pipe"),
|
||||
pipe_ty)],
|
||||
|
|
@ -129,7 +130,7 @@ impl gen_send for message {
|
|||
cx.item_fn_poly(name,
|
||||
args_ast,
|
||||
rty,
|
||||
params,
|
||||
self.get_generics(),
|
||||
cx.expr_block(body))
|
||||
}
|
||||
|
||||
|
|
@ -143,10 +144,10 @@ impl gen_send for message {
|
|||
|
||||
let args_ast = vec::append(
|
||||
~[cx.arg(cx.ident_of(~"pipe"),
|
||||
cx.ty_path_ast_builder(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars_global(
|
||||
this.ty_params))))],
|
||||
cx.ty_path_ast_builder(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars_global(
|
||||
&this.generics.ty_params))))],
|
||||
args_ast);
|
||||
|
||||
let message_args = if arg_names.len() == 0 {
|
||||
|
|
@ -184,7 +185,7 @@ impl gen_send for message {
|
|||
} else {
|
||||
cx.ty_nil_ast_builder()
|
||||
},
|
||||
params,
|
||||
self.get_generics(),
|
||||
cx.expr_block(body))
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +193,7 @@ impl gen_send for message {
|
|||
|
||||
fn to_ty(&mut self, cx: ext_ctxt) -> @ast::Ty {
|
||||
cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
|
||||
.add_tys(cx.ty_vars_global(self.get_params())))
|
||||
.add_tys(cx.ty_vars_global(&self.get_generics().ty_params)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +244,7 @@ impl to_type_decls for state {
|
|||
ast::enum_def(enum_def_ {
|
||||
variants: items_msg,
|
||||
common: None }),
|
||||
cx.strip_bounds(self.ty_params)
|
||||
cx.strip_bounds(&self.generics)
|
||||
)
|
||||
]
|
||||
}
|
||||
|
|
@ -281,8 +282,9 @@ impl to_type_decls for state {
|
|||
path(~[cx.ident_of(~"super"),
|
||||
self.data_name()],
|
||||
dummy_sp())
|
||||
.add_tys(cx.ty_vars_global(self.ty_params))))),
|
||||
cx.strip_bounds(self.ty_params)));
|
||||
.add_tys(cx.ty_vars_global(
|
||||
&self.generics.ty_params))))),
|
||||
cx.strip_bounds(&self.generics)));
|
||||
}
|
||||
else {
|
||||
items.push(
|
||||
|
|
@ -299,9 +301,10 @@ impl to_type_decls for state {
|
|||
path(~[cx.ident_of(~"super"),
|
||||
self.data_name()],
|
||||
dummy_sp())
|
||||
.add_tys(cx.ty_vars_global(self.ty_params))),
|
||||
.add_tys(cx.ty_vars_global(
|
||||
&self.generics.ty_params))),
|
||||
self.proto.buffer_ty_path(cx)])),
|
||||
cx.strip_bounds(self.ty_params)));
|
||||
cx.strip_bounds(&self.generics)));
|
||||
};
|
||||
items
|
||||
}
|
||||
|
|
@ -340,7 +343,7 @@ impl gen_init for protocol {
|
|||
|
||||
cx.parse_item(fmt!("pub fn init%s() -> (client::%s, server::%s)\
|
||||
{ use core::pipes::HasBuffer; %s }",
|
||||
start_state.ty_params.to_source(cx),
|
||||
start_state.generics.to_source(cx),
|
||||
start_state.to_ty(cx).to_source(cx),
|
||||
start_state.to_ty(cx).to_source(cx),
|
||||
body.to_source(cx)))
|
||||
|
|
@ -385,9 +388,9 @@ impl gen_init for protocol {
|
|||
}
|
||||
|
||||
fn buffer_ty_path(&self, cx: ext_ctxt) -> @ast::Ty {
|
||||
let mut params: ~[ast::ty_param] = ~[];
|
||||
let mut params: OptVec<ast::TyParam> = opt_vec::Empty;
|
||||
for (copy self.states).each |s| {
|
||||
for s.ty_params.each |tp| {
|
||||
for s.generics.ty_params.each |tp| {
|
||||
match params.find(|tpp| tp.ident == tpp.ident) {
|
||||
None => params.push(*tp),
|
||||
_ => ()
|
||||
|
|
@ -398,19 +401,20 @@ impl gen_init for protocol {
|
|||
cx.ty_path_ast_builder(path(~[cx.ident_of(~"super"),
|
||||
cx.ident_of(~"__Buffer")],
|
||||
copy self.span)
|
||||
.add_tys(cx.ty_vars_global(params)))
|
||||
.add_tys(cx.ty_vars_global(¶ms)))
|
||||
}
|
||||
|
||||
fn gen_buffer_type(&self, cx: ext_ctxt) -> @ast::item {
|
||||
let ext_cx = cx;
|
||||
let mut params: ~[ast::ty_param] = ~[];
|
||||
let mut params: OptVec<ast::TyParam> = opt_vec::Empty;
|
||||
let fields = do (copy self.states).map_to_vec |s| {
|
||||
for s.ty_params.each |tp| {
|
||||
for s.generics.ty_params.each |tp| {
|
||||
match params.find(|tpp| tp.ident == tpp.ident) {
|
||||
None => params.push(*tp),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
let ty = s.to_ty(cx);
|
||||
let fty = quote_ty!( ::core::pipes::Packet<$ty> );
|
||||
|
||||
|
|
@ -427,6 +431,11 @@ impl gen_init for protocol {
|
|||
}
|
||||
};
|
||||
|
||||
let generics = Generics {
|
||||
lifetimes: opt_vec::Empty,
|
||||
ty_params: params
|
||||
};
|
||||
|
||||
cx.item_struct_poly(
|
||||
cx.ident_of(~"__Buffer"),
|
||||
dummy_sp(),
|
||||
|
|
@ -435,7 +444,7 @@ impl gen_init for protocol {
|
|||
dtor: None,
|
||||
ctor_id: None
|
||||
},
|
||||
cx.strip_bounds(params))
|
||||
cx.strip_bounds(&generics))
|
||||
}
|
||||
|
||||
fn compile(&self, cx: ext_ctxt) -> @ast::item {
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ pub impl message {
|
|||
}
|
||||
|
||||
/// Return the type parameters actually used by this message
|
||||
fn get_params(&mut self) -> ~[ast::ty_param] {
|
||||
fn get_generics(&self) -> ast::Generics {
|
||||
match *self {
|
||||
message(_, _, _, this, _) => this.ty_params
|
||||
message(_, _, _, this, _) => this.generics
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ pub struct state_ {
|
|||
ident: ast::ident,
|
||||
span: span,
|
||||
dir: direction,
|
||||
ty_params: ~[ast::ty_param],
|
||||
generics: ast::Generics,
|
||||
messages: @mut ~[message],
|
||||
proto: protocol
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ pub impl state_ {
|
|||
fn to_ty(&self, cx: ext_ctxt) -> @ast::Ty {
|
||||
cx.ty_path_ast_builder
|
||||
(path(~[cx.ident_of(self.name)],self.span).add_tys(
|
||||
cx.ty_vars(self.ty_params)))
|
||||
cx.ty_vars(&self.generics.ty_params)))
|
||||
}
|
||||
|
||||
/// Iterate over the states that can be reached in one message
|
||||
|
|
@ -161,7 +161,7 @@ pub impl protocol_ {
|
|||
|
||||
fn has_ty_params(&mut self) -> bool {
|
||||
for self.states.each |s| {
|
||||
if s.ty_params.len() > 0 {
|
||||
if s.generics.ty_params.len() > 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ pub impl protocol_ {
|
|||
|
||||
pub impl protocol {
|
||||
fn add_state_poly(&self, name: ~str, ident: ast::ident, dir: direction,
|
||||
+ty_params: ~[ast::ty_param]) -> state {
|
||||
+generics: ast::Generics) -> state {
|
||||
let messages = @mut ~[];
|
||||
|
||||
let state = @state_ {
|
||||
|
|
@ -184,7 +184,7 @@ pub impl protocol {
|
|||
ident: ident,
|
||||
span: self.span,
|
||||
dir: dir,
|
||||
ty_params: ty_params,
|
||||
generics: generics,
|
||||
messages: messages,
|
||||
proto: *self
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ pub mod rt {
|
|||
use print::pprust::{item_to_str, ty_to_str};
|
||||
|
||||
trait ToTokens {
|
||||
pub fn to_tokens(_cx: ext_ctxt) -> ~[token_tree];
|
||||
pub fn to_tokens(&self, _cx: ext_ctxt) -> ~[token_tree];
|
||||
}
|
||||
|
||||
impl ToTokens for ~[token_tree] {
|
||||
pub fn to_tokens(_cx: ext_ctxt) -> ~[token_tree] {
|
||||
copy self
|
||||
pub fn to_tokens(&self, _cx: ext_ctxt) -> ~[token_tree] {
|
||||
copy *self
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,91 +75,91 @@ pub mod rt {
|
|||
|
||||
trait ToSource {
|
||||
// Takes a thing and generates a string containing rust code for it.
|
||||
pub fn to_source(cx: ext_ctxt) -> ~str;
|
||||
pub fn to_source(&self, cx: ext_ctxt) -> ~str;
|
||||
}
|
||||
|
||||
impl ToSource for ast::ident {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
copy *cx.parse_sess().interner.get(self)
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
copy *cx.parse_sess().interner.get(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for @ast::item {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
item_to_str(self, cx.parse_sess().interner)
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
item_to_str(*self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for ~[@ast::item] {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
str::connect(self.map(|i| i.to_source(cx)), ~"\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for @ast::Ty {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
ty_to_str(self, cx.parse_sess().interner)
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
ty_to_str(*self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for ~[@ast::Ty] {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
str::connect(self.map(|i| i.to_source(cx)), ~", ")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for ~[ast::ty_param] {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
pprust::typarams_to_str(self, cx.parse_sess().interner)
|
||||
impl ToSource for Generics {
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
pprust::generics_to_str(self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSource for @ast::expr {
|
||||
fn to_source(cx: ext_ctxt) -> ~str {
|
||||
pprust::expr_to_str(self, cx.parse_sess().interner)
|
||||
fn to_source(&self, cx: ext_ctxt) -> ~str {
|
||||
pprust::expr_to_str(*self, cx.parse_sess().interner)
|
||||
}
|
||||
}
|
||||
|
||||
// Alas ... we write these out instead. All redundant.
|
||||
|
||||
impl ToTokens for ast::ident {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for @ast::item {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ~[@ast::item] {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for @ast::Ty {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ~[@ast::Ty] {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ~[ast::ty_param] {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
impl ToTokens for Generics {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for @ast::expr {
|
||||
fn to_tokens(cx: ext_ctxt) -> ~[token_tree] {
|
||||
fn to_tokens(&self, cx: ext_ctxt) -> ~[token_tree] {
|
||||
cx.parse_tts(self.to_source(cx))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue