diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-05-03 06:11:20 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-05-03 06:15:39 -0400 |
| commit | f030b5dbc29b20b964f2cc448d893998080b1a46 (patch) | |
| tree | 14c0faafef67c1d847275ad58dff37d0b92c1675 /src/libsyntax/errors | |
| parent | 7d8100a068151512774caf15a6a88766ca9cf434 (diff) | |
| download | rust-f030b5dbc29b20b964f2cc448d893998080b1a46.tar.gz rust-f030b5dbc29b20b964f2cc448d893998080b1a46.zip | |
degrade gracefully with empty spans
Diffstat (limited to 'src/libsyntax/errors')
| -rw-r--r-- | src/libsyntax/errors/snippet/mod.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/errors/snippet/test.rs | 38 |
2 files changed, 49 insertions, 1 deletions
diff --git a/src/libsyntax/errors/snippet/mod.rs b/src/libsyntax/errors/snippet/mod.rs index e213f623ab8..237e6823e0f 100644 --- a/src/libsyntax/errors/snippet/mod.rs +++ b/src/libsyntax/errors/snippet/mod.rs @@ -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, diff --git a/src/libsyntax/errors/snippet/test.rs b/src/libsyntax/errors/snippet/test.rs index 569d1119919..5a888b48819 100644 --- a/src/libsyntax/errors/snippet/test.rs +++ b/src/libsyntax/errors/snippet/test.rs @@ -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..]); +} |
