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>2025-02-28 00:30:45 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-03-07 17:55:08 +0000
commita04c47a0f3501c04b8932a4f65473dc9cfe660a3 (patch)
tree98574f6820d4bfb5b2b4d9bebd7afa86065ab949 /compiler/rustc_errors/src/emitter.rs
parentc75da0eda678afa4eb5f983796aa8a59e4d01a4e (diff)
downloadrust-a04c47a0f3501c04b8932a4f65473dc9cfe660a3.tar.gz
rust-a04c47a0f3501c04b8932a4f65473dc9cfe660a3.zip
Make trimming logic work on more than one span at a time
Diffstat (limited to 'compiler/rustc_errors/src/emitter.rs')
-rw-r--r--compiler/rustc_errors/src/emitter.rs37
1 files changed, 25 insertions, 12 deletions
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 2db3c2b00ab..21255fcca96 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -882,11 +882,16 @@ impl HumanEmitter {
         //      |      x_span
         //      <EMPTY LINE>
         //
+        let mut overlap = vec![false; annotations.len()];
         let mut annotations_position = vec![];
         let mut line_len: usize = 0;
         let mut p = 0;
         for (i, annotation) in annotations.iter().enumerate() {
             for (j, next) in annotations.iter().enumerate() {
+                if overlaps(next, annotation, 0) && j > i {
+                    overlap[i] = true;
+                    overlap[j] = true;
+                }
                 if overlaps(next, annotation, 0)  // This label overlaps with another one and both
                     && annotation.has_label()     // take space (they have text and are not
                     && j > i                      // multiline lines).
@@ -1269,13 +1274,17 @@ impl HumanEmitter {
         // We look for individual *long* spans, and we trim the *middle*, so that we render
         // LL | ...= [0, 0, 0, ..., 0, 0];
         //    |      ^^^^^^^^^^...^^^^^^^ expected `&[u8]`, found `[{integer}; 1680]`
-        for &(pos, annotation) in &annotations_position {
+        for (i, (_pos, annotation)) in annotations_position.iter().enumerate() {
+            // Skip cases where multiple spans overlap each other.
+            if overlap[i] {
+                continue;
+            };
             let AnnotationType::Singleline = annotation.annotation_type else { continue };
             let width = annotation.end_col.display - annotation.start_col.display;
-            if pos == 0 && width > margin.column_width && width > 10 {
+            if width > margin.column_width * 2 && width > 10 {
                 // If the terminal is *too* small, we keep at least a tiny bit of the span for
                 // display.
-                let pad = max(margin.column_width / 2, 5);
+                let pad = max(margin.column_width / 3, 5);
                 // Code line
                 buffer.replace(
                     line_offset,
@@ -1800,15 +1809,7 @@ impl HumanEmitter {
                     width_offset + annotated_file.multiline_depth + 1
                 };
 
-                let column_width = if let Some(width) = self.diagnostic_width {
-                    width.saturating_sub(code_offset)
-                } else if self.ui_testing || cfg!(miri) {
-                    DEFAULT_COLUMN_WIDTH
-                } else {
-                    termize::dimensions()
-                        .map(|(w, _)| w.saturating_sub(code_offset))
-                        .unwrap_or(DEFAULT_COLUMN_WIDTH)
-                };
+                let column_width = self.column_width(code_offset);
 
                 let margin = Margin::new(
                     whitespace_margin,
@@ -1965,6 +1966,18 @@ impl HumanEmitter {
         Ok(())
     }
 
+    fn column_width(&self, code_offset: usize) -> usize {
+        if let Some(width) = self.diagnostic_width {
+            width.saturating_sub(code_offset)
+        } else if self.ui_testing || cfg!(miri) {
+            DEFAULT_COLUMN_WIDTH
+        } else {
+            termize::dimensions()
+                .map(|(w, _)| w.saturating_sub(code_offset))
+                .unwrap_or(DEFAULT_COLUMN_WIDTH)
+        }
+    }
+
     fn emit_suggestion_default(
         &mut self,
         span: &MultiSpan,