Fix an ICE on diagnostics originating in external macros

This commit is contained in:
Jakub Bukaj 2014-11-20 21:24:39 +01:00
parent 96c8f2b0c1
commit 0524161c0b
4 changed files with 85 additions and 34 deletions

View file

@ -293,15 +293,17 @@ impl FileMap {
/// get a line from the list of pre-computed line-beginnings
///
pub fn get_line(&self, line: int) -> String {
pub fn get_line(&self, line_number: uint) -> Option<String> {
let lines = self.lines.borrow();
let begin: BytePos = (*lines)[line as uint] - self.start_pos;
let begin = begin.to_uint();
let slice = self.src.as_slice().slice_from(begin);
match slice.find('\n') {
Some(e) => slice.slice_to(e).to_string(),
None => slice.to_string()
}
lines.get(line_number).map(|&line| {
let begin: BytePos = line - self.start_pos;
let begin = begin.to_uint();
let slice = self.src.as_slice().slice_from(begin);
match slice.find('\n') {
Some(e) => slice.slice_to(e),
None => slice
}.to_string()
})
}
pub fn record_multibyte_char(&self, pos: BytePos, bytes: uint) {
@ -578,10 +580,10 @@ mod test {
let fm = cm.new_filemap("blork.rs".to_string(),
"first line.\nsecond line".to_string());
fm.next_line(BytePos(0));
assert_eq!(&fm.get_line(0),&"first line.".to_string());
assert_eq!(fm.get_line(0), Some("first line.".to_string()));
// TESTING BROKEN BEHAVIOR:
fm.next_line(BytePos(10));
assert_eq!(&fm.get_line(1), &".".to_string());
assert_eq!(fm.get_line(1), Some(".".to_string()));
}
#[test]

View file

@ -436,9 +436,11 @@ fn highlight_lines(err: &mut EmitterWriter,
elided = true;
}
// Print the offending lines
for line in display_lines.iter() {
try!(write!(&mut err.dst, "{}:{} {}\n", fm.name, *line + 1,
fm.get_line(*line as int)));
for &line_number in display_lines.iter() {
if let Some(line) = fm.get_line(line_number) {
try!(write!(&mut err.dst, "{}:{} {}\n", fm.name,
line_number + 1, line));
}
}
if elided {
let last_line = display_lines[display_lines.len() - 1u];
@ -465,24 +467,26 @@ fn highlight_lines(err: &mut EmitterWriter,
for _ in range(0, skip) {
s.push(' ');
}
let orig = fm.get_line(lines.lines[0] as int);
for pos in range(0u, left-skip) {
let cur_char = orig.as_bytes()[pos] as char;
// Whenever a tab occurs on the previous line, we insert one on
// the error-point-squiggly-line as well (instead of a space).
// That way the squiggly line will usually appear in the correct
// position.
match cur_char {
'\t' => s.push('\t'),
_ => s.push(' '),
};
if let Some(orig) = fm.get_line(lines.lines[0]) {
for pos in range(0u, left - skip) {
let cur_char = orig.as_bytes()[pos] as char;
// Whenever a tab occurs on the previous line, we insert one on
// the error-point-squiggly-line as well (instead of a space).
// That way the squiggly line will usually appear in the correct
// position.
match cur_char {
'\t' => s.push('\t'),
_ => s.push(' '),
};
}
}
try!(write!(&mut err.dst, "{}", s));
let mut s = String::from_str("^");
let hi = cm.lookup_char_pos(sp.hi);
if hi.col != lo.col {
// the ^ already takes up one space
let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
let num_squigglies = hi.col.to_uint() - lo.col.to_uint() - 1u;
for _ in range(0, num_squigglies) {
s.push('~');
}
@ -510,16 +514,22 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
let lines = lines.lines.as_slice();
if lines.len() > MAX_LINES {
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
lines[0] + 1, fm.get_line(lines[0] as int)));
try!(write!(&mut w.dst, "...\n"));
let last_line = lines[lines.len()-1];
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
last_line + 1, fm.get_line(last_line as int)));
} else {
for line in lines.iter() {
if let Some(line) = fm.get_line(lines[0]) {
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
*line + 1, fm.get_line(*line as int)));
lines[0] + 1, line));
}
try!(write!(&mut w.dst, "...\n"));
let last_line_number = lines[lines.len() - 1];
if let Some(last_line) = fm.get_line(last_line_number) {
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
last_line_number + 1, last_line));
}
} else {
for &line_number in lines.iter() {
if let Some(line) = fm.get_line(line_number) {
try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
line_number + 1, line));
}
}
}
let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1]+1);

View file

@ -0,0 +1,26 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern: cannot apply unary operator `!` to type `BytePos`
// Very
// sensitive
pub struct BytePos(pub u32);
// to particular
// line numberings / offsets
fn main() {
let x = BytePos(1);
assert!(x, x);
}

View file

@ -0,0 +1,13 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern: expected `bool`, found `_` (expected bool, found integral variable)
fn main(){assert!(1,1);}