Skip to content

Commit b329f2f

Browse files
committed
auto merge of #5798 : recrack/rust/multiple-errors, r=brson
Fix #4569.
2 parents 348dc25 + 6030e39 commit b329f2f

File tree

1 file changed

+147
-13
lines changed

1 file changed

+147
-13
lines changed

src/libsyntax/diagnostic.rs

+147-13
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub trait handler {
3333
fn bump_err_count(@mut self);
3434
fn has_errors(@mut self) -> bool;
3535
fn abort_if_errors(@mut self);
36+
fn abort_error_print(@mut self);
3637
fn warn(@mut self, msg: &str);
3738
fn note(@mut self, msg: &str);
3839
// used to indicate a bug in the compiler:
@@ -42,6 +43,7 @@ pub trait handler {
4243
cmsp: Option<(@codemap::CodeMap, span)>,
4344
msg: &str,
4445
lvl: level);
46+
fn emit_print(@mut self, lvl: level);
4547
}
4648

4749
// a span-handler is like a handler but also
@@ -57,8 +59,15 @@ pub trait span_handler {
5759
fn handler(@mut self) -> @handler;
5860
}
5961

62+
struct emitter_arg {
63+
cmsp: Option<(@codemap::CodeMap, span)>,
64+
msg: ~str,
65+
lvl: level,
66+
}
67+
6068
struct HandlerT {
6169
err_count: uint,
70+
emitters: ~[emitter_arg],
6271
emit: Emitter,
6372
}
6473

