Skip to content

Commit f030b5d

Browse files
committed
degrade gracefully with empty spans
1 parent 7d8100a commit f030b5d

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/libsyntax/errors/snippet/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,21 @@ impl FileInfo {
376376
// Basically, although this loses information, multi-line spans just
377377
// never look good.
378378

379-
let (line, start_col, end_col) = if lines.len() == 1 {
379+
let (line, start_col, mut end_col) = if lines.len() == 1 {
380380
(lines[0].line_index, lines[0].start_col, lines[0].end_col)
381381
} else {
382382
(lines[0].line_index, lines[0].start_col, CharPos(lines[0].start_col.0 + 1))
383383
};
384+
385+
// Watch out for "empty spans". If we get a span like 6..6, we
386+
// want to just display a `^` at 6, so convert that to
387+
// 6..7. This is degenerate input, but it's best to degrade
388+
// gracefully -- and the parser likes to suply a span like
389+
// that for EOF, in particular.
390+
if start_col == end_col {
391+
end_col.0 += 1;
392+
}
393+
384394
let index = self.ensure_source_line(line);
385395
self.lines[index].push_annotation(start_col,
386396
end_col,

src/libsyntax/errors/snippet/test.rs

+38
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,41 @@ fn span_overlap_label3() {
519519
|> ----- bar
520520
"#[1..]);
521521
}
522+
523+
#[test]
524+
fn span_empty() {
525+
// In one of the unit tests, we found that the parser sometimes
526+
// gives empty spans, and in particular it supplied an EOF span
527+
// like this one, which points at the very end. We want to
528+
// fallback gracefully in this case.
529+
530+
let file_text = r#"
531+
fn main() {
532+
struct Foo;
533+
534+
impl !Sync for Foo {}
535+
536+
unsafe impl Send for &'static Foo {
537+
// error: cross-crate traits with a default impl, like `core::marker::Send`,
538+
// can only be implemented for a struct/enum type, not
539+
// `&'static Foo`
540+
}"#;
541+
542+
543+
let cm = Rc::new(CodeMap::new());
544+
let foo = cm.new_filemap_and_lines("foo.rs", file_text);
545+
546+
let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1);
547+
rbrace_span.lo = rbrace_span.hi;
548+
549+
let mut snippet = SnippetData::new(cm.clone(), Some(rbrace_span));
550+
snippet.push(rbrace_span, false, None);
551+
let lines = snippet.render_lines();
552+
let text: String = make_string(&lines);
553+
println!("r#\"\n{}\"", text);
554+
assert_eq!(text, &r#"
555+
--> foo.rs:11:2
556+
11 |> }
557+
|> -
558+
"#[1..]);
559+
}

0 commit comments

Comments
 (0)