diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 7405705dd33..45118bcc58a 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -902,7 +902,7 @@ fn render_source_line( // // let mut annotations_position = vec![]; - let mut line_len = 0; + let mut line_len: usize = 0; let mut p = 0; for (i, annotation) in annotations.iter().enumerate() { for (j, next) in annotations.iter().enumerate() { @@ -973,6 +973,31 @@ fn render_source_line( return vec![]; } + if annotations_position + .iter() + .all(|(_, ann)| matches!(ann.annotation_type, AnnotationType::MultilineStart(_))) + && let Some(max_pos) = annotations_position.iter().map(|(pos, _)| *pos).max() + { + // Special case the following, so that we minimize overlapping multiline spans. + // + // 3 │ X0 Y0 Z0 + // │ ┏━━━━━┛ │ │ < We are writing these lines + // │ ┃┌───────┘ │ < by reverting the "depth" of + // │ ┃│┌─────────┘ < their multilne spans. + // 4 │ ┃││ X1 Y1 Z1 + // 5 │ ┃││ X2 Y2 Z2 + // │ ┃│└────╿──│──┘ `Z` label + // │ ┃└─────│──┤ + // │ ┗━━━━━━┥ `Y` is a good letter too + // ╰╴ `X` is a good letter + for (pos, _) in &mut annotations_position { + *pos = max_pos - *pos; + } + // We know then that we don't need an additional line for the span label, saving us + // one line of vertical space. + line_len = line_len.saturating_sub(1); + } + // Write the column separator. // // After this we will have: diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 3a4690670af..42392ad2163 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -322,9 +322,8 @@ fn foo() { --> test.rs:3:3 | 3 | X0 Y0 - | ___^__- - | |___| - | || + | ____^ - + | | ______| 4 | || X1 Y1 5 | || X2 Y2 | ||____^__- `Y` is a good letter too @@ -361,9 +360,8 @@ fn foo() { --> test.rs:3:3 | 3 | X0 Y0 - | ___^__- - | |___| - | || + | ____^ - + | | ______| 4 | || Y1 X1 | ||____-__^ `X` is a good letter | |____| @@ -445,10 +443,9 @@ fn foo() { --> test.rs:3:3 | 3 | X0 Y0 Z0 - | ___^__-__- - | |___|__| - | ||___| - | ||| + | _____^ - - + | | _______| | + | || _________| 4 | ||| X1 Y1 Z1 5 | ||| X2 Y2 Z2 | |||____^__-__- `Z` label diff --git a/tests/ui/async-await/async-is-unwindsafe.stderr b/tests/ui/async-await/async-is-unwindsafe.stderr index 5d87fc74768..85fdcda3b8c 100644 --- a/tests/ui/async-await/async-is-unwindsafe.stderr +++ b/tests/ui/async-await/async-is-unwindsafe.stderr @@ -2,9 +2,8 @@ error[E0277]: the type `&mut Context<'_>` may not be safely transferred across a --> $DIR/async-is-unwindsafe.rs:12:5 | LL | is_unwindsafe(async { - | _____^_____________- - | |_____| - | || + | ______^ - + | | ___________________| LL | || LL | || use std::ptr::null; LL | || use std::task::{Context, RawWaker, RawWakerVTable, Waker}; diff --git a/tests/ui/lint/suggestions.stderr b/tests/ui/lint/suggestions.stderr index 4caee777a13..a4871ead74b 100644 --- a/tests/ui/lint/suggestions.stderr +++ b/tests/ui/lint/suggestions.stderr @@ -41,9 +41,8 @@ warning: variable does not need to be mutable --> $DIR/suggestions.rs:54:13 | LL | let mut - | ______________^ - | | _____________| - | || + | _____________^ + | |_____________| LL | || b = 1; | ||____________-^ | |_____________|