@@ -69,15 +78,19 @@ struct CodemapT {
6978

7079
impl span_handler for CodemapT {
7180
fn span_fatal(@mut self, sp: span, msg: &str) -> ! {
81+
self.handler.bump_err_count();
7282
self.handler.emit(Some((self.cm, sp)), msg, fatal);
83+
self.handler.emit_print(error);
84+
self.handler.emit_print(note);
85+
self.handler.abort_error_print();
7386
fail!();
7487
}
7588
fn span_err(@mut self, sp: span, msg: &str) {
7689
self.handler.emit(Some((self.cm, sp)), msg, error);
7790
self.handler.bump_err_count();
7891
}
7992
fn span_warn(@mut self, sp: span, msg: &str) {
80-
self.handler.emit(Some((self.cm, sp)), msg, warning);
93+
emit_one(Some((self.cm, sp)), msg, warning);
8194
}
8295
fn span_note(@mut self, sp: span, msg: &str) {
8396
self.handler.emit(Some((self.cm, sp)), msg, note);
@@ -95,11 +108,13 @@ impl span_handler for CodemapT {
95108
96109
impl handler for HandlerT {
97110
fn fatal(@mut self, msg: &str) -> ! {
98-
(self.emit)(None, msg, fatal);
111+
self.emit_print(error);
112+
self.emit_print(note);
113+
emit_one(None, msg, fatal);
99114
fail!();
100115
}
101116
fn err(@mut self, msg: &str) {
102-
(self.emit)(None, msg, error);
117+
emit_one(None, msg, error);
103118
self.bump_err_count();
104119
}
105120
fn bump_err_count(@mut self) {
@@ -118,13 +133,26 @@ impl handler for HandlerT {
118133
}
119134
self.fatal(s);
120135
}
136+
fn abort_error_print(@mut self) {
137+
let s;
138+
match self.err_count {
139+
0u => return,
140+
1u => s = ~"aborting due to previous error",
141+
_ => {
142+
s = fmt!("aborting due to %u previous errors",
143+
self.err_count);
144+
}
145+
}
146+
emit_one(None, s, fatal);
147+
}
121148
fn warn(@mut self, msg: &str) {
122-
(self.emit)(None, msg, warning);
149+
emit_one(None, msg, warning);
123150
}
124151
fn note(@mut self, msg: &str) {
125-
(self.emit)(None, msg, note);
152+
self.emit(None, msg, note);
126153
}
127154
fn bug(@mut self, msg: &str) -> ! {
155+
self.bump_err_count();
128156
self.fatal(ice_msg(msg));
129157
}
130158
fn unimpl(@mut self, msg: &str) -> ! {
@@ -135,6 +163,50 @@ impl handler for HandlerT {
135163
msg: &str,
136164
lvl: level) {
137165
(self.emit)(cmsp, msg, lvl);
166+
let emitter = emitter_arg { cmsp: cmsp,
167+
msg: str::from_slice(msg),
168+
lvl: lvl };
169+
self.emitters.push(emitter);
170+
}
171+
172+
fn emit_print(@mut self, lvl: level) {
173+
let mut old_cmsp = None;
174+
let mut old_line = 0u;
175+
176+
let emitters = self.emitters;
177+
let length = emitters.len();
178+
for uint::range(0, length) |i| {
179+
let emitter = copy self.emitters[i];
180+
let cmsp = emitter.cmsp;
181+
let msg = emitter.msg;
182+
if diagnosticstr(lvl) == diagnosticstr(emitter.lvl) {
183+
match cmsp {
184+
Some((cm, sp)) => {
185+
let lo = cm.lookup_char_pos_adj(sp.lo);
186+
let sp = cm.adjust_span(sp);
187+
let ss = cm.span_to_str(sp);
188+
if i == 0 || old_line == lo.line {
189+
if old_line == lo.line {
190+
highlight_lines_cmp(cmsp, old_cmsp);
191+
}
192+
print_diagnostic(ss, lvl, msg);
193+
highlight_lines_cmp(old_cmsp, cmsp);
194+
} else {
195+
highlight_lines(old_cmsp);
196+
print_macro_backtrace(old_cmsp);
197+
print_diagnostic(ss, lvl, msg);
198+
}
199+
old_line = lo.line;
200+
old_cmsp = emitter.cmsp;
201+
}
202+
None => {
203+
print_diagnostic(~"", lvl, msg);
204+
}
205+
}
206+
}
207+
}
208+
highlight_lines(old_cmsp);
209+
print_macro_backtrace(old_cmsp);
138210
}
139211
}
140212

@@ -156,7 +228,9 @@ pub fn mk_handler(emitter: Option<Emitter>) -> @handler {
156228
}
157229
};
158230

159-
@mut HandlerT { err_count: 0, emit: emit } as @handler
231+
@mut HandlerT { err_count: 0,
232+
emitters: ~[],
233+
emit: emit } as @handler
160234
}
161235

162236
#[deriving(Eq)]
@@ -208,23 +282,27 @@ pub fn collect(messages: @mut ~[~str])
208282
f
209283
}
210284

211-
pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) {
285+
pub fn emit(_cmsp: Option<(@codemap::CodeMap, span)>, _msg: &str, _lvl: level) {
286+
// Nothing to do
287+
}
288+
289+
pub fn emit_one(cmsp: Option<(@codemap::CodeMap, span)>,
290+
msg: &str, lvl: level) {
212291
match cmsp {
213292
Some((cm, sp)) => {
214293
let sp = cm.adjust_span(sp);
215294
let ss = cm.span_to_str(sp);
216-
let lines = cm.span_to_lines(sp);
217295
print_diagnostic(ss, lvl, msg);
218-
highlight_lines(cm, sp, lines);
219-
print_macro_backtrace(cm, sp);
296+
highlight_lines(cmsp);
297+
print_macro_backtrace(cmsp);
220298
}
221299
None => {
222300
print_diagnostic(~"", lvl, msg);
223301
}
224302
}
225303
}
226304

227-
fn highlight_lines(cm: @codemap::CodeMap,
305+
fn highlight_lines_internal(cm: @codemap::CodeMap,
228306
sp: span,
229307
lines: @codemap::FileLines) {
230308
let fm = lines.file;
@@ -291,14 +369,70 @@ fn highlight_lines(cm: @codemap::CodeMap,
291369
}
292370
}
293371

294-
fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) {
372+
fn highlight_lines(cmsp: Option<(@codemap::CodeMap, span)>) {
373+
match cmsp {
374+
Some((cm, sp)) => {
375+
let sp = cm.adjust_span(sp);
376+
let lines = cm.span_to_lines(sp);
377+
highlight_lines_internal(cm, sp, lines);
378+
}
379+
None => ()
380+
}
381+
}
382+
383+
fn highlight_lines_cmp(old_cmsp: Option<(@codemap::CodeMap, span)>,
384+
cmsp: Option<(@codemap::CodeMap, span)> ){
385+
let mut old_line = ~[];
386+
let mut new_line = ~[];
387+
let mut old_lo = 0u;
388+
let mut new_lo = 0u;
389+
let mut flag = true;
390+
match old_cmsp {
391+
Some((cm, sp)) => {
392+
let lo = cm.lookup_char_pos(sp.lo);
393+
let sp = cm.adjust_span(sp);
394+
let lines = cm.span_to_lines(sp);
395+
old_line = lines.lines;
396+
old_lo = lo.col.to_uint();
397+
}
398+
None => { flag = false; }
399+
}
400+
401+
match cmsp {
402+
Some((cm, sp)) => {
403+
let lo = cm.lookup_char_pos(sp.lo);
404+
let sp = cm.adjust_span(sp);
405+
let lines = cm.span_to_lines(sp);
406+
new_line = lines.lines;
407+
new_lo = lo.col.to_uint();
408+
}
409+
None => { flag = false; }
410+
}
411+
412+
if flag {
413+
if old_line == new_line && old_lo > new_lo {
414+
highlight_lines(cmsp);
415+
}
416+
}
417+
}
418+
419+
fn print_macro_backtrace_internal(cm: @codemap::CodeMap, sp: span) {
295420
for sp.expn_info.each |ei| {
296421
let ss = ei.callee.span.map_default(@~"", |span| @cm.span_to_str(*span));
297422
print_diagnostic(*ss, note,
298423
fmt!("in expansion of %s!", ei.callee.name));
299424
let ss = cm.span_to_str(ei.call_site);
300425
print_diagnostic(ss, note, ~"expansion site");
301-
print_macro_backtrace(cm, ei.call_site);
426+
print_macro_backtrace_internal(cm, ei.call_site);
427+
}
428+
}
429+
430+
fn print_macro_backtrace(cmsp: Option<(@codemap::CodeMap, span)>) {
431+
match cmsp {
432+
Some((cm, sp)) => {
433+
print_macro_backtrace_internal(cm, sp);
434+
}
435+
None => ()
302436
}
303437
}
304438

0 commit comments

Comments
 (0)