Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group labels originating from the same file into a single snippet #100

Closed
brendanzab opened this issue Jun 24, 2019 · 2 comments · Fixed by #210
Closed

Group labels originating from the same file into a single snippet #100

brendanzab opened this issue Jun 24, 2019 · 2 comments · Fixed by #210

Comments

@brendanzab
Copy link
Owner

brendanzab commented Jun 24, 2019

As mentioned in #77, Rustc does a clever job of grouping together labels:

It would be super neat if we could do something similar!

At the moment our diagnostics are all spread out:

error[E0308]: `case` clauses have incompatible types

   ┌── FizzBuzz.fun:8:12 ───
   │
 8 │     _ _ => num
   │            ^^^ expected `String`, found `Nat`
   │
   = expected type `String`
        found type `Nat`

   ┌── FizzBuzz.fun:4:13 ───
   │
 4 │   fizz₁ num = case (mod num 5) (mod num 3) of
   │ ╭─────────────'
 5 │ │     0 0 => "FizzBuzz"
 6 │ │     0 _ => "Fizz"
 7 │ │     _ 0 => "Buzz"
 8 │ │     _ _ => num
   │ ╰──────────────' `case` clauses have incompatible types
   │

   ┌── FizzBuzz.fun:3:15 ───
   │
 3 │ fizz₁ : Nat → String
   │               ------ expected type `String` found here
   │

It would be great if we could collapse things down, for example:

error[E0308]: `case` clauses have incompatible types

   ┌── FizzBuzz.fun:8:12 ───
   │
 3 │   fizz₁ : Nat → String
   │                 ------ expected type `String` found here
 4 │   fizz₁ num = case (mod num 5) (mod num 3) of
   │ ╭─────────────'
 5 │ │     0 0 => "FizzBuzz"
 6 │ │     0 _ => "Fizz"
 7 │ │     _ 0 => "Buzz"
 8 │ │     _ _ => num
   │ │            ^^^ expected `String`, found `Nat`
   │ ╰──────────────' `case` clauses have incompatible types
   │
   = expected type `String`
        found type `Nat`

Or in the case of that rustc error:

error[E0308]: match arms have incompatible types

    ┌─ codespan/src/file.rs:102:34
    :
99  │  ╭──────── match line_index.compare(self.last_line_index()) {
100 │  │             Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
    │  │                               --------------------------------------------- this is found to be of type `std::result::Result<index::ByteIndex, file::LineIndexOutOfBoundsError>`
101 │  │             Ordering::Equal => Ok(self.source_span().end()),
    │  │                                ---------------------------- this is found to be of type `std::result::Result<index::ByteIndex, file::LineIndexOutOfBoundsError>`
102 │  │             Ordering::Greater => LineIndexOutOfBoundsError {
    │ ╭│──────────────────────────────────^
103 │ ││                 given: line_index,
104 │ ││                 max: self.last_line_index(),
105 │ ││             },
    │ ╰│─────────────^ expected enum `std::result::Result`, found struct `file::LineIndexOutOfBoundsError`
106 │  │         }
    │  ╰─────────' `match` arms have incompatible types
    :
    = note: expected type `std::result::Result<index::ByteIndex, file::LineIndexOutOfBoundsError>`
               found type `file::LineIndexOutOfBoundsError`

It might be worth studying how librustc_errors does this. There's a bunch of clever logic in emitter.rs that it might be worth understanding.

@brendanzab
Copy link
Owner Author

This seems like it could be a helpful library: https://crates.io/crates/nested_intervals - or at least thinking about this stuff in terms of interval sets... 🤔

brendanzab added a commit that referenced this issue Mar 9, 2020
Working towards #100, this slightly cleans up the rendering of diagnostics with multiple labels.
brendanzab added a commit that referenced this issue Mar 9, 2020
Working towards #100, this slightly cleans up the rendering of diagnostics with multiple labels.
@brendanzab
Copy link
Owner Author

Making progress on this on my overlapping-maks branch:

error[E0308]: match arms have incompatible types

   ┌── codespan/src/file.rs:1:9 ───
   │
 1 │ ╭         match line_index.compare(self.last_line_index()) {
 2 │ │             Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
   │ │                               --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
 3 │ │             Ordering::Equal => Ok(self.source_span().end()),
   │ │                                ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
 4 │   │             Ordering::Greater => LineIndexOutOfBoundsError {
   │ ╭─│──────────────────────────────────^
 5 │ │ │                 given: line_index,
 6 │ │ │                 max: self.last_line_index(),
 7 │ │ │             },
   │ ╰─│─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
 8 │ │         }
   │ ╰─────────' `match` arms have incompatible types
   │
   = expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
        found type `LineIndexOutOfBoundsError`

brendanzab added a commit that referenced this issue Mar 24, 2020
This renders overlapping multiline marks on the same lines of source code. This means that the following example:

```
error[E0308]: match arms have incompatible types

   ┌── codespan/src/file.rs:1:9 ───
   │
 1 │ ╭         match line_index.compare(self.last_line_index()) {
 2 │ │             Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
 3 │ │             Ordering::Equal => Ok(self.source_span().end()),
 4 │ │             Ordering::Greater => LineIndexOutOfBoundsError {
 5 │ │                 given: line_index,
 6 │ │                 max: self.last_line_index(),
 7 │ │             },
 8 │ │         }
   │ ╰─────────' `match` arms have incompatible types
   ·
 2 │               Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
   │                                 --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
 3 │               Ordering::Equal => Ok(self.source_span().end()),
   │                                  ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
 4 │               Ordering::Greater => LineIndexOutOfBoundsError {
   │ ╭──────────────────────────────────^
 5 │ │                 given: line_index,
 6 │ │                 max: self.last_line_index(),
 7 │ │             },
   │ ╰─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
   │
   = expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
        found type `LineIndexOutOfBoundsError`
```

…is now rendered as:

```
error[E0308]: match arms have incompatible types

   ┌── codespan/src/file.rs:1:9 ───
   │
 1 │   ╭         match line_index.compare(self.last_line_index()) {
 2 │   │             Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
   │   │                               --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
 3 │   │             Ordering::Equal => Ok(self.source_span().end()),
   │   │                                ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
 4 │   │             Ordering::Greater => LineIndexOutOfBoundsError {
   │ ╭─│──────────────────────────────────^
 5 │ │ │                 given: line_index,
 6 │ │ │                 max: self.last_line_index(),
 7 │ │ │             },
   │ ╰─│─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
 8 │   │         }
   │   ╰─────────' `match` arms have incompatible types
   │
   = expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
        found type `LineIndexOutOfBoundsError`
```

Closes #100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant