degrade gracefully with empty spans

This commit is contained in:
Niko Matsakis 2016-05-03 06:11:20 -04:00
parent 7d8100a068
commit f030b5dbc2
2 changed files with 49 additions and 1 deletions

View File

@ -376,11 +376,21 @@ impl FileInfo {
// Basically, although this loses information, multi-line spans just // Basically, although this loses information, multi-line spans just
// never look good. // never look good.
let (line, start_col, end_col) = if lines.len() == 1 { let (line, start_col, mut end_col) = if lines.len() == 1 {
(lines[0].line_index, lines[0].start_col, lines[0].end_col) (lines[0].line_index, lines[0].start_col, lines[0].end_col)
} else { } else {
(lines[0].line_index, lines[0].start_col, CharPos(lines[0].start_col.0 + 1)) (lines[0].line_index, lines[0].start_col, CharPos(lines[0].start_col.0 + 1))
}; };
// Watch out for "empty spans". If we get a span like 6..6, we
// want to just display a `^` at 6, so convert that to
// 6..7. This is degenerate input, but it's best to degrade
// gracefully -- and the parser likes to suply a span like
// that for EOF, in particular.
if start_col == end_col {
end_col.0 += 1;
}
let index = self.ensure_source_line(line); let index = self.ensure_source_line(line);
self.lines[index].push_annotation(start_col, self.lines[index].push_annotation(start_col,
end_col, end_col,

View File

@ -519,3 +519,41 @@ fn span_overlap_label3() {
|> ----- bar |> ----- bar
"#[1..]); "#[1..]);
} }
#[test]
fn span_empty() {
// In one of the unit tests, we found that the parser sometimes
// gives empty spans, and in particular it supplied an EOF span
// like this one, which points at the very end. We want to
// fallback gracefully in this case.
let file_text = r#"
fn main() {
struct Foo;
impl !Sync for Foo {}
unsafe impl Send for &'static Foo {
// error: cross-crate traits with a default impl, like `core::marker::Send`,
// can only be implemented for a struct/enum type, not
// `&'static Foo`
}"#;
let cm = Rc::new(CodeMap::new());
let foo = cm.new_filemap_and_lines("foo.rs", file_text);
let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1);
rbrace_span.lo = rbrace_span.hi;
let mut snippet = SnippetData::new(cm.clone(), Some(rbrace_span));
snippet.push(rbrace_span, false, None);
let lines = snippet.render_lines();
let text: String = make_string(&lines);
println!("r#\"\n{}\"", text);
assert_eq!(text, &r#"
--> foo.rs:11:2
11 |> }
|> -
"#[1..]);
}