Skip to content

Commit

Permalink
degrade gracefully with empty spans
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed May 3, 2016
1 parent 7d8100a commit f030b5d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/libsyntax/errors/snippet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,21 @@ impl FileInfo {
// Basically, although this loses information, multi-line spans just
// 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)
} else {
(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);
self.lines[index].push_annotation(start_col,
end_col,
Expand Down
38 changes: 38 additions & 0 deletions src/libsyntax/errors/snippet/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,3 +519,41 @@ fn span_overlap_label3() {
|> ----- bar
"#[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..]);
}

0 comments on commit f030b5d

Please sign in to comment.