Skip to content

Commit b25bd3e

Browse files
committed
feat: Match Rust's overlapping multiline starts
1 parent 66bbd82 commit b25bd3e

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

src/renderer/display_list.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl<'a> DisplaySet<'a> {
269269
}
270270
}
271271

272-
// Adapted from https://github.com/rust-lang/rust/blob/894f7a4ba6554d3797404bbf550d9919df060b97/compiler/rustc_errors/src/emitter.rs#L706-L1155
272+
// Adapted from https://github.com/rust-lang/rust/blob/d371d17496f2ce3a56da76aa083f4ef157572c20/compiler/rustc_errors/src/emitter.rs#L706-L1211
273273
#[inline]
274274
fn format_line(
275275
&self,
@@ -366,7 +366,7 @@ impl<'a> DisplaySet<'a> {
366366
annotations.sort_by_key(|a| Reverse(a.range.0));
367367

368368
let mut annotations_positions = vec![];
369-
let mut line_len = 0;
369+
let mut line_len: usize = 0;
370370
let mut p = 0;
371371
for (i, annotation) in annotations.iter().enumerate() {
372372
for (j, next) in annotations.iter().enumerate() {
@@ -442,6 +442,36 @@ impl<'a> DisplaySet<'a> {
442442
line_len += 1;
443443
}
444444

445+
if annotations_positions.iter().all(|(_, ann)| {
446+
matches!(
447+
ann.annotation_part,
448+
DisplayAnnotationPart::MultilineStart(_)
449+
)
450+
}) {
451+
if let Some(max_pos) =
452+
annotations_positions.iter().map(|(pos, _)| *pos).max()
453+
{
454+
// Special case the following, so that we minimize overlapping multiline spans.
455+
//
456+
// 3 │ X0 Y0 Z0
457+
// │ ┏━━━━━┛ │ │ < We are writing these lines
458+
// │ ┃┌───────┘ │ < by reverting the "depth" of
459+
// │ ┃│┌─────────┘ < their multilne spans.
460+
// 4 │ ┃││ X1 Y1 Z1
461+
// 5 │ ┃││ X2 Y2 Z2
462+
// │ ┃│└────╿──│──┘ `Z` label
463+
// │ ┃└─────│──┤
464+
// │ ┗━━━━━━┥ `Y` is a good letter too
465+
// ╰╴ `X` is a good letter
466+
for (pos, _) in &mut annotations_positions {
467+
*pos = max_pos - *pos;
468+
}
469+
// We know then that we don't need an additional line for the span label, saving us
470+
// one line of vertical space.
471+
line_len = line_len.saturating_sub(1);
472+
}
473+
}
474+
445475
// This is a special case where we have a multiline
446476
// annotation that is at the start of the line disregarding
447477
// any leading whitespace, and no other multiline

tests/rustc_tests.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ error: foo
9191
--> test.rs:3:3
9292
|
9393
3 | X0 Y0
94-
| ___^__-
95-
| |___|
96-
| ||
94+
| ____^ -
95+
| | ______|
9796
4 | || X1 Y1
9897
5 | || X2 Y2
9998
| ||____^__- `Y` is a good letter too
@@ -130,9 +129,8 @@ error: foo
130129
--> test.rs:3:3
131130
|
132131
3 | X0 Y0
133-
| ___^__-
134-
| |___|
135-
| ||
132+
| ____^ -
133+
| | ______|
136134
4 | || Y1 X1
137135
| ||____-__^ `X` is a good letter
138136
| |____|
@@ -210,10 +208,9 @@ error: foo
210208
--> test.rs:3:3
211209
|
212210
3 | X0 Y0 Z0
213-
| ___^__-__-
214-
| |___|__|
215-
| ||___|
216-
| |||
211+
| _____^ - -
212+
| | _______| |
213+
| || _________|
217214
4 | ||| X1 Y1 Z1
218215
5 | ||| X2 Y2 Z2
219216
| |||____^__-__- `Z` label

0 commit comments

Comments
 (0)