about summary refs log tree commit diff
path: root/src/libsyntax/ext/pipes
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-07-18 16:18:02 -0700
committerPaul Stansifer <paul.stansifer@gmail.com>2012-08-22 14:59:25 -0700
commit1153b5dcc86c3567b0a86e441938f05d4f2e295b (patch)
treefdcbcea39abecb4ad1ea5145e62e8c013b05e930 /src/libsyntax/ext/pipes
parent7317bf8792ebb3f27768109b7d574ee0806cc5e5 (diff)
intern identifiers
Diffstat (limited to 'src/libsyntax/ext/pipes')
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs15
-rw-r--r--src/libsyntax/ext/pipes/check.rs10
-rw-r--r--src/libsyntax/ext/pipes/liveness.rs6
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs15
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs142
-rw-r--r--src/libsyntax/ext/pipes/proto.rs41
6 files changed, 116 insertions, 113 deletions
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 39132fd0d59..45873f81dea 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -15,14 +15,10 @@ mod syntax {
     export parse;
 }
 
-fn ident(s: &str) -> ast::ident {
-    @(s.to_unique())
-}
-
-fn path(id: ident, span: span) -> @ast::path {
+fn path(ids: ~[ident], span: span) -> @ast::path {
     @{span: span,
       global: false,
-      idents: ~[id],
+      idents: ids,
       rp: none,
       types: ~[]}
 }
@@ -94,7 +90,8 @@ trait ext_ctxt_ast_builder {
 
 impl ext_ctxt: ext_ctxt_ast_builder {
     fn ty_option(ty: @ast::ty) -> @ast::ty {
-        self.ty_path_ast_builder(path(@~"option", self.empty_span())
+        self.ty_path_ast_builder(path(~[self.ident_of(~"option")],
+                                      self.empty_span())
                                  .add_ty(ty))
     }
 
@@ -126,7 +123,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
                      ty: self.ty_infer(),
                      pat: @{id: self.next_id(),
                             node: ast::pat_ident(ast::bind_by_implicit_ref,
-                                                 path(ident,
+                                                 path(~[ident],
                                                       self.empty_span()),
                                                  none),
                             span: self.empty_span()},
@@ -301,6 +298,6 @@ impl ext_ctxt: ext_ctxt_ast_builder {
 
     fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] {
         ty_params.map(|p| self.ty_path_ast_builder(
-            path(p.ident, self.empty_span())))
+            path(~[p.ident], self.empty_span())))
     }
 }
diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs
index e286b4f76be..b7ad5c21bd9 100644
--- a/src/libsyntax/ext/pipes/check.rs
+++ b/src/libsyntax/ext/pipes/check.rs
@@ -21,8 +21,6 @@ that.
 
 import ext::base::ext_ctxt;
 
-import ast::{ident};
-
 import proto::{state, protocol, next_state};
 import ast_builder::empty_span;
 
@@ -36,11 +34,11 @@ impl ext_ctxt: proto::visitor<(), (), ()>  {
                 state.span, // use a real span!
                 fmt!{"state %s contains no messages, \
                       consider stepping to a terminal state instead",
-                     *state.name})
+                      state.name})
         }
     }
 
