about summary refs log tree commit diff
path: root/compiler/rustc_errors/src/emitter.rs
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-06-23 21:33:59 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-06-23 22:00:52 +0000
commit284437d4342b70e03771d5329e5ac02dd719166a (patch)
tree25fdda29d4a48fde46b3d2f1dad63eba309d25b6 /compiler/rustc_errors/src/emitter.rs
parent33422e72c8a66bdb5ee21246a948a1a02ca91674 (diff)
downloadrust-284437d4342b70e03771d5329e5ac02dd719166a.tar.gz
rust-284437d4342b70e03771d5329e5ac02dd719166a.zip
Special case when a code line only has multiline span starts
```
3 |       X0 Y0 Z0
  |  _____^  -  -
  | | _______|  |
  | || _________|
4 | |||   X1 Y1 Z1
5 | |||   X2 Y2 Z2
  | |||____^__-__- `Z` label
  | ||_____|__|
  | |______|  `Y` is a good letter too
  |        `X` is a good letter
```
Diffstat (limited to 'compiler/rustc_errors/src/emitter.rs')
-rw-r--r--compiler/rustc_errors/src/emitter.rs27
1 files changed, 26 insertions, 1 deletions
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 @@ impl HumanEmitter {
         //      <EMPTY 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 @@ impl HumanEmitter {
             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: