Stream: ideas

Topic: Formatting source spans in warnings/errors


view this post on Zulip Qqwy / Marten (Jun 23 2022 at 20:17):

I recently came across a very beautiful way to style source spans in compiler warnings/errors, using some unicode arrows. Might make for nice inspiration: https://twitter.com/_lrlna/status/1539349704080871425?t=7fqNjt72CgD7NkWYnq4iVw&s=09

hooked up source spans and syntax node pointers to the compiler today, and man is it going to be nice once all of the diagnostics are rewritten to use this (tysm @zkat__ for miette!!) https://twitter.com/_lrlna/status/1539349704080871425/photo/1

- ірина (@_lrlna)

view this post on Zulip Folkert de Vries (Jun 23 2022 at 20:21):

yeah miette is really cool

view this post on Zulip Folkert de Vries (Jun 23 2022 at 20:22):

might work well for your debug IR format

view this post on Zulip Folkert de Vries (Jun 23 2022 at 20:22):

perhaps after we rewrite that then start doing some proper optimizations there

view this post on Zulip Brian Carroll (Jun 23 2022 at 20:29):

A language named after a meme, that's hilarious, love it! :laughing:

view this post on Zulip Brian Carroll (Jun 23 2022 at 20:31):

oh it's a tool?

view this post on Zulip Folkert de Vries (Jun 23 2022 at 20:42):

yeah it's crate for generating these pretty error messages

view this post on Zulip Folkert de Vries (Jun 23 2022 at 20:42):

You run miette? You run her code like the software? Oh. Oh! Error code for coder! Error code for One Thousand Lines!

view this post on Zulip Qqwy / Marten (Jun 23 2022 at 20:45):

:open_mouth: I was not aware that it was a library. That's really nice!

view this post on Zulip Qqwy / Marten (Jun 25 2022 at 21:29):

Folkert de Vries said:

yeah miette is really cool

Turns out Miette is not the only library doing this.
Once you come across one, you suddenly find many (Baader-Meinhof Phoenomenon?)

There also is 'Ariadne' for Rust which looks like https://raw.githubusercontent.com/zesterer/ariadne/main/misc/example.png

And 'Diagnose' for Haskell which looks like https://github.com/Mesabloo/diagnose/raw/master/assets/real-world-example-unicode.png and also has a nice ASCII fallback.

view this post on Zulip Richard Feldman (Jun 25 2022 at 21:45):

the inline arrows look great to me, but the outside line + arrows feel like noise. They don't communicate anything as far as I can tell, they just look cool but are distracting :big_smile:

view this post on Zulip Richard Feldman (Jun 25 2022 at 21:45):

outside as in the long line on the left that connects to the error message above the note/hint

view this post on Zulip Qqwy / Marten (Jun 25 2022 at 21:54):

The main reason for that line is -- I think -- to disambugate lines in the source (that have line numbers) from lines containing error/warning information (that is not in the original source).

The flourish connecting it at the top is probably only a taste thing; I also don't really like it.

view this post on Zulip Richard Feldman (Jun 25 2022 at 21:56):

oh I don't mean the leftmost gray line, I mean the vertical line next to it (light blue in the top screenshot, red in the bottom screenshot)

view this post on Zulip Richard Feldman (Jun 25 2022 at 21:56):

the line numbers part makes great sense to me :+1:

view this post on Zulip Richard Feldman (Jun 25 2022 at 21:57):

and I agree about the flourish of connecting it at the top haha

view this post on Zulip Richard Feldman (Jun 25 2022 at 21:59):

one thing I'm not sure about is how the lines in the middle look with a big multiline type. Maybe the idea is that hopefully those wouldn't come up much?

view this post on Zulip Qqwy / Marten (Jun 25 2022 at 22:04):

Good question! Let's see what they do in practice when multiline messages come up

view this post on Zulip Qqwy / Marten (Jun 25 2022 at 22:29):

So when a source span is so long that it takes multiple lines, then that is where the extra colored arrows come in. So in the first picture, the whole match in { ... } is used as source span for one of the messages.

The flat lines instead of arrows that Diagnose uses I find nicer for this.

If the message you want to attach to a source span takes multiple lines, then Ariadne currently just breaks (the newlines are printed as-is, disrupting its formatting). Diagnose handles them gracefully:

image.png

view this post on Zulip Qqwy / Marten (Jun 25 2022 at 22:49):

Some more examples, taken from the Diagnose test suite:

image.png
image.png
image.png
image.png
image.png

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:31):

hmm, all very interesting

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:31):

I wonder what happens if you have a long message that needs to point to something that's at the end of a very long line

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:31):

does the message just span a bunch of lines and get really squished?

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:31):

the pathological case would be where the arrow needs to point to the rightmost character in the terminal

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:32):

I guess maybe you just have to put a wrapping width on the source lines that's low enough to give yourself a reasonable buffer :thinking:

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:33):

it's cool to see that the colored lines along the side are optional, and that there can be multiple colors!

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:34):

knowing that, I'd be interested to experiment with these at some point

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:35):

these look closer to how I'd imagine errors in the editor looking someday - more integrated inline, with arrows pointing to the relevant problems right there in the code, rather than confined to a single box off to the side

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:36):

maybe we could pick an error message (or two) that we have today and experiment with hardcoding an example into this library, just to see how it would look

view this post on Zulip Richard Feldman (Jun 26 2022 at 00:37):

like taking something from one of our reporting tests, for example

view this post on Zulip Qqwy / Marten (Jun 26 2022 at 09:50):

Richard Feldman said:

it's cool to see that the colored lines along the side are optional, and that there can be multiple colors!

This might very well secretly be the real reason a line length of <80 characters is still recommended in many places :stuck_out_tongue_wink:

view this post on Zulip Folkert de Vries (Jun 29 2022 at 11:04):

if someone wants to play around with this, working on/with morphic's debug output might be interesting

view this post on Zulip Folkert de Vries (Jun 29 2022 at 11:05):

errors in there look like this today

    fn "mainForHost" (val_0: type_3) -> type_3 {
      let val_6 = choice {
        case {
          let val_1 = make_tuple ();
          let val_2 = make_union<type_1, type_0> 0 (val_1);
          let val_3 = unwrap_union 1 (val_2);
          let val_4 = call["\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"] "UserApp"::"\x00\x00\x00\x00\x0e\x00\x00\x00_\xa8\x0c\xbc5\xf4\x81h\x00\x00\x00\x00\x00\x00\x00\x00\x00`pf..mainForHost`\x00\x00\x00\x00\x00\x00\x00\x00" (val_3);
          let val_5 = unknown_with<type_2> (val_4);
          val_5
        },
      } ();
      val_6
    } where {
      type type_0 = ();
      type type_1 = ();
      type type_2 = ();
      type type_3 = ();
    }
  }

  entry_point "mainForHost" = "UserApp"::"mainForHost";
}
thread 'main' panicked at 'Error in alias analysis: error in module ModName("UserApp"), function definition FuncName("<\x00\x00\x00\x06\x00\x00\x00\xe0\xaf\xbe8\xd1\xe6\xeb\xe1\x00\x00\x00\x00\x00\x00\x00\x00\x00`List.loop`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), definition of value binding ValueId(9): expected type '((), (), ((),))', found type '(union { ((),), ((),) }, (), ((),))'', compiler/gen_llvm/src/llvm/build.rs:4166:19
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Last updated: Jun 16 2026 at 16:19 UTC