Skip to content

Commit 4026053

Browse files
committed
Do a better job of reporting source location for files (i.e. filemap)
that are really a substr of another file.
1 parent a7c362a commit 4026053

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed

src/comp/driver/diagnostic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ fn emit(cmsp: option<(codemap::codemap, span)>,
175175
msg: str, lvl: level) {
176176
alt cmsp {
177177
some((cm, sp)) {
178+
let sp = codemap::adjust_span(cm,sp);
178179
let ss = codemap::span_to_str(sp, cm);
179180
let lines = codemap::span_to_lines(sp, cm);
180181
print_diagnostic(ss, lvl, msg);

src/comp/syntax/codemap.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ fn get_substr_info(cm: codemap, sp: span)
4646
let pos = lookup_char_pos(cm, sp.lo);
4747
let name = #fmt("<%s:%u:%u>", pos.file.name, pos.line, pos.col);
4848
ret (name, fss_internal(sp));
49+
//ret (name, fss_external({filename: pos.file.name,
50+
// line: pos.line, col: pos.col}));
4951
}
5052

5153
fn next_line(file: filemap, chpos: uint, byte_pos: uint) {
@@ -92,26 +94,66 @@ fn lookup_byte_pos(map: codemap, pos: uint) -> loc {
9294
ret lookup_pos(map, pos, lookup);
9395
}
9496

97+
fn lookup_char_pos_adj(map: codemap, pos: uint)
98+
-> {filename: str, line: uint, col: uint, file: option<filemap>}
99+
{
100+
let loc = lookup_char_pos(map, pos);
101+
alt (loc.file.substr) {
102+
fss_none {
103+
{filename: loc.file.name, line: loc.line, col: loc.col,
104+
file: some(loc.file)}
105+
}
106+
fss_internal(sp) {
107+
lookup_char_pos_adj(map, sp.lo + (pos - loc.file.start_pos.ch))
108+
}
109+
fss_external(eloc) {
110+
{filename: eloc.filename,
111+
line: eloc.line + loc.line - 1u,
112+
col: if loc.line == 1u {eloc.col + loc.col} else {loc.col},
113+
file: none}
114+
}
115+
}
116+
}
117+
118+
fn adjust_span(map: codemap, sp: span) -> span {
119+
fn lookup(pos: file_pos) -> uint { ret pos.ch; }
120+
let line = lookup_line(map, sp.lo, lookup);
121+
alt (line.fm.substr) {
122+
fss_none {sp}
123+
fss_internal(s) {
124+
adjust_span(map, {lo: s.lo + (sp.lo - line.fm.start_pos.ch),
125+
hi: s.lo + (sp.hi - line.fm.start_pos.ch),
126+
expn_info: sp.expn_info})}
127+
fss_external(_) {sp}
128+
}
129+
}
130+
95131
enum expn_info_ {
96132
expanded_from({call_site: span,
97133
callie: {name: str, span: option<span>}})
98134
}
99135
type expn_info = option<@expn_info_>;
100136
type span = {lo: uint, hi: uint, expn_info: expn_info};
101137

102-
fn span_to_str(sp: span, cm: codemap) -> str {
138+
fn span_to_str_no_adj(sp: span, cm: codemap) -> str {
103139
let lo = lookup_char_pos(cm, sp.lo);
104140
let hi = lookup_char_pos(cm, sp.hi);
105141
ret #fmt("%s:%u:%u: %u:%u", lo.file.name,
106142
lo.line, lo.col, hi.line, hi.col)
107143
}
108144

145+
fn span_to_str(sp: span, cm: codemap) -> str {
146+
let lo = lookup_char_pos_adj(cm, sp.lo);
147+
let hi = lookup_char_pos_adj(cm, sp.hi);
148+
ret #fmt("%s:%u:%u: %u:%u", lo.filename,
149+
lo.line, lo.col, hi.line, hi.col)
150+
}
151+
109152
type file_lines = {file: filemap, lines: [uint]};
110153

111154
fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines {
112155
let lo = lookup_char_pos(cm, sp.lo);
113156
let hi = lookup_char_pos(cm, sp.hi);
114-
// FIXME: Check for filemap?
115157
let lines = [];
116158
uint::range(lo.line - 1u, hi.line as uint) {|i| lines += [i]; };
117159
ret @{file: lo.file, lines: lines};

src/test/compile-fail/qquote.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// xfail-pretty
2+
3+
use std;
4+
use rustc;
5+
6+
import rustc::*;
7+
import std::io::*;
8+
9+
import rustc::driver::diagnostic;
10+
import rustc::syntax::ast;
11+
import rustc::syntax::codemap;
12+
import rustc::syntax::parse::parser;
13+
import rustc::syntax::print::*;
14+
15+
fn new_parse_sess() -> parser::parse_sess {
16+
fail;
17+
}
18+
19+
iface fake_ext_ctxt {
20+
fn session() -> fake_session;
21+
}
22+
23+
type fake_options = {cfg: ast::crate_cfg};
24+
25+
type fake_session = {opts: @fake_options,
26+
parse_sess: parser::parse_sess};
27+
28+
impl of fake_ext_ctxt for fake_session {
29+
fn session() -> fake_session {self}
30+
}
31+
32+
fn mk_ctxt() -> fake_ext_ctxt {
33+
let opts : fake_options = {cfg: []};
34+
{opts: @opts, parse_sess: new_parse_sess()} as fake_ext_ctxt
35+
}
36+
37+
38+
fn main() {
39+
let ext_cx = mk_ctxt();
40+
41+
let abc = #ast{23};
42+
check_pp(abc, pprust::print_expr, "23");
43+
44+
let expr3 = #ast{2 - $(abcd) + 7}; //! ERROR unresolved name: abcd
45+
check_pp(expr3, pprust::print_expr, "2 - 23 + 7");
46+
}
47+
48+
fn check_pp<T>(expr: T, f: fn(pprust::ps, T), expect: str) {
49+
fail;
50+
}
51+

0 commit comments

Comments
 (0)