Skip to content

Commit 326ec80

Browse files
committed
Account for fully overlapping multiline annotations
When two multiline span labels point at the same span, we special case the output to avoid weird behavior: ``` foo( _____^ |_____| || bar, || ); || ^ ||______| |______foo baz ``` instead showing ``` foo( _____^ | bar, | ); | ^ | | |______foo baz ```
1 parent 925ca49 commit 326ec80

File tree

5 files changed

+116
-25
lines changed

5 files changed

+116
-25
lines changed

src/librustc_errors/emitter.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ impl EmitterWriter {
243243
end_col: hi.col_display,
244244
is_primary: span_label.is_primary,
245245
label: span_label.label.clone(),
246+
overlaps: false,
246247
};
247248
multiline_annotations.push((lo.file.clone(), ml.clone()));
248249
AnnotationType::Multiline(ml)
@@ -258,10 +259,7 @@ impl EmitterWriter {
258259
};
259260

260261
if !ann.is_multiline() {
261-
add_annotation_to_file(&mut output,
262-
lo.file,
263-
lo.line,
264-
ann);
262+
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
265263
}
266264
}
267265
}
@@ -274,10 +272,12 @@ impl EmitterWriter {
274272
let ref mut a = item.1;
275273
// Move all other multiline annotations overlapping with this one
276274
// one level to the right.
277-
if &ann != a &&
275+
if !(ann.same_span(a)) &&
278276
num_overlap(ann.line_start, ann.line_end, a.line_start, a.line_end, true)
279277
{
280278
a.increase_depth();
279+
} else if ann.same_span(a) && &ann != a {
280+
a.overlaps = true;
281281
} else {
282282
break;
283283
}
@@ -289,17 +289,44 @@ impl EmitterWriter {
289289
if ann.depth > max_depth {
290290
max_depth = ann.depth;
291291
}
292-
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
293-
let middle = min(ann.line_start + 4, ann.line_end);
294-
for line in ann.line_start + 1..middle {
295-
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
296-
}
297-
if middle < ann.line_end - 1 {
298-
for line in ann.line_end - 1..ann.line_end {
292+
let mut end_ann = ann.as_end();
293+
if !ann.overlaps {
294+
// avoid output like
295+
//
296+
// | foo(
297+
// | _____^
298+
// | |_____|
299+
// | || bar,
300+
// | || );
301+
// | || ^
302+
// | ||______|
303+
// | |______foo
304+
// | baz
305+
//
306+
// and instead get
307+
//
308+
// | foo(
309+
// | _____^
310+
// | | bar,
311+
// | | );
312+
// | | ^
313+
// | | |
314+
// | |______foo
315+
// | baz
316+
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
317+
let middle = min(ann.line_start + 4, ann.line_end);
318+
for line in ann.line_start + 1..middle {
299319
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
300320
}
321+
if middle < ann.line_end - 1 {
322+
for line in ann.line_end - 1..ann.line_end {
323+
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
324+
}
325+
}
326+
} else {
327+
end_ann.annotation_type = AnnotationType::Singleline;
301328
}
302-
add_annotation_to_file(&mut output, file, ann.line_end, ann.as_end());
329+
add_annotation_to_file(&mut output, file, ann.line_end, end_ann);
303330
}
304331
for file_vec in output.iter_mut() {
305332
file_vec.multiline_depth = max_depth;

src/librustc_errors/snippet.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@ pub struct MultilineAnnotation {
1818
pub end_col: usize,
1919
pub is_primary: bool,
2020
pub label: Option<String>,
21+
pub overlaps: bool,
2122
}
2223

2324
impl MultilineAnnotation {
2425
pub fn increase_depth(&mut self) {
2526
self.depth += 1;
2627
}
2728

29+
/// Compare two `MultilineAnnotation`s considering only the `Span` they cover.
30+
pub fn same_span(&self, other: &MultilineAnnotation) -> bool {
31+
self.line_start == other.line_start && self.line_end == other.line_end
32+
&& self.start_col == other.start_col && self.end_col == other.end_col
33+
}
34+
2835
pub fn as_start(&self) -> Annotation {
2936
Annotation {
3037
start_col: self.start_col,

src/libsyntax/test_snippet.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,66 @@ error: foo
374374
"#);
375375
}
376376

377+
#[test]
378+
fn triple_exact_overlap() {
379+
test_harness(r#"
380+
fn foo() {
381+
X0 Y0 Z0
382+
X1 Y1 Z1
383+
X2 Y2 Z2
384+
}
385+
"#,
386+
vec![
387+
SpanLabel {
388+
start: Position {
389+
string: "X0",
390+
count: 1,
391+
},
392+
end: Position {
393+
string: "X2",
394+
count: 1,
395+
},
396+
label: "`X` is a good letter",
397+
},
398+
SpanLabel {
399+
start: Position {
400+
string: "X0",
401+
count: 1,
402+
},
403+
end: Position {
404+
string: "X2",
405+
count: 1,
406+
},
407+
label: "`Y` is a good letter too",
408+
},
409+
SpanLabel {
410+
start: Position {
411+
string: "X0",
412+
count: 1,
413+
},
414+
end: Position {
415+
string: "X2",
416+
count: 1,
417+
},
418+
label: "`Z` label",
419+
},
420+
],
421+
r#"
422+
error: foo
423+
--> test.rs:3:3
424+
|
425+
3 | / X0 Y0 Z0
426+
4 | | X1 Y1 Z1
427+
5 | | X2 Y2 Z2
428+
| | ^
429+
| | |
430+
| | `X` is a good letter
431+
| |____`Y` is a good letter too
432+
| `Z` label
433+
434+
"#);
435+
}
436+
377437
#[test]
378438
fn minimum_depth() {
379439
test_harness(r#"

src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fn warn(_: &str) {}
33
macro_rules! intrinsic_match {
44
($intrinsic:expr) => {
55
warn(format!("unsupported intrinsic {}", $intrinsic));
6-
//^~ ERROR mismatched types
6+
//~^ ERROR mismatched types
77
};
88
}
99

src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
error[E0308]: mismatched types
2-
--> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:10:5
2+
--> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:11:5
33
|
4-
LL | intrinsic_match! {
5-
| _____^
6-
| |_____|
7-
| ||
8-
LL | || "abc"
9-
LL | || };
10-
| || ^
11-
| ||______|
12-
| |_______expected &str, found struct `std::string::String`
13-
| in this macro invocation
4+
LL | / intrinsic_match! {
5+
LL | | "abc"
6+
LL | | };
7+
| | ^
8+
| | |
9+
| |______expected &str, found struct `std::string::String`
10+
| in this macro invocation
1411
|
1512
= note: expected type `&str`
1613
found type `std::string::String`

0 commit comments

Comments
 (0)