about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorEric Holk <eric.holk@gmail.com>2012-07-24 16:58:48 -0700
committerEric Holk <eric.holk@gmail.com>2012-07-25 12:12:25 -0700
commit1dde5e7fc2ed6c1530919a0298bd3691feca3e2f (patch)
tree5af656f1318fe06b7e51ad4c37c3592362f37677 /src/libsyntax
parent7ecddb2771922bcd0f117a3a3f681da9bcb8b70c (diff)
downloadrust-1dde5e7fc2ed6c1530919a0298bd3691feca3e2f.tar.gz
rust-1dde5e7fc2ed6c1530919a0298bd3691feca3e2f.zip
Thread spans through the pipe compiler. They aren't perfect, but they make debugging far easier than core.rc:0:0.
Changed the is_bounded check, so we fail compiling core right now due to not supporting type parameters.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs73
-rw-r--r--src/libsyntax/ext/pipes/check.rs8
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs4
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs19
-rw-r--r--src/libsyntax/ext/pipes/proto.rs56
5 files changed, 90 insertions, 70 deletions
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index b70100de4c5..c9b35e561bb 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -19,30 +19,25 @@ fn ident(s: ~str) -> ast::ident {
     @(copy s)
 }
 
-fn empty_span() -> span {
-    {lo: 0, hi: 0, expn_info: none}
-}
-
-fn span<T>(+x: T) -> ast::spanned<T> {
-    {node: x,
-     span: empty_span()}
-}
-
-fn path(id: ident) -> @ast::path {
-    @{span: empty_span(),
+fn path(id: ident, span: span) -> @ast::path {
+    @{span: span,
       global: false,
       idents: ~[id],
       rp: none,
       types: ~[]}
 }
 
+fn empty_span() -> span {
+    {lo: 0, hi: 0, expn_info: none}
+}
+
 trait path_concat {
     fn +(id: ident) -> @ast::path;
 }
 
 impl methods of path_concat for ident {
     fn +(id: ident) -> @ast::path {
-        path(self) + id
+        path(self, empty_span()) + id
     }
 }
 
@@ -107,19 +102,24 @@ trait ext_ctxt_ast_builder {
     fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt;
     fn stmt_expr(e: @ast::expr) -> @ast::stmt;
     fn block_expr(b: ast::blk) -> @ast::expr;
+    fn empty_span() -> span;
 }
 
 impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
+    fn empty_span() -> span {
+        {lo: 0, hi: 0, expn_info: self.backtrace()}
+    }
+
     fn block_expr(b: ast::blk) -> @ast::expr {
         @{id: self.next_id(),
           callee_id: self.next_id(),
           node: ast::expr_block(b),
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn stmt_expr(e: @ast::expr) -> @ast::stmt {
         @{node: ast::stmt_expr(e, self.next_id()),
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt {
@@ -133,43 +133,44 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
             @{node: {is_mutbl: false,
                      ty: self.ty_infer(),
                      pat: @{id: self.next_id(),
-                            node: ast::pat_ident(path(ident), none),
-                            span: empty_span()},
+                            node: ast::pat_ident(
+                                path(ident, self.empty_span()), none),
+                            span: self.empty_span()},
                      init: some({op: ast::init_move,
                                  expr: e}),
                      id: self.next_id()},
-              span: empty_span()}]),
-                               span: empty_span()}, self.next_id()),
-         span: empty_span()}
+              span: self.empty_span()}]),
+                               span: self.empty_span()}, self.next_id()),
+         span: self.empty_span()}
     }
 
     fn field_imm(name: ident, e: @ast::expr) -> ast::field {
         {node: {mutbl: ast::m_imm, ident: name, expr: e},
-         span: empty_span()}
+         span: self.empty_span()}
     }
 
     fn rec(+fields: ~[ast::field]) -> @ast::expr {
         @{id: self.next_id(),
           callee_id: self.next_id(),
           node: ast::expr_rec(fields, none),
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn ty_field_imm(name: ident, ty: @ast::ty) -> ast::ty_field {
         {node: {ident: name, mt: { ty: ty, mutbl: ast::m_imm } },
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::ty {
         @{id: self.next_id(),
           node: ast::ty_rec(fields),
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn ty_infer() -> @ast::ty {
         @{id: self.next_id(),
           node: ast::ty_infer,
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
@@ -201,7 +202,7 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
                    rules: ast::default_blk};
 
         {node: blk,
-         span: empty_span()}
+         span: self.empty_span()}
     }
 
     fn expr_block(e: @ast::expr) -> ast::blk {
@@ -223,7 +224,7 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
          id: self.next_id(),
          node: node,
          vis: ast::public,
-         span: empty_span()}
+         span: self.empty_span()}
     }
 
     fn item_fn_poly(name: ident,
@@ -261,12 +262,13 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
                +tys: ~[@ast::ty]) -> ast::variant {
         let args = tys.map(|ty| {ty: ty, id: self.next_id()});
 
-        span({name: name,
-              attrs: ~[],
-              args: args,
-              id: self.next_id(),
-              disr_expr: none,
-              vis: ast::public})
+        {node: {name: name,
+                attrs: ~[],
+                args: args,
+                id: self.next_id(),
+                disr_expr: none,
+                vis: ast::public},
+         span: self.empty_span()}
     }
 
     fn item_mod(name: ident,
@@ -281,13 +283,13 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
         // FIXME #2886: make sure the node ids are legal.
         @{id: self.next_id(),
           node: ast::ty_path(path, self.next_id()),
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn ty_nil_ast_builder() -> @ast::ty {
         @{id: self.next_id(),
           node: ast::ty_nil,
-          span: empty_span()}
+          span: self.empty_span()}
     }
 
     fn item_ty_poly(name: ident,
@@ -301,6 +303,7 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
     }
 
     fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] {
-        ty_params.map(|p| self.ty_path_ast_builder(path(p.ident)))
+        ty_params.map(|p| self.ty_path_ast_builder(
+            path(p.ident, self.empty_span())))
     }
 }
diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs
index 492cb255805..2988b8eaeb1 100644
--- a/src/libsyntax/ext/pipes/check.rs
+++ b/src/libsyntax/ext/pipes/check.rs
@@ -35,14 +35,14 @@ impl proto_check of proto::visitor<(), (), ()>  for ext_ctxt {
     fn visit_state(state: state, _m: &[()]) {
         if state.messages.len() == 0 {
             self.span_warn(
-                empty_span(), // use a real span!
+                state.span, // use a real span!
                 #fmt("state %s contains no messages, \
                       consider stepping to a terminal state instead",
                      *state.name))
         }
     }
 
-    fn visit_message(name: ident, _tys: &[@ast::ty],
+    fn visit_message(name: ident, _span: span, _tys: &[@ast::ty],
                      this: state, next: next_state) {
         alt next {
           some({state: next, tys: next_tys}) {
@@ -51,7 +51,7 @@ impl proto_check of proto::visitor<(), (), ()>  for ext_ctxt {
                 // This should be a span fatal, but then we need to
                 // track span information.
                 self.span_err(
-                    empty_span(),
+                    proto.get_state(next).span,
                     #fmt("message %s steps to undefined state, %s",
                          *name, *next));
             }
@@ -60,7 +60,7 @@ impl proto_check of proto::visitor<(), (), ()>  for ext_ctxt {
 
                 if next.ty_params.len() != next_tys.len() {
                     self.span_err(
-                        empty_span(), // use a real span
+                        next.span, // use a real span
                         #fmt("message %s target (%s) \
                               needs %u type parameters, but got %u",
                              *name, *next.name,
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index 091eaf697bb..0375f742b4b 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -13,7 +13,7 @@ trait proto_parser {
 
 impl proto_parser of proto_parser for parser {
     fn parse_proto(id: ident) -> protocol {
-        let proto = protocol(id);
+        let proto = protocol(id, self.span);
 
         self.parse_seq_to_before_end(token::EOF,
                                      {sep: none, trailing_sep_allowed: false},
@@ -87,7 +87,7 @@ impl proto_parser of proto_parser for parser {
           _ { self.fatal(~"invalid next state") }
         };
 
-        state.add_message(mname, args, next);
+        state.add_message(mname, copy self.span, args, next);
 
     }
 }
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 7dd33e35bc8..a322409e857 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -49,7 +49,7 @@ impl compile of gen_send for message {
     fn gen_send(cx: ext_ctxt) -> @ast::item {
         #debug("pipec: gen_send");
         alt self {
-          message(id, tys, this, some({state: next, tys: next_tys})) {
+          message(id, span, tys, this, some({state: next, tys: next_tys})) {
             #debug("pipec: next state exists");
             let next = this.proto.get_state(next);
             assert next_tys.len() == next.ty_params.len();
@@ -60,7 +60,7 @@ impl compile of gen_send for message {
             );
 
             let pipe_ty = cx.ty_path_ast_builder(
-                path(this.data_name())
+                path(this.data_name(), span)
                 .add_tys(cx.ty_vars(this.ty_params)));
             let args_ast = vec::append(
                 ~[cx.arg_mode(@~"pipe",
@@ -110,13 +110,13 @@ impl compile of gen_send for message {
 
             cx.item_fn_poly(self.name(),
                             args_ast,
-                            cx.ty_path_ast_builder(path(next.data_name())
+                            cx.ty_path_ast_builder(path(next.data_name(), span)
                                       .add_tys(next_tys)),
                             self.get_params(),
                             cx.expr_block(body))
           }
 
-          message(id, tys, this, none) {
+          message(id, span, tys, this, none) {
             #debug("pipec: no next state");
             let arg_names = tys.mapi(|i, _ty| @(~"x_" + i.to_str()));
 
@@ -126,7 +126,8 @@ impl compile of gen_send for message {
 
             let args_ast = vec::append(
                 ~[cx.arg_mode(@~"pipe",
-                              cx.ty_path_ast_builder(path(this.data_name())
+                              cx.ty_path_ast_builder(path(this.data_name(),
+                                                          span)
                                         .add_tys(cx.ty_vars(this.ty_params))),
                               ast::by_copy)],
                 args_ast);
@@ -158,7 +159,7 @@ impl compile of gen_send for message {
     }
 
     fn to_ty(cx: ext_ctxt) -> @ast::ty {
-        cx.ty_path_ast_builder(path(self.name())
+        cx.ty_path_ast_builder(path(self.name(), self.span())
           .add_tys(cx.ty_vars(self.get_params())))
     }
 }
@@ -177,7 +178,7 @@ impl compile of to_type_decls for state {
         let mut items_msg = ~[];
 
         for self.messages.each |m| {
-            let message(name, tys, this, next) = m;
+            let message(name, _span, tys, this, next) = m;
 
             let tys = alt next {
               some({state: next, tys: next_tys}) {
@@ -287,7 +288,7 @@ impl compile of gen_init for protocol {
 
     fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr {
         ext_cx.rec(self.states.map_to_vec(|s| {
-            let fty = ext_cx.ty_path_ast_builder(path(s.name));
+            let fty = ext_cx.ty_path_ast_builder(path(s.name, s.span));
             ext_cx.field_imm(s.name, #ast { pipes::mk_packet::<$(fty)>() })
         }))
     }
@@ -324,7 +325,7 @@ impl compile of gen_init for protocol {
             cx.ty_rec(
                 (copy self.states).map_to_vec(
                     |s| {
-                        let ty = cx.ty_path_ast_builder(path(s.name));
+                        let ty = cx.ty_path_ast_builder(path(s.name, s.span));
                         let fty = #ast[ty] {
                             pipes::packet<$(ty)>
                         };
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index a0091806b02..8fe995de091 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -30,23 +30,31 @@ impl methods for direction {
 type next_state = option<{state: ident, tys: ~[@ast::ty]}>;
 
 enum message {
-    // name, data, current state, next state
-    message(ident, ~[@ast::ty], state, next_state)
+    // name, span, data, current state, next state
+    message(ident, span, ~[@ast::ty], state, next_state)
 }
 
 impl methods for message {
     fn name() -> ident {
         alt self {
-          message(id, _, _, _) {
+          message(id, _, _, _, _) {
             id
           }
         }
     }
 
+    fn span() -> span {
+        alt self {
+          message(_, span, _, _, _) {
+            span
+          }
+        }
+    }
+
     /// Return the type parameters actually used by this message
     fn get_params() -> ~[ast::ty_param] {
         alt self {
-          message(_, _, this, _) {
+          message(_, _, _, this, _) {
             this.ty_params
           }
         }
@@ -57,6 +65,7 @@ enum state {
     state_(@{
         id: uint,
         name: ident,
+        span: span,
         dir: direction,
         ty_params: ~[ast::ty_param],
         messages: dvec<message>,
@@ -65,8 +74,9 @@ enum state {
 }
 
 impl methods for state {
-    fn add_message(name: ident, +data: ~[@ast::ty], next: next_state) {
-        self.messages.push(message(name, data, self,
+    fn add_message(name: ident, span: span, 
+                   +data: ~[@ast::ty], next: next_state) {
+        self.messages.push(message(name, span, data, self,
                                    next));
     }
 
@@ -80,7 +90,7 @@ impl methods for state {
 
     fn to_ty(cx: ext_ctxt) -> @ast::ty {
         cx.ty_path_ast_builder
-            (path(self.name).add_tys(cx.ty_vars(self.ty_params)))
+            (path(self.name, self.span).add_tys(cx.ty_vars(self.ty_params)))
     }
 
     /// Iterate over the states that can be reached in one message
@@ -88,7 +98,7 @@ impl methods for state {
     fn reachable(f: fn(state) -> bool) {
         for self.messages.each |m| {
             alt m {
-              message(_, _, _, some({state: id, _})) {
+              message(_, _, _, _, some({state: id, _})) {
                 let state = self.proto.get_state(id);
                 if !f(state) { break }
               }
@@ -100,16 +110,20 @@ impl methods for state {
 
 type protocol = @protocol_;
 
-fn protocol(name: ident) -> protocol { @protocol_(name) }
+fn protocol(name: ident, +span: span) -> protocol {
+    @protocol_(name, span)
+}
 
 class protocol_ {
     let name: ident;
+    let span: span;
     let states: dvec<state>;
 
     let mut bounded: option<bool>;
 
-    new(name: ident) {
+    new(name: ident, span: span) {
         self.name = name;
+        self.span = span;
         self.states = dvec();
         self.bounded = none;
     }
@@ -141,13 +155,14 @@ class protocol_ {
     }
     fn is_bounded() -> bool {
         let bounded = self.bounded.get();
-        if bounded && self.has_ty_params() {
-            #debug("protocol %s has is bounded, but type parameters\
-                    are not yet supported.",
-                   *self.name);
-            false
-        }
-        else { bounded }
+        bounded
+        //if bounded && self.has_ty_params() {
+        //    #debug("protocol %s has is bounded, but type parameters\
+        //            are not yet supported.",
+        //           *self.name);
+        //    false
+        //}
+        //else { bounded }
     }
 }
 
@@ -163,6 +178,7 @@ impl methods for protocol {
         let state = state_(@{
             id: self.states.len(),
             name: name,
+            span: self.span,
             dir: dir,
             ty_params: ty_params,
             messages: messages,
@@ -177,7 +193,7 @@ impl methods for 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, tys: &[@ast::ty],
+    fn visit_message(name: ident, spane: span, tys: &[@ast::ty],
                      this: state, next: next_state) -> Tmessage;
 }
 
@@ -187,8 +203,8 @@ fn visit<Tproto, Tstate, Tmessage, V: visitor<Tproto, Tstate, Tmessage>>(
     // the copy keywords prevent recursive use of dvec
     let states = do (copy proto.states).map_to_vec |s| {
         let messages = do (copy s.messages).map_to_vec |m| {
-            let message(name, tys, this, next) = m;
-            visitor.visit_message(name, tys, this, next)
+            let message(name, span, tys, this, next) = m;
+            visitor.visit_message(name, span, tys, this, next)
         };
         visitor.visit_state(s, messages)
     };