Repository: brendanzab/codespan (rust)

Issue:
[v 0.9.2] Recent changes to label ordering make errors more confusing
I find the recent change to the order in which labels displayed make a lot of error messages *really* confusing to read when displayed in the new format. 
https://github.com/brendanzab/codespan/commit/c3dd8465c762d7ead9471426d56fa539e4b324a2

For example, I find 
```
    ┌── tests/move_check/borrows/assign_local_combo_invalid.move:14:9 ───
    │
 14 │         s = S { f: 0, g: 0 };
    │         ^ Invalid assignment of local 's'
    ·
 13 │         if (cond) f = &s.f else f = &s.g;
    │                                     ---- It is still being borrowed by this reference
    │
```
A lot easier to reason through than the new version:
```
    ┌── tests/move_check/borrows/assign_local_combo_invalid.move:13:37 ───
    │
 13 │         if (cond) f = &s.f else f = &s.g;
    │                                     ---- It is still being borrowed by this reference
 14 │         s = S { f: 0, g: 0 };
    │         ^ Invalid assignment of local 's'
    │
```

Sometimes, if they are on the same line, it gets really really weird:
```
   ┌── tests/move_check/expansion/global_access_pack.move:3:13 ───
   │
 3 │         ::S { }
   │             ^ Unexpected '{'
   ·
 3 │         ::S { }
   │             - Expected '('
   │
```
Becomes
```
   ┌── tests/move_check/expansion/global_access_pack.move:3:13 ───
   │
 3 │         ::S { }
   │             - Expected '('
   │             ^ Unexpected '{'
   │
```
Do you have any suggests to how to fix this if we are on version 0.9.2?

Further context and discussion:
https://github.com/libra/libra/pull/3447


Pull request description:
Fix same range label rendering order
Fix label ordering for ranges that are the same

Labels that cover the same range are now rendered in the order that they were specified in the diagnostic (as opposed to in reverse order). This means that this diagnostic:

```
   ┌─ same_range:1:7
   │
 1 │ ::S { }
   │     - Expected '('
   │     ^ Unexpected '{'
   │
```

…will now be rendered as:

```
   ┌─ same_range:1:7
   │
 1 │ ::S { }
   │     ^ Unexpected '{'
   │     - Expected '('
   │
```

Closes #231

Patch:
diff --git a/codespan-reporting/src/term/views.rs b/codespan-reporting/src/term/views.rs
index 1845bf1..5d0f906 100644
--- a/codespan-reporting/src/term/views.rs
+++ b/codespan-reporting/src/term/views.rs
@@ -143,7 +143,10 @@ where
                     // to piggyback off its lexicographic comparison implementation.
                     (range.start, range.end).cmp(&(label_start, label_end))
                 }) {
-                    Ok(index) | Err(index) => index,
+                    // If the ranges are the same, order the labels as they
+                    // originally were specified in the diagnostic.
+                    Ok(index) => index + 1,
+                    Err(index) => index,
                 };
 
                 line.single_labels


