diff options
| author | Eric Holk <eric.holk@gmail.com> | 2012-07-24 16:58:48 -0700 |
|---|---|---|
| committer | Eric Holk <eric.holk@gmail.com> | 2012-07-25 12:12:25 -0700 |
| commit | 1dde5e7fc2ed6c1530919a0298bd3691feca3e2f (patch) | |
| tree | 5af656f1318fe06b7e51ad4c37c3592362f37677 /src/libsyntax | |
| parent | 7ecddb2771922bcd0f117a3a3f681da9bcb8b70c (diff) | |
| download | rust-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.rs | 73 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/check.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/parse_proto.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/pipec.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/proto.rs | 56 |
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) }; |
