diff options
| author | bors <bors@rust-lang.org> | 2013-02-27 17:36:41 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-02-27 17:36:41 -0800 |
| commit | d0a12347dec3045eaf8dcded7add914d4491276f (patch) | |
| tree | 420ba34bc2e064d64d83dfd9c37dd2281236686d /src/libsyntax/ext | |
| parent | 269409f91231c4b1ea896844b820781d2cfab053 (diff) | |
| parent | c623d21e388315df672951fcb8efb5000923ab3d (diff) | |
| download | rust-d0a12347dec3045eaf8dcded7add914d4491276f.tar.gz rust-d0a12347dec3045eaf8dcded7add914d4491276f.zip | |
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
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/auto_encode.rs | 122 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving.rs | 112 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/ast_builder.rs | 72 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/check.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/parse_proto.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/pipec.rs | 53 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/proto.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 50 |
9 files changed, 260 insertions, 190 deletions
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 9e60e215174..aea39502362 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -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 { + /*! + * + * 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 + */ + + + // 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 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, - }); + 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, + }); - ast::ty_param { - ident: tp.ident, - id: cx.next_id(), - bounds: @vec::append(~[t_bound], *tp.bounds) - } - } - ); + 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( diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 55e5d5fbe17..fa21243df03 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -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 } } diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index 094eea81fd2..0164f807f4b 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -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, diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 6adea6395a3..a49d3dead0c 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -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() } } diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs index f456f7b81ae..b543ef5fdae 100644 --- a/src/libsyntax/ext/pipes/check.rs +++ b/src/libsyntax/ext/pipes/check.rs @@ -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())); } } diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs index 9a330db9f18..8caa2c4bba8 100644 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ b/src/libsyntax/ext/pipes/parse_proto.rs @@ -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( diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 84d46e318b1..6c124ce16df 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -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 { diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index d22feff9470..6873baf731f 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -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 }; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index d529ee0c01b..b313d42e812 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -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)) } } |
