From 487eec291b55727a92c3fefd6236778ff8f16ae0 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Sat, 21 Jan 2012 02:00:06 -0700 Subject: [PATCH 1/7] Revert "rustc: Exclude stdin from codemap files when lookup_pos". Need a better fix, right now it is just causing even more confusion, for example in issue #1448 and #1387. This reverts commit 1e4de333740690357a8f58883c5c69bf58be1424. --- src/comp/syntax/codemap.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/comp/syntax/codemap.rs b/src/comp/syntax/codemap.rs index 367bd9a02fd25..a8c76724b2696 100644 --- a/src/comp/syntax/codemap.rs +++ b/src/comp/syntax/codemap.rs @@ -34,17 +34,15 @@ type lookup_fn = fn@(file_pos) -> uint; fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc { let len = vec::len(map.files); - if len > 1u && map.files[len - 1u].name == "-" { - // the trailing "-" must be the core_macros inserted by expand_crate, - // exclude it from the targets to lookup - len = len - 1u; - } let a = 0u; let b = len; while b - a > 1u { let m = (a + b) / 2u; if lookup(map.files[m].start_pos) > pos { b = m; } else { a = m; } } + if (a >= len) { + ret { filename: "-", line: 0u, col: 0u }; + } let f = map.files[a]; a = 0u; b = vec::len(f.lines); From d25feaab003f3cd2badbb145c258dd6af02b2918 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Sat, 21 Jan 2012 02:22:54 -0700 Subject: [PATCH 2/7] Change "file" of injected string from "-" to "<anon>", less confusing that way. --- src/comp/syntax/ext/expand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comp/syntax/ext/expand.rs b/src/comp/syntax/ext/expand.rs index 09748a3168ef0..8b20bba9ce14b 100644 --- a/src/comp/syntax/ext/expand.rs +++ b/src/comp/syntax/ext/expand.rs @@ -70,7 +70,7 @@ fn expand_crate(sess: session::session, c: @crate) -> @crate { {fold_expr: bind expand_expr(exts, cx, _, _, afp.fold_expr) with *afp}; let f = make_fold(f_pre); - let cm = parse_expr_from_source_str("-", core_macros(), + let cm = parse_expr_from_source_str("<anon>", core_macros(), sess.opts.cfg, sess.parse_sess); From b705926b74ef983deb47ea9a00d9aebdab5b885c Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Sun, 22 Jan 2012 17:24:55 -0700 Subject: [PATCH 3/7] Don't reset the chpos/byte_pos to 0 in new_parser_from_source_str. This correctly fixes issue #1362. chpos/byte_pos are now the offsets within a particular file, but rather the offsets within a virtual file with is formed by combing all of the modules within a crate. Thus, resetting them to 0 causes an overlap and hence, bogus source locations. Fix #1362 by moving chpos/byte_pos to parse_sess so that new_parser_from_source_str has access to them and hence can chose an initial value that is not already been used in the crate. Note that the trigger for bug 1361 was that syntax/ext/expand.rs calls parse_expr_from_source_str (which calls new_parser_from_source_str) using the same codemap as the current crate (and hence causing overlap with files in the crate as new_parser_from_source_str resets the chpos/byte_pos to 0). --- src/cargo/cargo.rs | 4 +++- src/comp/driver/driver.rs | 4 +++- src/comp/syntax/parse/eval.rs | 15 ++++++--------- src/comp/syntax/parse/parser.rs | 34 ++++++++++++++++++++++----------- src/fuzzer/fuzzer.rs | 8 ++++++-- src/rustdoc/attr_parser.rs | 4 +++- src/rustdoc/parse.rs | 4 +++- 7 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs index a12c01de5474d..424d930e35c30 100644 --- a/src/cargo/cargo.rs +++ b/src/cargo/cargo.rs @@ -105,7 +105,9 @@ fn load_pkg(filename: str) -> option::t<pkg> { let sess = @{ cm: cm, mutable next_id: 1, - diagnostic: diagnostic::mk_handler(cm, none) + diagnostic: diagnostic::mk_handler(cm, none), + mutable chpos: 0u, + mutable byte_pos: 0u }; let c = parser::parse_crate_from_crate_file(filename, [], sess); diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs index 9d9c0542c8235..9d8d9ac03b7ba 100644 --- a/src/comp/driver/driver.rs +++ b/src/comp/driver/driver.rs @@ -488,7 +488,9 @@ fn build_session(sopts: @session::options, input: str, parse_sess: @{ cm: codemap, mutable next_id: 1, - diagnostic: diagnostic_handler + diagnostic: diagnostic_handler, + mutable chpos: 0u, + mutable byte_pos: 0u }, codemap: codemap, // For a library crate, this is always none diff --git a/src/comp/syntax/parse/eval.rs b/src/comp/syntax/parse/eval.rs index 897cfe03e09d3..ca7af9e273da8 100644 --- a/src/comp/syntax/parse/eval.rs +++ b/src/comp/syntax/parse/eval.rs @@ -14,8 +14,6 @@ export eval_crate_directives_to_mod; type ctx = @{p: parser, sess: parser::parse_sess, - mutable chpos: uint, - mutable byte_pos: uint, cfg: ast::crate_cfg}; fn eval_crate_directives(cx: ctx, cdirs: [@ast::crate_directive], prefix: str, @@ -76,12 +74,12 @@ fn parse_companion_mod(cx: ctx, prefix: str, suffix: option::t<str>) if file_exists(modpath) { #debug("found companion mod"); let p0 = new_parser_from_file(cx.sess, cx.cfg, modpath, - cx.chpos, cx.byte_pos, SOURCE_FILE); + SOURCE_FILE); let inner_attrs = parse_inner_attrs_and_next(p0); let first_item_outer_attrs = inner_attrs.next; let m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs); - cx.chpos = p0.reader.chpos; - cx.byte_pos = p0.reader.pos; + cx.sess.chpos = p0.reader.chpos; + cx.sess.byte_pos = p0.reader.pos; ret (m0.view_items, m0.items, inner_attrs.inner); } else { ret ([], [], []); @@ -108,8 +106,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, file_path } else { prefix + std::fs::path_sep() + file_path }; let p0 = - new_parser_from_file(cx.sess, cx.cfg, full_path, cx.chpos, - cx.byte_pos, SOURCE_FILE); + new_parser_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE); let inner_attrs = parse_inner_attrs_and_next(p0); let mod_attrs = attrs + inner_attrs.inner; let first_item_outer_attrs = inner_attrs.next; @@ -119,8 +116,8 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, syntax::parse::parser::mk_item(p0, cdir.span.lo, cdir.span.hi, id, ast::item_mod(m0), mod_attrs); // Thread defids, chpos and byte_pos through the parsers - cx.chpos = p0.reader.chpos; - cx.byte_pos = p0.reader.pos; + cx.sess.chpos = p0.reader.chpos; + cx.sess.byte_pos = p0.reader.pos; items += [i]; } ast::cdir_dir_mod(id, cdirs, attrs) { diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index d020c46c6a0a2..29b8bf7aab2ce 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -25,7 +25,10 @@ enum file_type { CRATE_FILE, SOURCE_FILE, } type parse_sess = @{ cm: codemap::codemap, mutable next_id: node_id, - diagnostic: diagnostic::handler + diagnostic: diagnostic::handler, + // these two must be kept up to date + mutable chpos: uint, + mutable byte_pos: uint }; fn next_node_id(sess: parse_sess) -> node_id { @@ -91,7 +94,7 @@ impl parser for parser { } fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str, - chpos: uint, byte_pos: uint, ftype: file_type) -> + ftype: file_type) -> parser { let src = alt io::read_whole_file_str(path) { result::ok(src) { @@ -102,7 +105,7 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str, sess.diagnostic.fatal(e) } }; - let filemap = codemap::new_filemap(path, chpos, byte_pos); + let filemap = codemap::new_filemap(path, sess.chpos, sess.byte_pos); sess.cm.files += [filemap]; let itr = @interner::mk(str::hash, str::eq); let rdr = lexer::new_reader(sess.cm, sess.diagnostic, @@ -113,7 +116,7 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str, fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg, name: str, source: str) -> parser { let ftype = SOURCE_FILE; - let filemap = codemap::new_filemap(name, 0u, 0u); + let filemap = codemap::new_filemap(name, sess.chpos, sess.byte_pos); sess.cm.files += [filemap]; let itr = @interner::mk(str::hash, str::eq); let rdr = lexer::new_reader(sess.cm, sess.diagnostic, @@ -2481,21 +2484,30 @@ fn parse_native_view(p: parser) -> [@ast::view_item] { fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { - let p = new_parser_from_file(sess, cfg, input, 0u, 0u, SOURCE_FILE); - ret parse_crate_mod(p, cfg); + let p = new_parser_from_file(sess, cfg, input, SOURCE_FILE); + let r = parse_crate_mod(p, cfg); + sess.chpos = p.reader.chpos; + sess.byte_pos = p.reader.pos; + ret r; } fn parse_expr_from_source_str(name: str, source: str, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::expr { let p = new_parser_from_source_str(sess, cfg, name, source); - ret parse_expr(p); + let r = parse_expr(p); + sess.chpos = p.reader.chpos; + sess.byte_pos = p.reader.pos; + ret r; } fn parse_crate_from_source_str(name: str, source: str, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { let p = new_parser_from_source_str(sess, cfg, name, source); - ret parse_crate_mod(p, cfg); + let r = parse_crate_mod(p, cfg); + sess.chpos = p.reader.chpos; + sess.byte_pos = p.reader.pos; + ret r; } // Parses a source module as a crate @@ -2588,18 +2600,18 @@ fn parse_crate_directives(p: parser, term: token::token, fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { - let p = new_parser_from_file(sess, cfg, input, 0u, 0u, CRATE_FILE); + let p = new_parser_from_file(sess, cfg, input, CRATE_FILE); let lo = p.span.lo; let prefix = std::fs::dirname(p.reader.filemap.name); let leading_attrs = parse_inner_attrs_and_next(p); let crate_attrs = leading_attrs.inner; let first_cdir_attr = leading_attrs.next; let cdirs = parse_crate_directives(p, token::EOF, first_cdir_attr); + sess.chpos = p.reader.chpos; + sess.byte_pos = p.reader.pos; let cx = @{p: p, sess: sess, - mutable chpos: p.reader.chpos, - mutable byte_pos: p.reader.pos, cfg: p.cfg}; let (companionmod, _) = fs::splitext(fs::basename(input)); let (m, attrs) = eval::eval_crate_directives_to_mod( diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index fa6c88787d487..3dbcadb944919 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -419,7 +419,9 @@ fn parse_and_print(code: str) -> str { let sess = @{ cm: cm, mutable next_id: 0, - diagnostic: diagnostic::mk_handler(cm, none) + diagnostic: diagnostic::mk_handler(cm, none), + mutable chpos: 0u, + mutable byte_pos: 0u }; write_file(filename, code); let crate = parser::parse_crate_from_source_str( @@ -566,7 +568,9 @@ fn check_variants(files: [str], cx: context) { let sess = @{ cm: cm, mutable next_id: 0, - diagnostic: diagnostic::mk_handler(cm, none) + diagnostic: diagnostic::mk_handler(cm, none), + mutable chpos: 0u, + mutable byte_pos: 0u }; let crate = parser::parse_crate_from_source_str( diff --git a/src/rustdoc/attr_parser.rs b/src/rustdoc/attr_parser.rs index f952bb1a92f92..8074b47ab5b33 100644 --- a/src/rustdoc/attr_parser.rs +++ b/src/rustdoc/attr_parser.rs @@ -289,7 +289,9 @@ mod test { let parse_sess = @{ cm: cm, mutable next_id: 0, - diagnostic: diagnostic::mk_handler(cm, none) + diagnostic: diagnostic::mk_handler(cm, none), + mutable chpos: 0u, + mutable byte_pos: 0u }; let parser = parser::new_parser_from_source_str( parse_sess, [], "-", source); diff --git a/src/rustdoc/parse.rs b/src/rustdoc/parse.rs index 0afc625378d4a..11eb469e641f9 100644 --- a/src/rustdoc/parse.rs +++ b/src/rustdoc/parse.rs @@ -12,7 +12,9 @@ fn new_parse_sess() -> parser::parse_sess { let sess = @{ cm: cm, mutable next_id: 1, - diagnostic: diagnostic::mk_handler(cm, none) + diagnostic: diagnostic::mk_handler(cm, none), + mutable chpos: 0u, + mutable byte_pos: 0u }; ret sess; } From 0801eadca8ac022e8ae576ffc9b86bdee42493dc Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Sun, 22 Jan 2012 17:30:07 -0700 Subject: [PATCH 4/7] Allow ast_fold_precursor to change the span. This involved changing the prototype for the callbacks to thread the span though. A wrapper function, fold::wrap, can be used to wrap the old style callbacks. --- src/comp/front/config.rs | 2 +- src/comp/front/test.rs | 2 +- src/comp/syntax/ext/expand.rs | 17 ++++-- src/comp/syntax/ext/simplext.rs | 70 +++++++++++----------- src/comp/syntax/fold.rs | 101 +++++++++++++++++++------------- src/fuzzer/fuzzer.rs | 4 +- 6 files changed, 113 insertions(+), 83 deletions(-) diff --git a/src/comp/front/config.rs b/src/comp/front/config.rs index c7de20bb1b3fc..684564052afc1 100644 --- a/src/comp/front/config.rs +++ b/src/comp/front/config.rs @@ -27,7 +27,7 @@ fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred) let precursor = {fold_mod: bind fold_mod(ctxt, _, _), - fold_block: bind fold_block(ctxt, _, _), + fold_block: fold::wrap(bind fold_block(ctxt, _, _)), fold_native_mod: bind fold_native_mod(ctxt, _, _) with *fold::default_ast_fold()}; diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs index 1e0c9c22bba94..05eedf09bd712 100644 --- a/src/comp/front/test.rs +++ b/src/comp/front/test.rs @@ -44,7 +44,7 @@ fn generate_test_harness(sess: session::session, mutable testfns: []}; let precursor = - {fold_crate: bind fold_crate(cx, _, _), + {fold_crate: fold::wrap(bind fold_crate(cx, _, _)), fold_item: bind fold_item(cx, _, _), fold_mod: bind fold_mod(cx, _, _) with *fold::default_ast_fold()}; diff --git a/src/comp/syntax/ext/expand.rs b/src/comp/syntax/ext/expand.rs index 8b20bba9ce14b..e749b28a41718 100644 --- a/src/comp/syntax/ext/expand.rs +++ b/src/comp/syntax/ext/expand.rs @@ -10,8 +10,13 @@ import syntax::fold::*; import syntax::ext::base::*; import syntax::parse::parser::parse_expr_from_source_str; -fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, e: expr_, - fld: ast_fold, orig: fn@(expr_, ast_fold) -> expr_) -> expr_ { +import codemap::span; + +fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, + e: expr_, s: span, fld: ast_fold, + orig: fn@(expr_, span, ast_fold) -> (expr_, span)) + -> (expr_, span) +{ ret alt e { expr_mac(mac) { alt mac.node { @@ -31,19 +36,19 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, e: expr_, let fully_expanded = fld.fold_expr(expanded).node; cx.bt_pop(); - fully_expanded + (fully_expanded, s) } some(macro_defining(ext)) { let named_extension = ext(cx, pth.span, args, body); exts.insert(named_extension.ident, named_extension.ext); - ast::expr_rec([], none) + (ast::expr_rec([], none), s) } } } _ { cx.span_bug(mac.span, "naked syntactic bit") } } } - _ { orig(e, fld) } + _ { orig(e, s, fld) } }; } @@ -67,7 +72,7 @@ fn expand_crate(sess: session::session, c: @crate) -> @crate { let afp = default_ast_fold(); let cx: ext_ctxt = mk_ctxt(sess); let f_pre = - {fold_expr: bind expand_expr(exts, cx, _, _, afp.fold_expr) + {fold_expr: bind expand_expr(exts, cx, _, _, _, afp.fold_expr) with *afp}; let f = make_fold(f_pre); let cm = parse_expr_from_source_str("<anon>", core_macros(), diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs index 891a01495ac2d..a8fe550489786 100644 --- a/src/comp/syntax/ext/simplext.rs +++ b/src/comp/syntax/ext/simplext.rs @@ -194,12 +194,12 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr { let afp = default_ast_fold(); let f_pre = {fold_ident: bind transcribe_ident(cx, b, idx_path, _, _), - fold_path: bind transcribe_path(cx, b, idx_path, _, _), + fold_path: bind transcribe_path(cx, b, idx_path, _, _, _), fold_expr: - bind transcribe_expr(cx, b, idx_path, _, _, afp.fold_expr), - fold_ty: bind transcribe_type(cx, b, idx_path, _, _, afp.fold_ty), + bind transcribe_expr(cx, b, idx_path, _, _, _, afp.fold_expr), + fold_ty: bind transcribe_type(cx, b, idx_path, _, _, _, afp.fold_ty), fold_block: - bind transcribe_block(cx, b, idx_path, _, _, afp.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), new_span: bind new_span(cx, _) with *afp}; @@ -209,7 +209,6 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr { } - /* helper: descend into a matcher */ fn follow(m: arb_depth<matchable>, idx_path: @mutable [uint]) -> arb_depth<matchable> { @@ -334,64 +333,67 @@ fn transcribe_ident(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], fn transcribe_path(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], - p: path_, _fld: ast_fold) -> path_ { + p: path_, s:span, _fld: ast_fold) -> (path_, span) { // Don't substitute into qualified names. - if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { ret p; } + if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { ret (p, s); } ret alt follow_for_trans(cx, b.find(p.idents[0]), idx_path) { some(match_ident(id)) { - {global: false, idents: [id.node], types: []} + ({global: false, idents: [id.node], types: []}, s) } - some(match_path(a_pth)) { a_pth.node } + some(match_path(a_pth)) { (a_pth.node, s) } some(m) { match_error(cx, m, "a path") } - none { p } + none { (p, s) } } } fn transcribe_expr(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], - e: ast::expr_, fld: ast_fold, - orig: fn@(ast::expr_, ast_fold) -> ast::expr_) -> - ast::expr_ { + e: ast::expr_, s: span, fld: ast_fold, + orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span)) + -> (ast::expr_, span) +{ ret alt e { expr_path(p) { // Don't substitute into qualified names. if vec::len(p.node.types) > 0u || vec::len(p.node.idents) != 1u { - e; + (e, s); } alt follow_for_trans(cx, b.find(p.node.idents[0]), idx_path) { some(match_ident(id)) { - expr_path(@respan(id.span, - {global: false, - idents: [id.node], - types: []})) + (expr_path(@respan(id.span, + {global: false, + idents: [id.node], + types: []})), s) } - some(match_path(a_pth)) { expr_path(a_pth) } - some(match_expr(a_exp)) { a_exp.node } + some(match_path(a_pth)) { (expr_path(a_pth), s) } + some(match_expr(a_exp)) { (a_exp.node, s) } some(m) { match_error(cx, m, "an expression") } - none { orig(e, fld) } + none { orig(e, s, fld) } } } - _ { orig(e, fld) } + _ { orig(e, s, fld) } } } fn transcribe_type(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], - t: ast::ty_, fld: ast_fold, - orig: fn@(ast::ty_, ast_fold) -> ast::ty_) -> ast::ty_ { + t: ast::ty_, s: span, fld: ast_fold, + orig: fn@(ast::ty_, span, ast_fold) -> (ast::ty_, span)) + -> (ast::ty_, span) +{ ret alt t { ast::ty_path(pth, _) { alt path_to_ident(pth) { some(id) { alt follow_for_trans(cx, b.find(id), idx_path) { - some(match_ty(ty)) { ty.node } + some(match_ty(ty)) { (ty.node, s) } some(m) { match_error(cx, m, "a type") } - none { orig(t, fld) } + none { orig(t, s, fld) } } } - none { orig(t, fld) } + none { orig(t, s, fld) } } } - _ { orig(t, fld) } + _ { orig(t, s, fld) } } } @@ -400,12 +402,14 @@ fn transcribe_type(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], `{v}` */ fn transcribe_block(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], - blk: blk_, fld: ast_fold, - orig: fn@(blk_, ast_fold) -> blk_) -> blk_ { + blk: blk_, s: span, fld: ast_fold, + orig: fn@(blk_, span, ast_fold) -> (blk_, span)) + -> (blk_, span) +{ ret alt block_to_ident(blk) { some(id) { alt follow_for_trans(cx, b.find(id), idx_path) { - some(match_block(new_blk)) { new_blk.node } + some(match_block(new_blk)) { (new_blk.node, s) } @@ -415,10 +419,10 @@ fn transcribe_block(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], some(m) { match_error(cx, m, "a block") } - none { orig(blk, fld) } + none { orig(blk, s, fld) } } } - none { orig(blk, fld) } + none { orig(blk, s, fld) } } } diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index 4d9b697297fbf..f4647211f611f 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -13,6 +13,7 @@ export noop_fold_expr; export noop_fold_pat; export noop_fold_mod; export noop_fold_ty; +export wrap; type ast_fold = @mutable a_f; @@ -20,28 +21,28 @@ type ast_fold = @mutable a_f; type ast_fold_precursor = //unlike the others, item_ is non-trivial - {fold_crate: fn@(crate_, ast_fold) -> crate_, - fold_crate_directive: fn@(crate_directive_, - ast_fold) -> crate_directive_, + {fold_crate: fn@(crate_, span, ast_fold) -> (crate_, span), + fold_crate_directive: fn@(crate_directive_, span, + ast_fold) -> (crate_directive_, span), fold_view_item: fn@(view_item_, ast_fold) -> view_item_, fold_native_item: fn@(&&@native_item, ast_fold) -> @native_item, fold_item: fn@(&&@item, ast_fold) -> @item, fold_item_underscore: fn@(item_, ast_fold) -> item_, fold_method: fn@(&&@method, ast_fold) -> @method, - fold_block: fn@(blk_, ast_fold) -> blk_, - fold_stmt: fn@(stmt_, ast_fold) -> stmt_, + fold_block: fn@(blk_, span, ast_fold) -> (blk_, span), + fold_stmt: fn@(stmt_, span, ast_fold) -> (stmt_, span), fold_arm: fn@(arm, ast_fold) -> arm, - fold_pat: fn@(pat_, ast_fold) -> pat_, - fold_decl: fn@(decl_, ast_fold) -> decl_, - fold_expr: fn@(expr_, ast_fold) -> expr_, - fold_ty: fn@(ty_, ast_fold) -> ty_, - fold_constr: fn@(ast::constr_, ast_fold) -> constr_, + fold_pat: fn@(pat_, span, ast_fold) -> (pat_, span), + fold_decl: fn@(decl_, span, ast_fold) -> (decl_, span), + fold_expr: fn@(expr_, span, ast_fold) -> (expr_, span), + fold_ty: fn@(ty_, span, ast_fold) -> (ty_, span), + fold_constr: fn@(ast::constr_, span, ast_fold) -> (constr_, span), fold_mod: fn@(_mod, ast_fold) -> _mod, fold_native_mod: fn@(native_mod, ast_fold) -> native_mod, - fold_variant: fn@(variant_, ast_fold) -> variant_, + fold_variant: fn@(variant_, span, ast_fold) -> (variant_, span), fold_ident: fn@(&&ident, ast_fold) -> ident, - fold_path: fn@(path_, ast_fold) -> path_, - fold_local: fn@(local_, ast_fold) -> local_, + fold_path: fn@(path_, span, ast_fold) -> (path_, span), + fold_local: fn@(local_, span, ast_fold) -> (local_, span), map_exprs: fn@(fn@(&&@expr) -> @expr, [@expr]) -> [@expr], new_id: fn@(node_id) -> node_id, new_span: fn@(span) -> span}; @@ -305,6 +306,14 @@ fn noop_fold_decl(d: decl_, fld: ast_fold) -> decl_ { } } +fn wrap<T>(f: fn@(T, ast_fold) -> T) + -> fn@(T, span, ast_fold) -> (T, span) +{ + ret fn@(x: T, s: span, fld: ast_fold) -> (T, span) { + (f(x, fld), s) + } +} + fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { fn fold_field_(field: field, fld: ast_fold) -> field { ret {node: @@ -474,27 +483,27 @@ fn noop_span(sp: span) -> span { ret sp; } fn default_ast_fold() -> @ast_fold_precursor { - ret @{fold_crate: noop_fold_crate, - fold_crate_directive: noop_fold_crate_directive, + ret @{fold_crate: wrap(noop_fold_crate), + fold_crate_directive: wrap(noop_fold_crate_directive), fold_view_item: noop_fold_view_item, fold_native_item: noop_fold_native_item, fold_item: noop_fold_item, fold_item_underscore: noop_fold_item_underscore, fold_method: noop_fold_method, - fold_block: noop_fold_block, - fold_stmt: noop_fold_stmt, + fold_block: wrap(noop_fold_block), + fold_stmt: wrap(noop_fold_stmt), fold_arm: noop_fold_arm, - fold_pat: noop_fold_pat, - fold_decl: noop_fold_decl, - fold_expr: noop_fold_expr, - fold_ty: noop_fold_ty, - fold_constr: noop_fold_constr, + fold_pat: wrap(noop_fold_pat), + fold_decl: wrap(noop_fold_decl), + fold_expr: wrap(noop_fold_expr), + fold_ty: wrap(noop_fold_ty), + fold_constr: wrap(noop_fold_constr), fold_mod: noop_fold_mod, fold_native_mod: noop_fold_native_mod, - fold_variant: noop_fold_variant, + fold_variant: wrap(noop_fold_variant), fold_ident: noop_fold_ident, - fold_path: noop_fold_path, - fold_local: noop_fold_local, + fold_path: wrap(noop_fold_path), + fold_local: wrap(noop_fold_local), map_exprs: noop_map_exprs, new_id: noop_id, new_span: noop_span}; @@ -531,12 +540,14 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold { /* 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: afp.new_span(c.span)}; + let (n, s) = afp.fold_crate(c.node, c.span, f); + ret {node: n, span: afp.new_span(s)}; } 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: afp.new_span(c.span)}; + let (n, s) = afp.fold_crate_directive(c.node, c.span, f); + ret @{node: n, + span: afp.new_span(s)}; } fn f_view_item(afp: ast_fold_precursor, f: ast_fold, &&x: @view_item) -> @view_item { @@ -559,33 +570,40 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold { ret afp.fold_method(x, f); } fn f_block(afp: ast_fold_precursor, f: ast_fold, x: blk) -> blk { - ret {node: afp.fold_block(x.node, f), span: afp.new_span(x.span)}; + let (n, s) = afp.fold_block(x.node, x.span, f); + ret {node: n, span: afp.new_span(s)}; } fn f_stmt(afp: ast_fold_precursor, f: ast_fold, &&x: @stmt) -> @stmt { - ret @{node: afp.fold_stmt(x.node, f), span: afp.new_span(x.span)}; + let (n, s) = afp.fold_stmt(x.node, x.span, f); + ret @{node: n, span: afp.new_span(s)}; } 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 { + let (n, s) = afp.fold_pat(x.node, x.span, f); ret @{id: afp.new_id(x.id), - node: afp.fold_pat(x.node, f), - span: afp.new_span(x.span)}; + node: n, + span: afp.new_span(s)}; } fn f_decl(afp: ast_fold_precursor, f: ast_fold, &&x: @decl) -> @decl { - ret @{node: afp.fold_decl(x.node, f), span: afp.new_span(x.span)}; + let (n, s) = afp.fold_decl(x.node, x.span, f); + ret @{node: n, span: afp.new_span(s)}; } fn f_expr(afp: ast_fold_precursor, f: ast_fold, &&x: @expr) -> @expr { + let (n, s) = afp.fold_expr(x.node, x.span, f); ret @{id: afp.new_id(x.id), - node: afp.fold_expr(x.node, f), - span: afp.new_span(x.span)}; + node: n, + span: afp.new_span(s)}; } fn f_ty(afp: ast_fold_precursor, f: ast_fold, &&x: @ty) -> @ty { - ret @{node: afp.fold_ty(x.node, f), span: afp.new_span(x.span)}; + let (n, s) = afp.fold_ty(x.node, x.span, f); + ret @{node: n, span: afp.new_span(s)}; } fn f_constr(afp: ast_fold_precursor, f: ast_fold, &&x: @ast::constr) -> @ast::constr { - ret @{node: afp.fold_constr(x.node, f), span: afp.new_span(x.span)}; + let (n, s) = afp.fold_constr(x.node, x.span, f); + ret @{node: n, span: afp.new_span(s)}; } fn f_mod(afp: ast_fold_precursor, f: ast_fold, x: _mod) -> _mod { ret afp.fold_mod(x, f); @@ -596,16 +614,19 @@ 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: afp.new_span(x.span)}; + let (n, s) = afp.fold_variant(x.node, x.span, f); + ret {node: n, span: afp.new_span(s)}; } 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: afp.new_span(x.span)}; + let (n, s) = afp.fold_path(x.node, x.span, f); + ret @{node: n, span: afp.new_span(s)}; } fn f_local(afp: ast_fold_precursor, f: ast_fold, &&x: @local) -> @local { - ret @{node: afp.fold_local(x.node, f), span: afp.new_span(x.span)}; + let (n, s) = afp.fold_local(x.node, x.span, f); + ret @{node: n, span: afp.new_span(s)}; } *result = diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 3dbcadb944919..b905bfddddec1 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -187,7 +187,7 @@ fn replace_expr_in_crate(crate: ast::crate, i: uint, newexpr: ast::expr, tm: tes } } let afp = - {fold_expr: bind fold_expr_rep(j, i, newexpr.node, _, _, tm) + {fold_expr: fold::wrap(bind fold_expr_rep(j, i, newexpr.node, _, _, tm)) with *fold::default_ast_fold()}; let af = fold::make_fold(afp); let crate2: @ast::crate = @af.fold_crate(crate); @@ -208,7 +208,7 @@ fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::ty, tm: test_mode } else { fold::noop_fold_ty(original, fld) } } let afp = - {fold_ty: bind fold_ty_rep(j, i, newty.node, _, _, tm) + {fold_ty: fold::wrap(bind fold_ty_rep(j, i, newty.node, _, _, tm)) with *fold::default_ast_fold()}; let af = fold::make_fold(afp); let crate2: @ast::crate = @af.fold_crate(crate); From 308b5e90bb7472e5a6f404dd5c4b7ccb0472572d Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Sat, 21 Jan 2012 18:49:51 -0700 Subject: [PATCH 5/7] When replacing a pattern variable in macro expansion use the span of the replacement and not the span of the pattern variable. Fixes issue #1448, and #1387. --- src/comp/syntax/ext/simplext.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs index a8fe550489786..dcaf16c973efb 100644 --- a/src/comp/syntax/ext/simplext.rs +++ b/src/comp/syntax/ext/simplext.rs @@ -338,9 +338,9 @@ fn transcribe_path(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { ret (p, s); } ret alt follow_for_trans(cx, b.find(p.idents[0]), idx_path) { some(match_ident(id)) { - ({global: false, idents: [id.node], types: []}, s) + ({global: false, idents: [id.node], types: []}, id.span) } - some(match_path(a_pth)) { (a_pth.node, s) } + some(match_path(a_pth)) { (a_pth.node, a_pth.span) } some(m) { match_error(cx, m, "a path") } none { (p, s) } } @@ -363,10 +363,10 @@ fn transcribe_expr(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], (expr_path(@respan(id.span, {global: false, idents: [id.node], - types: []})), s) + types: []})), id.span) } some(match_path(a_pth)) { (expr_path(a_pth), s) } - some(match_expr(a_exp)) { (a_exp.node, s) } + some(match_expr(a_exp)) { (a_exp.node, a_exp.span) } some(m) { match_error(cx, m, "an expression") } none { orig(e, s, fld) } } @@ -385,7 +385,7 @@ fn transcribe_type(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], alt path_to_ident(pth) { some(id) { alt follow_for_trans(cx, b.find(id), idx_path) { - some(match_ty(ty)) { (ty.node, s) } + some(match_ty(ty)) { (ty.node, ty.span) } some(m) { match_error(cx, m, "a type") } none { orig(t, s, fld) } } @@ -409,7 +409,7 @@ fn transcribe_block(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint], ret alt block_to_ident(blk) { some(id) { alt follow_for_trans(cx, b.find(id), idx_path) { - some(match_block(new_blk)) { (new_blk.node, s) } + some(match_block(new_blk)) { (new_blk.node, new_blk.span) } From afd03f38ced85337fa0b71f166acac2a6edc8810 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Mon, 23 Jan 2012 00:29:11 -0700 Subject: [PATCH 6/7] Add regresion tests for issue #1448 and #1387. --- src/test/compile-fail/issue-1448-1.rs | 7 +++++++ src/test/compile-fail/issue-1448-2.rs | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 src/test/compile-fail/issue-1448-1.rs create mode 100644 src/test/compile-fail/issue-1448-2.rs diff --git a/src/test/compile-fail/issue-1448-1.rs b/src/test/compile-fail/issue-1448-1.rs new file mode 100644 index 0000000000000..8c3617a99da7c --- /dev/null +++ b/src/test/compile-fail/issue-1448-1.rs @@ -0,0 +1,7 @@ +// Regresion test for issue #1448 and #1386 + +fn main() { + #macro[[#apply[f, [x, ...]], f(x, ...)]]; + fn add(a: int, b: int) -> int { ret a + b; } + assert (#apply[add, [y, 15]] == 16); //! ERROR unresolved name: y +} diff --git a/src/test/compile-fail/issue-1448-2.rs b/src/test/compile-fail/issue-1448-2.rs new file mode 100644 index 0000000000000..548523ecb45e7 --- /dev/null +++ b/src/test/compile-fail/issue-1448-2.rs @@ -0,0 +1,5 @@ +// Regresion test for issue #1448 and #1386 + +fn main() { + #debug["%u", 10]; //! ERROR mismatched types +} From fea5b26d628be5c1ce0e0232c9bf7d24a5b8ad8f Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <kevina@cs.utah.edu> Date: Mon, 23 Jan 2012 01:08:47 -0700 Subject: [PATCH 7/7] Add regression test for issue #1362. Although its not really needed. Without that fix, reported spans will likely be bogus if the error is within the first couple of lines (probable around 5) of that file. Thus, many of the compile-fail tests will fail due to incorrect location. --- src/test/compile-fail/issue-1362.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/test/compile-fail/issue-1362.rs diff --git a/src/test/compile-fail/issue-1362.rs b/src/test/compile-fail/issue-1362.rs new file mode 100644 index 0000000000000..685bc4419438d --- /dev/null +++ b/src/test/compile-fail/issue-1362.rs @@ -0,0 +1,8 @@ +// Regression test for issue #1362 +// (without out that fix the location will be bogus) +fn main() { + let x: uint = 20; //! ERROR mismatched types +} +// NOTE: Do not add any extra lines as the line number the error is +// on is significant; an error later in the source file might not +// trigger the bug.