diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2017-04-14 16:38:10 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2017-04-20 17:31:20 -0700 |
| commit | cc07c357e421eebff58eb6948c8e1412ae7d8069 (patch) | |
| tree | 560bdd78cbfc03646386e6d8ed881c901f4bda79 /src/librustc_errors | |
| parent | 968ae7babecfc6c62ef9699ff052d9ab00411848 (diff) | |
| download | rust-cc07c357e421eebff58eb6948c8e1412ae7d8069.tar.gz rust-cc07c357e421eebff58eb6948c8e1412ae7d8069.zip | |
Reduce visual clutter of multiline start when possible
When a span starts on a line with nothing but whitespace to the left,
and there are no other annotations in that line, simplify the visual
representation of the span.
Go from:
```rust
error[E0072]: recursive type `A` has infinite size
--> file2.rs:1:1
|
1 | struct A {
| _^ starting here...
2 | | a: A,
3 | | }
| |_^ ...ending here: recursive type has infinite size
|
```
To:
```rust
error[E0072]: recursive type `A` has infinite size
--> file2.rs:1:1
|
1 | / struct A {
2 | | a: A,
3 | | }
| |_^ recursive type has infinite size
```
Remove `starting here...`/`...ending here` labels from all multiline
diagnostics.
Diffstat (limited to 'src/librustc_errors')
| -rw-r--r-- | src/librustc_errors/emitter.rs | 67 | ||||
| -rw-r--r-- | src/librustc_errors/snippet.rs | 22 |
2 files changed, 68 insertions, 21 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index a52628ceb47..64652bb308b 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -263,6 +263,41 @@ impl EmitterWriter { draw_col_separator(buffer, line_offset, width_offset - 2); + // Special case when there's only one annotation involved, it is the start of a multiline + // span and there's no text at the beginning of the code line. Instead of doing the whole + // graph: + // + // 2 | fn foo() { + // | _^ + // 3 | | + // 4 | | } + // | |_^ test + // + // we simplify the output to: + // + // 2 | / fn foo() { + // 3 | | + // 4 | | } + // | |_^ test + if line.annotations.len() == 1 { + if let Some(ref ann) = line.annotations.get(0) { + if let AnnotationType::MultilineStart(depth) = ann.annotation_type { + if source_string[0..ann.start_col].trim() == "" { + let style = if ann.is_primary { + Style::UnderlinePrimary + } else { + Style::UnderlineSecondary + }; + buffer.putc(line_offset, + width_offset + depth - 1, + '/', + style); + return vec![(depth, style)]; + } + } + } + } + // We want to display like this: // // vec.push(vec.pop().unwrap()); @@ -355,10 +390,8 @@ impl EmitterWriter { for (i, annotation) in annotations.iter().enumerate() { for (j, next) in annotations.iter().enumerate() { if overlaps(next, annotation, 0) // This label overlaps with another one and both - && !annotation.is_line() // take space (they have text and are not - && !next.is_line() // multiline lines). - && annotation.has_label() - && j > i + && annotation.has_label() // take space (they have text and are not + && j > i // multiline lines). && p == 0 // We're currently on the first line, move the label one line down { // This annotation needs a new line in the output. @@ -374,7 +407,7 @@ impl EmitterWriter { } else { 0 }; - if overlaps(next, annotation, l) // Do not allow two labels to be in the same + if (overlaps(next, annotation, l) // Do not allow two labels to be in the same // line if they overlap including padding, to // avoid situations like: // @@ -383,11 +416,18 @@ impl EmitterWriter { // | | // fn_spanx_span // - && !annotation.is_line() // Do not add a new line if this annotation - && !next.is_line() // or the next are vertical line placeholders. && annotation.has_label() // Both labels must have some text, otherwise - && next.has_label() // they are not overlapping. + && next.has_label()) // they are not overlapping. + // Do not add a new line if this annotation + // or the next are vertical line placeholders. + || (annotation.takes_space() // If either this or the next annotation is + && next.has_label()) // multiline start/end, move it to a new line + || (annotation.has_label() // so as not to overlap the orizontal lines. + && next.takes_space()) + || (annotation.takes_space() + && next.takes_space()) { + // This annotation needs a new line in the output. p += 1; break; } @@ -397,6 +437,7 @@ impl EmitterWriter { line_len = p; } } + if line_len != 0 { line_len += 1; } @@ -480,7 +521,7 @@ impl EmitterWriter { }; let pos = pos + 1; - if pos > 1 && annotation.has_label() { + if pos > 1 && (annotation.has_label() || annotation.takes_space()) { for p in line_offset + 1..line_offset + pos + 1 { buffer.putc(p, code_offset + annotation.start_col, @@ -514,12 +555,12 @@ impl EmitterWriter { // After this we will have: // // 2 | fn foo() { - // | __________ starting here... + // | __________ // | | // | something about `foo` // 3 | // 4 | } - // | _ ...ending here: test + // | _ test for &(pos, annotation) in &annotations_position { let style = if annotation.is_primary { Style::LabelPrimary @@ -557,12 +598,12 @@ impl EmitterWriter { // After this we will have: // // 2 | fn foo() { - // | ____-_____^ starting here... + // | ____-_____^ // | | // | something about `foo` // 3 | // 4 | } - // | _^ ...ending here: test + // | _^ test for &(_, annotation) in &annotations_position { let (underline, style) = if annotation.is_primary { ('^', Style::UnderlinePrimary) diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs index 9aa4682e1af..7401ead2208 100644 --- a/src/librustc_errors/snippet.rs +++ b/src/librustc_errors/snippet.rs @@ -63,7 +63,7 @@ impl MultilineAnnotation { start_col: self.start_col, end_col: self.start_col + 1, is_primary: self.is_primary, - label: Some("starting here...".to_owned()), + label: None, annotation_type: AnnotationType::MultilineStart(self.depth) } } @@ -73,10 +73,7 @@ impl MultilineAnnotation { start_col: self.end_col - 1, end_col: self.end_col, is_primary: self.is_primary, - label: match self.label { - Some(ref label) => Some(format!("...ending here: {}", label)), - None => Some("...ending here".to_owned()), - }, + label: self.label.clone(), annotation_type: AnnotationType::MultilineEnd(self.depth) } } @@ -106,9 +103,9 @@ pub enum AnnotationType { // Each of these corresponds to one part of the following diagram: // // x | foo(1 + bar(x, - // | _________^ starting here... < MultilineStart - // x | | y), < MultilineLine - // | |______________^ ...ending here: label < MultilineEnd + // | _________^ < MultilineStart + // x | | y), < MultilineLine + // | |______________^ label < MultilineEnd // x | z); /// Annotation marking the first character of a fully shown multiline span MultilineStart(usize), @@ -189,6 +186,15 @@ impl Annotation { false } } + + pub fn takes_space(&self) -> bool { + // Multiline annotations always have to keep vertical space. + match self.annotation_type { + AnnotationType::MultilineStart(_) | + AnnotationType::MultilineEnd(_) => true, + _ => false, + } + } } #[derive(Debug)] |
