Use span stacks to track macro expansion for less troublesome error messages.

This commit is contained in:
Paul Stansifer 2011-08-15 13:33:12 -07:00
parent c48036c0b7
commit ebb16e6a25
8 changed files with 63 additions and 37 deletions

View file

@ -153,7 +153,7 @@ fn parse_ty_constr_arg(st: @pstate, sd: str_def) ->
fn parse_constr[@T](st: @pstate, sd: str_def, pser: arg_parser[T]) ->
@ty::constr_general[T] {
let sp = ast::dummy_sp(); // FIXME: use a real span
let args: [@sp_constr_arg[T]][] = ~[];
let args: [@sp_constr_arg[T]] = ~[];
let pth: path = parse_path(st, sd);
let ignore: char = next(st) as char;
assert (ignore as char == '(');

View file

@ -127,7 +127,7 @@ fn node_span(node: &ast_node) -> codemap::span {
mod test {
#[test]
fn test_node_span_item() {
let expected: codemap::span = {lo: 20u, hi: 30u};
let expected: codemap::span = mk_sp(20u, 30u);
let node = node_item(@{ident: "test",
attrs: ~[],
id: 0,
@ -139,7 +139,7 @@ mod test {
#[test]
fn test_node_span_obj_ctor() {
let expected: codemap::span = {lo: 20u, hi: 30u};
let expected: codemap::span = mk_sp(20u, 30u);
let node = node_obj_ctor(@{ident: "test",
attrs: ~[],
id: 0,
@ -151,7 +151,7 @@ mod test {
#[test]
fn test_node_span_native_item() {
let expected: codemap::span = {lo: 20u, hi: 30u};
let expected: codemap::span = mk_sp(20u, 30u);
let node = node_native_item(@{ident: "test",
attrs: ~[],
node: native_item_ty,
@ -162,7 +162,7 @@ mod test {
#[test]
fn test_node_span_expr() {
let expected: codemap::span = {lo: 20u, hi: 30u};
let expected: codemap::span = mk_sp(20u, 30u);
let node = node_expr(@{id: 0,
node: expr_break,
span: expected});

View file

@ -49,7 +49,7 @@ fn pattern_supersedes(tcx: &ty::ctxt, a: &@pat, b: &@pat) -> bool {
}
fn field_patterns_supersede(tcx: &ty::ctxt, fas: &[field_pat],
fbs: &[field_pat]) -> bool {
let wild = @{id: 0, node: pat_wild, span: dummy_sp();
let wild = @{id: 0, node: pat_wild, span: dummy_sp()};
for fa: field_pat in fas {
let pb = wild;
for fb: field_pat in fbs {

View file

@ -126,7 +126,7 @@ fn enter_opt(ccx: &@crate_ctxt, m: &match, opt: &opt, col: uint,
fn enter_rec(m: &match, col: uint, fields: &[ast::ident], val: ValueRef) ->
match {
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp();
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
fn e(dummy: &@ast::pat, fields: &[ast::ident], p: &@ast::pat) ->
option::t[[@ast::pat]] {
alt p.node {
@ -148,7 +148,7 @@ fn enter_rec(m: &match, col: uint, fields: &[ast::ident], val: ValueRef) ->
}
fn enter_tup(m: &match, col: uint, val: ValueRef, n_elts: uint) -> match {
let dummy = @{id: 0, node: ast::pat_wild, span: {lo: 0u, hi: 0u}};
let dummy = @{id: 0, node: ast::pat_wild, span: dummy_sp()};
fn e(dummy: &@ast::pat, n_elts: uint, p: &@ast::pat)
-> option::t[[@ast::pat]] {
alt p.node {

View file

@ -35,19 +35,29 @@ fn syntax_expander_table() -> hashmap[str, syntax_extension] {
}
obj ext_ctxt(sess: @session, crate_file_name_hack: str,
mutable backtrace: span[]) {
mutable backtrace: codemap::opt_span) {
fn crate_file_name() -> str { ret crate_file_name_hack; }
fn session() -> @session { ret sess; }
fn print_backtrace() {
for sp: span in backtrace {
sess.span_note(sp, "(while expanding this)")
}
}
fn bt_push(sp: span) { backtrace += ~[sp]; }
fn bt_pop() { ivec::pop(backtrace); }
fn backtrace() -> codemap::opt_span { ret backtrace; }
fn bt_push(sp: span) {
backtrace = codemap::os_some(@{lo: sp.lo, hi: sp.hi,
expanded_from: backtrace});
}
fn bt_pop() {
alt backtrace {
codemap::os_some(@{expanded_from: pre, _}) {
let tmp = pre;
backtrace = tmp;
}
_ { self.bug("tried to pop without a push"); }
}
}
fn span_fatal(sp: span, msg: str) -> ! {
self.print_backtrace();
@ -85,7 +95,7 @@ fn mk_ctxt(sess: &session) -> ext_ctxt {
// super-ugly and needs a better solution.
let crate_file_name_hack = sess.get_codemap().files.(0).name;
ret ext_ctxt(@sess, crate_file_name_hack, ~[]);
ret ext_ctxt(@sess, crate_file_name_hack, codemap::os_none);
}
fn expr_to_str(cx: &ext_ctxt, expr: @ast::expr, error: str) -> str {

View file

@ -205,6 +205,10 @@ fn use_selectors_to_bind(b: &binders, e: @expr) -> option::t[bindings] {
fn transcribe(cx: &ext_ctxt, b: &bindings, body: @expr) -> @expr {
let idx_path: @mutable [uint] = @mutable ~[];
fn new_id(old: node_id, cx: &ext_ctxt) -> node_id { ret cx.next_id(); }
fn new_span(cx: &ext_ctxt, sp: &span) -> span {
/* this discards information in the case of macro-defining macros */
ret {lo: sp.lo, hi: sp.hi, expanded_from: cx.backtrace()};
}
let afp = default_ast_fold();
let f_pre =
{fold_ident: bind transcribe_ident(cx, b, idx_path, _, _),
@ -215,7 +219,8 @@ fn transcribe(cx: &ext_ctxt, b: &bindings, body: @expr) -> @expr {
fold_block:
bind transcribe_block(cx, b, idx_path, _, _, afp.fold_block),
map_exprs: bind transcribe_exprs(cx, b, idx_path, _, _),
new_id: bind new_id(_, cx) with *afp};
new_id: bind new_id(_, cx),
new_span: bind new_span(cx, _) with *afp};
let f = make_fold(f_pre);
let result = f.fold_expr(body);
dummy_out(f); //temporary: kill circular reference

View file

@ -44,7 +44,8 @@ type ast_fold_precursor =
fold_path: fn(&path_, ast_fold) -> path_ ,
fold_local: fn(&local_, ast_fold) -> local_ ,
map_exprs: fn(fn(&@expr) -> @expr , [@expr]) -> [@expr],
new_id: fn(node_id) -> node_id};
new_id: fn(node_id) -> node_id,
new_span: fn(&span) -> span};
type a_f =
{fold_crate: fn(&crate) -> crate ,
@ -70,7 +71,8 @@ type a_f =
fold_path: fn(&path) -> path ,
fold_local: fn(&@local) -> @local ,
map_exprs: fn(fn(&@expr) -> @expr , [@expr]) -> [@expr],
new_id: fn(node_id) -> node_id};
new_id: fn(node_id) -> node_id,
new_span: fn(&span) -> span};
//fn nf_dummy[T](&T node) -> T { fail; }
@ -514,6 +516,8 @@ fn noop_map_exprs(f: fn(&@expr) -> @expr , es: [@expr]) -> [@expr] {
fn noop_id(i: node_id) -> node_id { ret i; }
fn noop_span(sp: &span) -> span { ret sp; }
fn default_ast_fold() -> @ast_fold_precursor {
ret @{fold_crate: noop_fold_crate,
@ -539,7 +543,8 @@ fn default_ast_fold() -> @ast_fold_precursor {
fold_path: noop_fold_path,
fold_local: noop_fold_local,
map_exprs: noop_map_exprs,
new_id: noop_id};
new_id: noop_id,
new_span: noop_span};
}
fn dummy_out(a: ast_fold) {
@ -567,7 +572,8 @@ fn dummy_out(a: ast_fold) {
fold_path: nf_path_dummy,
fold_local: nf_local_dummy,
map_exprs: noop_map_exprs,
new_id: noop_id};
new_id: noop_id,
new_span: noop_span};
}
@ -596,19 +602,22 @@ fn make_fold(afp: &ast_fold_precursor) -> ast_fold {
fold_path: nf_path_dummy,
fold_local: nf_local_dummy,
map_exprs: noop_map_exprs,
new_id: noop_id};
new_id: noop_id,
new_span: noop_span};
/* naturally, a macro to write these would be nice */
fn f_crate(afp: &ast_fold_precursor, f: ast_fold, c: &crate) -> crate {
ret {node: afp.fold_crate(c.node, f), span: c.span};
ret {node: afp.fold_crate(c.node, f), span: afp.new_span(c.span)};
}
fn f_crate_directive(afp: &ast_fold_precursor, f: ast_fold,
c: &@crate_directive) -> @crate_directive {
ret @{node: afp.fold_crate_directive(c.node, f), span: c.span};
ret @{node: afp.fold_crate_directive(c.node, f),
span: afp.new_span(c.span)};
}
fn f_view_item(afp: &ast_fold_precursor, f: ast_fold, x: &@view_item) ->
@view_item {
ret @{node: afp.fold_view_item(x.node, f), span: x.span};
ret @{node: afp.fold_view_item(x.node, f),
span: afp.new_span(x.span)};
}
fn f_native_item(afp: &ast_fold_precursor, f: ast_fold, x: &@native_item)
-> @native_item {
@ -623,34 +632,34 @@ fn make_fold(afp: &ast_fold_precursor) -> ast_fold {
}
fn f_method(afp: &ast_fold_precursor, f: ast_fold, x: &@method) ->
@method {
ret @{node: afp.fold_method(x.node, f), span: x.span};
ret @{node: afp.fold_method(x.node, f), span: afp.new_span(x.span)};
}
fn f_block(afp: &ast_fold_precursor, f: ast_fold, x: &blk) -> blk {
ret {node: afp.fold_block(x.node, f), span: x.span};
ret {node: afp.fold_block(x.node, f), span: afp.new_span(x.span)};
}
fn f_stmt(afp: &ast_fold_precursor, f: ast_fold, x: &@stmt) -> @stmt {
ret @{node: afp.fold_stmt(x.node, f), span: x.span};
ret @{node: afp.fold_stmt(x.node, f), span: afp.new_span(x.span)};
}
fn f_arm(afp: &ast_fold_precursor, f: ast_fold, x: &arm) -> arm {
ret afp.fold_arm(x, f);
}
fn f_pat(afp: &ast_fold_precursor, f: ast_fold, x: &@pat) -> @pat {
ret @{id: afp.new_id(x.id),
node: afp.fold_pat(x.node, f), span: x.span};
node: afp.fold_pat(x.node, f), span: afp.new_span(x.span)};
}
fn f_decl(afp: &ast_fold_precursor, f: ast_fold, x: &@decl) -> @decl {
ret @{node: afp.fold_decl(x.node, f), span: x.span};
ret @{node: afp.fold_decl(x.node, f), span: afp.new_span(x.span)};
}
fn f_expr(afp: &ast_fold_precursor, f: ast_fold, x: &@expr) -> @expr {
ret @{id: afp.new_id(x.id),
node: afp.fold_expr(x.node, f), span: x.span};
node: afp.fold_expr(x.node, f), span: afp.new_span(x.span)};
}
fn f_ty(afp: &ast_fold_precursor, f: ast_fold, x: &@ty) -> @ty {
ret @{node: afp.fold_ty(x.node, f), span: x.span};
ret @{node: afp.fold_ty(x.node, f), span: afp.new_span(x.span)};
}
fn f_constr(afp: &ast_fold_precursor, f: ast_fold, x: &@ast::constr) ->
@ast::constr {
ret @{node: afp.fold_constr(x.node, f), span: x.span};
ret @{node: afp.fold_constr(x.node, f), span: afp.new_span(x.span)};
}
fn f_fn(afp: &ast_fold_precursor, f: ast_fold, x: &_fn) -> _fn {
ret afp.fold_fn(x, f);
@ -664,16 +673,16 @@ fn make_fold(afp: &ast_fold_precursor) -> ast_fold {
}
fn f_variant(afp: &ast_fold_precursor, f: ast_fold, x: &variant) ->
variant {
ret {node: afp.fold_variant(x.node, f), span: x.span};
ret {node: afp.fold_variant(x.node, f), span: afp.new_span(x.span)};
}
fn f_ident(afp: &ast_fold_precursor, f: ast_fold, x: &ident) -> ident {
ret afp.fold_ident(x, f);
}
fn f_path(afp: &ast_fold_precursor, f: ast_fold, x: &path) -> path {
ret {node: afp.fold_path(x.node, f), span: x.span};
ret {node: afp.fold_path(x.node, f), span: afp.new_span(x.span)};
}
fn f_local(afp: &ast_fold_precursor, f: ast_fold, x: &@local) -> @local {
ret @{node: afp.fold_local(x.node, f), span: x.span};
ret @{node: afp.fold_local(x.node, f), span: afp.new_span(x.span)};
}
*result =
@ -700,7 +709,8 @@ fn make_fold(afp: &ast_fold_precursor) -> ast_fold {
fold_path: bind f_path(afp, result, _),
fold_local: bind f_local(afp, result, _),
map_exprs: afp.map_exprs,
new_id: afp.new_id};
new_id: afp.new_id,
new_span: afp.new_span};
ret result;
}

View file

@ -1478,7 +1478,8 @@ fn parse_pat(p: &parser) -> @ast::pat {
if p.peek() == token::RPAREN {
hi = p.get_hi_pos();
p.bump();
pat = ast::pat_lit(@{node: ast::lit_nil, span: {lo: lo, hi: hi}});
pat = ast::pat_lit(@{node: ast::lit_nil,
span: ast::mk_sp(lo,hi)});
} else {
let fields = ~[parse_pat(p)];
while p.peek() == token::COMMA {