-    fn visit_message(name: ident, _span: span, _tys: &[@ast::ty],
+    fn visit_message(name: ~str, _span: span, _tys: &[@ast::ty],
                      this: state, next: next_state) {
         match next {
           some({state: next, tys: next_tys}) => {
@@ -51,7 +49,7 @@ impl ext_ctxt: proto::visitor<(), (), ()>  {
                 self.span_err(
                     proto.get_state(next).span,
                     fmt!{"message %s steps to undefined state, %s",
-                         *name, *next});
+                         name, next});
             }
             else {
                 let next = proto.get_state(next);
@@ -61,7 +59,7 @@ impl ext_ctxt: proto::visitor<(), (), ()>  {
                         next.span, // use a real span
                         fmt!{"message %s target (%s) \
                               needs %u type parameters, but got %u",
-                             *name, *next.name,
+                             name, next.name,
                              next.ty_params.len(),
                              next_tys.len()});
                 }
diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs
index 17e569552a7..2325e4ed27d 100644
--- a/src/libsyntax/ext/pipes/liveness.rs
+++ b/src/libsyntax/ext/pipes/liveness.rs
@@ -70,10 +70,10 @@ fn analyze(proto: protocol, _cx: ext_ctxt) {
     }
 
     if self_live.len() > 0 {
-        let states = str::connect(self_live.map(|s| *s.name), ~" ");
+        let states = str::connect(self_live.map(|s| s.name), ~" ");
 
         debug!{"protocol %s is unbounded due to loops involving: %s",
-               *proto.name, states};
+               proto.name, states};
 
         // Someday this will be configurable with a warning
         //cx.span_warn(empty_span(),
@@ -85,7 +85,7 @@ fn analyze(proto: protocol, _cx: ext_ctxt) {
         proto.bounded = some(false);
     }
     else {
-        debug!{"protocol %s is bounded. yay!", *proto.name};
+        debug!{"protocol %s is bounded. yay!", proto.name};
         proto.bounded = some(true);
     }
 }
\ No newline at end of file
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index 84180ff3797..4dc61e54aa4 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -1,18 +1,17 @@
 // Parsing pipes protocols from token trees.
 
 import parse::parser;
-import ast::ident;
 import parse::token;
 
 import pipec::*;
 
 trait proto_parser {
-    fn parse_proto(id: ident) -> protocol;
+    fn parse_proto(id: ~str) -> protocol;
     fn parse_state(proto: protocol);
 }
 
 impl parser: proto_parser {
-    fn parse_proto(id: ident) -> protocol {
+    fn parse_proto(id: ~str) -> protocol {
         let proto = protocol(id, self.span);
 
         self.parse_seq_to_before_end(token::EOF,
@@ -24,9 +23,11 @@ impl parser: proto_parser {
 
     fn parse_state(proto: protocol) {
         let id = self.parse_ident();
+        let name = *self.interner.get(id);
+
         self.expect(token::COLON);
         let dir = match copy self.token {
-          token::IDENT(n, _) => self.get_str(n),
+          token::IDENT(n, _) => self.interner.get(n),
           _ => fail
         };
         self.bump();
@@ -41,7 +42,7 @@ impl parser: proto_parser {
         }
         else { ~[] };
 
-        let state = proto.add_state_poly(id, dir, typarms);
+        let state = proto.add_state_poly(name, id, dir, typarms);
 
         // parse the messages
         self.parse_unspanned_seq(
@@ -51,7 +52,7 @@ impl parser: proto_parser {
     }
 
     fn parse_message(state: state) {
-        let mname = self.parse_ident();
+        let mname = *self.interner.get(self.parse_ident());
 
         let args = if self.token == token::LPAREN {
             self.parse_unspanned_seq(token::LPAREN,
@@ -66,7 +67,7 @@ impl parser: proto_parser {
 
         let next = match copy self.token {
           token::IDENT(_, _) => {
-            let name = self.parse_ident();
+            let name = *self.interner.get(self.parse_ident());
             let ntys = if self.token == token::LT {
                 self.parse_unspanned_seq(token::LT,
                                          token::GT,
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index f7f2981f066..b5a1ae588a7 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -13,8 +13,7 @@ import parse;
 import parse::*;
 import proto::*;
 
-import ast_builder::append_types;
-import ast_builder::path;
+import ast_builder::{append_types, path, empty_span};
 
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
@@ -47,17 +46,17 @@ impl message: gen_send {
             debug!("pipec: next state exists");
             let next = this.proto.get_state(next);
             assert next_tys.len() == next.ty_params.len();
-            let arg_names = tys.mapi(|i, _ty| @(~"x_" + i.to_str()));
+            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_mode(n, t, ast::by_copy)
             );
 
             let pipe_ty = cx.ty_path_ast_builder(
-                path(this.data_name(), span)
+                path(~[this.data_name()], span)
                 .add_tys(cx.ty_vars(this.ty_params)));
             let args_ast = vec::append(
-                ~[cx.arg_mode(@~"pipe",
+                ~[cx.arg_mode(cx.ident_of(~"pipe"),
                               pipe_ty,
                               ast::by_copy)],
                 args_ast);
@@ -75,10 +74,10 @@ impl message: gen_send {
                 body += ~"let b = pipe.reuse_buffer();\n";
                 body += fmt!("let %s = pipes::send_packet_buffered(\
                               ptr::addr_of(b.buffer.data.%s));\n",
-                             sp, *next.name);
-                body += fmt!("let %s = pipes::recv_packet_buffered(\
+                             sp, next.name);
+                body += fmt!{"let %s = pipes::recv_packet_buffered(\
                               ptr::addr_of(b.buffer.data.%s));\n",
-                             rp, *next.name);
+                             rp, next.name};
             }
             else {
                 let pat = match (this.dir, next.dir) {
@@ -91,10 +90,10 @@ impl message: gen_send {
                 body += fmt!("let %s = pipes::entangle();\n", pat);
             }
             body += fmt!("let message = %s::%s(%s);\n",
-                         *this.proto.name,
-                         *self.name(),
-                         str::connect(vec::append_one(arg_names, @~"s")
-                                      .map(|x| *x),
+                         this.proto.name,
+                         self.name(),
+                         str::connect(vec::append_one(
+                             arg_names.map(|x| cx.str_of(x)), ~"s"),
                                       ~", "));
 
             if !try {
@@ -110,17 +109,15 @@ impl message: gen_send {
 
             let body = cx.parse_expr(body);
 
-            let mut rty = cx.ty_path_ast_builder(path(next.data_name(),
+            let mut rty = cx.ty_path_ast_builder(path(~[next.data_name()],
                                                       span)
                                                  .add_tys(next_tys));
             if try {
                 rty = cx.ty_option(rty);
             }
 
-            let name = if try {
-                @(~"try_" + *self.name())
-            }
-            else { self.name() };
+            let name = cx.ident_of(if try { ~"try_" + self.name()
+                                          } else { self.name() } );
 
             cx.item_fn_poly(name,
                             args_ast,
@@ -131,16 +128,16 @@ impl message: gen_send {
 
             message(id, span, tys, this, none) => {
                 debug!{"pipec: no next state"};
-                let arg_names = tys.mapi(|i, _ty| @(~"x_" + i.to_str()));
+                let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
 
                 let args_ast = (arg_names, tys).map(
-                    |n, t| cx.arg_mode(n, t, ast::by_copy)
+                    |n, t| cx.arg_mode(cx.ident_of(n), t, ast::by_copy)
                 );
 
                 let args_ast = vec::append(
-                    ~[cx.arg_mode(@~"pipe",
+                    ~[cx.arg_mode(cx.ident_of(~"pipe"),
                                   cx.ty_path_ast_builder(
-                                      path(this.data_name(), span)
+                                      path(~[this.data_name()], span)
                                       .add_tys(cx.ty_vars(this.ty_params))),
                                   ast::by_copy)],
                     args_ast);
@@ -149,13 +146,13 @@ impl message: gen_send {
                     ~""
                 }
                 else {
-                    ~"(" + str::connect(arg_names.map(|x| *x), ~", ") + ~")"
+                    ~"(" + str::connect(arg_names, ~", ") + ~")"
                 };
 
                 let mut body = ~"{ ";
                 body += fmt!{"let message = %s::%s%s;\n",
-                             *this.proto.name,
-                             *self.name(),
+                             this.proto.name,
+                             self.name(),
                              message_args};
 
                 if !try {
@@ -170,11 +167,11 @@ impl message: gen_send {
                 let body = cx.parse_expr(body);
 
                 let name = if try {
-                    @(~"try_" + *self.name())
+                    ~"try_" + self.name()
                 }
                 else { self.name() };
 
-                cx.item_fn_poly(name,
+                cx.item_fn_poly(cx.ident_of(name),
                                 args_ast,
                                 if try {
                                     cx.ty_option(cx.ty_nil_ast_builder())
@@ -188,7 +185,7 @@ impl message: gen_send {
         }
 
     fn to_ty(cx: ext_ctxt) -> @ast::ty {
-        cx.ty_path_ast_builder(path(self.name(), self.span())
+        cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
           .add_tys(cx.ty_vars(self.get_params())))
     }
 }
@@ -212,21 +209,23 @@ impl state: to_type_decls {
             let tys = match next {
               some({state: next, tys: next_tys}) => {
                 let next = this.proto.get_state(next);
-                let next_name = next.data_name();
+                let next_name = cx.str_of(next.data_name());
 
                 let dir = match this.dir {
-                  send => @~"server",
-                  recv => @~"client"
+                  send => ~"server",
+                  recv => ~"client"
                 };
 
                 vec::append_one(tys,
-                                cx.ty_path_ast_builder((dir + next_name)
-                                           .add_tys(next_tys)))
+                                cx.ty_path_ast_builder(
+                                    path(~[cx.ident_of(dir),
+                                           cx.ident_of(next_name)], span)
+                                    .add_tys(next_tys)))
               }
               none => tys
             };
 
-            let v = cx.variant(name, span, tys);
+            let v = cx.variant(cx.ident_of(name), span, tys);
 
             vec::push(items_msg, v);
         }
@@ -258,9 +257,13 @@ impl state: to_type_decls {
                           self.data_name(),
                           self.span,
                           cx.ty_path_ast_builder(
-                              (@~"pipes" + @(dir.to_str() + ~"_packet"))
+                              path(~[cx.ident_of(~"pipes"),
+                                     cx.ident_of(dir.to_str() + ~"_packet")],
+                                   empty_span())
                               .add_ty(cx.ty_path_ast_builder(
-                                  (self.proto.name + self.data_name())
+                                  path(~[cx.ident_of(self.proto.name),
+                                         self.data_name()],
+                                       empty_span())
                                   .add_tys(cx.ty_vars(self.ty_params))))),
                           self.ty_params));
         }
@@ -270,10 +273,14 @@ impl state: to_type_decls {
                           self.data_name(),
                           self.span,
                           cx.ty_path_ast_builder(
-                              (@~"pipes" + @(dir.to_str()
-                                             + ~"_packet_buffered"))
+                              path(~[cx.ident_of(~"pipes"),
+                                     cx.ident_of(dir.to_str()
+                                                 + ~"_packet_buffered")],
+                                  empty_span())
                               .add_tys(~[cx.ty_path_ast_builder(
-                                  (self.proto.name + self.data_name())
+                                  path(~[cx.ident_of(self.proto.name),
+                                         self.data_name()],
+                                       empty_span())
                                   .add_tys(cx.ty_vars(self.ty_params))),
                                          self.proto.buffer_ty_path(cx)])),
                           self.ty_params));
@@ -315,16 +322,17 @@ impl protocol: gen_init {
 
         cx.parse_item(fmt!{"fn init%s() -> (client::%s, server::%s)\
                             { import pipes::has_buffer; %s }",
-                           start_state.ty_params.to_source(),
-                           start_state.to_ty(cx).to_source(),
-                           start_state.to_ty(cx).to_source(),
-                           body.to_source()})
+                           start_state.ty_params.to_source(cx),
+                           start_state.to_ty(cx).to_source(cx),
+                           start_state.to_ty(cx).to_source(cx),
+                           body.to_source(cx)})
     }
 
     fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
         ext_cx.rec(self.states.map_to_vec(|s| {
             let fty = s.to_ty(ext_cx);
-            ext_cx.field_imm(s.name, #ast { pipes::mk_packet::<$(fty)>() })
+            ext_cx.field_imm(ext_cx.ident_of(s.name),
+                             #ast { pipes::mk_packet::<$(fty)>() })
         }))
     }
 
@@ -341,9 +349,11 @@ impl protocol: gen_init {
             ext_cx.block(
                 self.states.map_to_vec(
                     |s| ext_cx.parse_stmt(
-                        fmt!{"data.%s.set_buffer(buffer)", *s.name})),
+                        fmt!{"data.%s.set_buffer(buffer)",
+                             s.name})),
                 ext_cx.parse_expr(
-                    fmt!{"ptr::addr_of(data.%s)", *self.states[0].name})));
+                    fmt!{"ptr::addr_of(data.%s)",
+                         self.states[0].name})));
 
         #ast {{
             let buffer = $(buffer);
@@ -357,14 +367,14 @@ impl protocol: gen_init {
         let mut params: ~[ast::ty_param] = ~[];
         for (copy self.states).each |s| {
             for s.ty_params.each |tp| {
-                match params.find(|tpp| *tp.ident == *tpp.ident) {
+                match params.find(|tpp| tp.ident == tpp.ident) {
                   none => vec::push(params, tp),
                   _ => ()
                 }
             }
         }
 
-        cx.ty_path_ast_builder(path(@~"__Buffer", self.span)
+        cx.ty_path_ast_builder(path(~[cx.ident_of(~"__Buffer")], self.span)
                                .add_tys(cx.ty_vars(params)))
     }
 
@@ -373,7 +383,7 @@ impl protocol: gen_init {
         let mut params: ~[ast::ty_param] = ~[];
         let fields = do (copy self.states).map_to_vec |s| {
             for s.ty_params.each |tp| {
-                match params.find(|tpp| *tp.ident == *tpp.ident) {
+                match params.find(|tpp| tp.ident == tpp.ident) {
                   none => vec::push(params, tp),
                   _ => ()
                 }
@@ -382,11 +392,11 @@ impl protocol: gen_init {
             let fty = #ast[ty] {
                 pipes::packet<$(ty)>
             };
-            cx.ty_field_imm(s.name, fty)
+            cx.ty_field_imm(cx.ident_of(s.name), fty)
         };
 
         cx.item_ty_poly(
-            @~"__Buffer",
+            cx.ident_of(~"__Buffer"),
             cx.empty_span(),
             cx.ty_rec(fields),
             params)
@@ -410,56 +420,56 @@ impl protocol: gen_init {
         }
 
         vec::push(items,
-                  cx.item_mod(@~"client",
+                  cx.item_mod(cx.ident_of(~"client"),
                               self.span,
                               client_states));
         vec::push(items,
-                  cx.item_mod(@~"server",
+                  cx.item_mod(cx.ident_of(~"server"),
                               self.span,
                               server_states));
 
-        cx.item_mod(self.name, self.span, items)
+        cx.item_mod(cx.ident_of(self.name), self.span, items)
     }
 }
 
 trait to_source {
     // Takes a thing and generates a string containing rust code for it.
-    fn to_source() -> ~str;
+    fn to_source(cx: ext_ctxt) -> ~str;
 }
 
 impl @ast::item: to_source {
-    fn to_source() -> ~str {
-        item_to_str(self)
+    fn to_source(cx: ext_ctxt) -> ~str {
+        item_to_str(self, cx.parse_sess().interner)
     }
 }
 
 impl ~[@ast::item]: to_source {
-    fn to_source() -> ~str {
-        str::connect(self.map(|i| i.to_source()), ~"\n\n")
+    fn to_source(cx: ext_ctxt) -> ~str {
+        str::connect(self.map(|i| i.to_source(cx)), ~"\n\n")
     }
 }
 
 impl @ast::ty: to_source {
-    fn to_source() -> ~str {
-        ty_to_str(self)
+    fn to_source(cx: ext_ctxt) -> ~str {
+        ty_to_str(self, cx.parse_sess().interner)
     }
 }
 
 impl ~[@ast::ty]: to_source {
-    fn to_source() -> ~str {
-        str::connect(self.map(|i| i.to_source()), ~", ")
+    fn to_source(cx: ext_ctxt) -> ~str {
+        str::connect(self.map(|i| i.to_source(cx)), ~", ")
     }
 }
 
 impl ~[ast::ty_param]: to_source {
-    fn to_source() -> ~str {
-        pprust::typarams_to_str(self)
+    fn to_source(cx: ext_ctxt) -> ~str {
+        pprust::typarams_to_str(self, cx.parse_sess().interner)
     }
 }
 
 impl @ast::expr: to_source {
-    fn to_source() -> ~str {
-        pprust::expr_to_str(self)
+    fn to_source(cx: ext_ctxt) -> ~str {
+        pprust::expr_to_str(self, cx.parse_sess().interner)
     }
 }
 
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 9e44ce7acda..62c5329525f 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -1,8 +1,6 @@
 import to_str::ToStr;
 import dvec::{DVec, dvec};
 
-import ast::{ident};
-
 import ast_builder::{path, append_types};
 
 enum direction {
@@ -27,15 +25,15 @@ impl direction {
     }
 }
 
-type next_state = option<{state: ident, tys: ~[@ast::ty]}>;
+type next_state = option<{state: ~str, tys: ~[@ast::ty]}>;
 
 enum message {
     // name, span, data, current state, next state
-    message(ident, span, ~[@ast::ty], state, next_state)
+    message(~str, span, ~[@ast::ty], state, next_state)
 }
 
 impl message {
-    fn name() -> ident {
+    fn name() -> ~str {
         match self {
           message(id, _, _, _, _) => id
         }
@@ -58,7 +56,8 @@ impl message {
 enum state {
     state_(@{
         id: uint,
-        name: ident,
+        name: ~str,
+        ident: ast::ident,
         span: span,
         dir: direction,
         ty_params: ~[ast::ty_param],
@@ -68,7 +67,7 @@ enum state {
 }
 
 impl state {
-    fn add_message(name: ident, span: span,
+    fn add_message(name: ~str, span: span,
                    +data: ~[@ast::ty], next: next_state) {
         self.messages.push(message(name, span, data, self,
                                    next));
@@ -78,14 +77,15 @@ impl state {
         (*self).proto.filename()
     }
 
-    fn data_name() -> ident {
-        self.name
+    fn data_name() -> ast::ident {
+        self.ident
     }
 
     /// Returns the type that is used for the messages.
     fn to_ty(cx: ext_ctxt) -> @ast::ty {
         cx.ty_path_ast_builder
-            (path(self.name, self.span).add_tys(cx.ty_vars(self.ty_params)))
+            (path(~[cx.ident_of(self.name)],self.span).add_tys(
+                cx.ty_vars(self.ty_params)))
     }
 
     /// Iterate over the states that can be reached in one message
@@ -105,18 +105,18 @@ impl state {
 
 type protocol = @protocol_;
 
-fn protocol(name: ident, +span: span) -> protocol {
+fn protocol(name: ~str, +span: span) -> protocol {
     @protocol_(name, span)
 }
 
 struct protocol_ {
-    let name: ident;
+    let name: ~str;
     let span: span;
     let states: DVec<state>;
 
     let mut bounded: option<bool>;
 
-    new(name: ident, span: span) {
+    new(name: ~str, span: span) {
         self.name = name;
         self.span = span;
         self.states = dvec();
@@ -124,18 +124,18 @@ struct protocol_ {
     }
 
     /// Get a state.
-    fn get_state(name: ident) -> state {
+    fn get_state(name: ~str) -> state {
         self.states.find(|i| i.name == name).get()
     }
 
     fn get_state_by_id(id: uint) -> state { self.states[id] }
 
-    fn has_state(name: ident) -> bool {
+    fn has_state(name: ~str) -> bool {
         self.states.find(|i| i.name == name) != none
     }
 
     fn filename() -> ~str {
-        ~"proto://" + *self.name
+        ~"proto://" + self.name
     }
 
     fn num_states() -> uint { self.states.len() }
@@ -162,17 +162,14 @@ struct protocol_ {
 }
 
 impl protocol {
-    fn add_state(name: ident, dir: direction) -> state {
-        self.add_state_poly(name, dir, ~[])
-    }
-
-    fn add_state_poly(name: ident, dir: direction,
+    fn add_state_poly(name: ~str, ident: ast::ident, dir: direction,
                       +ty_params: ~[ast::ty_param]) -> state {
         let messages = dvec();
 
         let state = state_(@{
             id: self.states.len(),
             name: name,
+            ident: ident,
             span: self.span,
             dir: dir,
             ty_params: ty_params,
@@ -188,7 +185,7 @@ impl protocol {
 trait visitor<Tproto, Tstate, Tmessage> {
     fn visit_proto(proto: protocol, st: &[Tstate]) -> Tproto;
     fn visit_state(state: state, m: &[Tmessage]) -> Tstate;
-    fn visit_message(name: ident, spane: span, tys: &[@ast::ty],
+    fn visit_message(name: ~str, spane: span, tys: &[@ast::ty],
                      this: state, next: next_state) -> Tmessage;
 }