Test patch:
diff --git a/codespan-reporting/tests/snapshots/term__empty_spans__rich_color.snap b/codespan-reporting/tests/snapshots/term__empty_ranges__rich_color.snap
similarity index 100%
rename from codespan-reporting/tests/snapshots/term__empty_spans__rich_color.snap
rename to codespan-reporting/tests/snapshots/term__empty_ranges__rich_color.snap
diff --git a/codespan-reporting/tests/snapshots/term__empty_spans__rich_no_color.snap b/codespan-reporting/tests/snapshots/term__empty_ranges__rich_no_color.snap
similarity index 100%
rename from codespan-reporting/tests/snapshots/term__empty_spans__rich_no_color.snap
rename to codespan-reporting/tests/snapshots/term__empty_ranges__rich_no_color.snap
diff --git a/codespan-reporting/tests/snapshots/term__empty_spans__short_color.snap b/codespan-reporting/tests/snapshots/term__empty_ranges__short_color.snap
similarity index 100%
rename from codespan-reporting/tests/snapshots/term__empty_spans__short_color.snap
rename to codespan-reporting/tests/snapshots/term__empty_ranges__short_color.snap
diff --git a/codespan-reporting/tests/snapshots/term__empty_spans__short_no_color.snap b/codespan-reporting/tests/snapshots/term__empty_ranges__short_no_color.snap
similarity index 100%
rename from codespan-reporting/tests/snapshots/term__empty_spans__short_no_color.snap
rename to codespan-reporting/tests/snapshots/term__empty_ranges__short_no_color.snap
diff --git a/codespan-reporting/tests/snapshots/term__same_ranges__rich_color.snap b/codespan-reporting/tests/snapshots/term__same_ranges__rich_color.snap
new file mode 100644
index 0000000..c1fb8a6
--- /dev/null
+++ b/codespan-reporting/tests/snapshots/term__same_ranges__rich_color.snap
@@ -0,0 +1,14 @@
+---
+source: codespan-reporting/tests/term.rs
+expression: TEST_DATA.emit_color(&config)
+---
+{fg:Red bold bright}error{bold bright}: Unexpected token{/}
+
+   {fg:Blue}┌─{/} same_range:1:5
+   {fg:Blue}│{/}
+ {fg:Blue}1{/} {fg:Blue}│{/} ::S { }
+   {fg:Blue}│{/}     {fg:Red}^ Unexpected '{'{/}
+   {fg:Blue}│{/}     {fg:Blue}- Expected '('{/}
+   {fg:Blue}│{/}
+
+
diff --git a/codespan-reporting/tests/snapshots/term__same_ranges__rich_no_color.snap b/codespan-reporting/tests/snapshots/term__same_ranges__rich_no_color.snap
new file mode 100644
index 0000000..016d225
--- /dev/null
+++ b/codespan-reporting/tests/snapshots/term__same_ranges__rich_no_color.snap
@@ -0,0 +1,14 @@
+---
+source: codespan-reporting/tests/term.rs
+expression: TEST_DATA.emit_no_color(&config)
+---
+error: Unexpected token
+
+   ┌─ same_range:1:5
+   │
+ 1 │ ::S { }
+   │     ^ Unexpected '{'
+   │     - Expected '('
+   │
+
+
diff --git a/codespan-reporting/tests/snapshots/term__same_ranges__short_color.snap b/codespan-reporting/tests/snapshots/term__same_ranges__short_color.snap
new file mode 100644
index 0000000..14ccc40
--- /dev/null
+++ b/codespan-reporting/tests/snapshots/term__same_ranges__short_color.snap
@@ -0,0 +1,6 @@
+---
+source: codespan-reporting/tests/term.rs
+expression: TEST_DATA.emit_color(&config)
+---
+same_range:1:5: {fg:Red bold bright}error{bold bright}: Unexpected token{/}
+
diff --git a/codespan-reporting/tests/snapshots/term__same_ranges__short_no_color.snap b/codespan-reporting/tests/snapshots/term__same_ranges__short_no_color.snap
new file mode 100644
index 0000000..94bdc59
--- /dev/null
+++ b/codespan-reporting/tests/snapshots/term__same_ranges__short_no_color.snap
@@ -0,0 +1,6 @@
+---
+source: codespan-reporting/tests/term.rs
+expression: TEST_DATA.emit_no_color(&config)
+---
+same_range:1:5: error: Unexpected token
+
diff --git a/codespan-reporting/tests/term.rs b/codespan-reporting/tests/term.rs
index 6de43e8..5ce3b31 100644
--- a/codespan-reporting/tests/term.rs
+++ b/codespan-reporting/tests/term.rs
@@ -180,7 +180,7 @@ mod message_and_notes {
     test_emit!(short_no_color);
 }
 
-mod empty_spans {
+mod empty_ranges {
     use super::*;
 
     lazy_static::lazy_static! {
@@ -210,6 +210,32 @@ mod empty_spans {
     test_emit!(short_no_color);
 }
 
+mod same_ranges {
+    use super::*;
+
+    lazy_static::lazy_static! {
+        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, &'static str>> = {
+            let file = SimpleFile::new("same_range", "::S { }");
+
+            let diagnostics = vec![
+                Diagnostic::error()
+                    .with_message("Unexpected token")
+                    .with_labels(vec![
+                        Label::primary((), 4..4).with_message("Unexpected '{'"),
+                        Label::secondary((), 4..4).with_message("Expected '('"),
+                    ]),
+            ];
+
+            TestData { files: file, diagnostics }
+        };
+    }
+
+    test_emit!(rich_color);
+    test_emit!(short_color);
+    test_emit!(rich_no_color);
+    test_emit!(short_no_color);
+}
+
 mod multifile {
     use super::*;