summary refs log tree commit diff
path: root/src/libsyntax/ext/pipes
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-02-27 17:36:41 -0800
committerbors <bors@rust-lang.org>2013-02-27 17:36:41 -0800
commitd0a12347dec3045eaf8dcded7add914d4491276f (patch)
tree420ba34bc2e064d64d83dfd9c37dd2281236686d /src/libsyntax/ext/pipes
parent269409f91231c4b1ea896844b820781d2cfab053 (diff)
parentc623d21e388315df672951fcb8efb5000923ab3d (diff)
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/pipes')
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs72
-rw-r--r--src/libsyntax/ext/pipes/check.rs4
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs8
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs53
-rw-r--r--src/libsyntax/ext/pipes/proto.rs14
5 files changed, 84 insertions, 67 deletions
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(&params)))
     }
 
     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
         };