Improving dmd's error output
Richard Andrew Cattermole (Rikki)
richard at cattermole.co.nz
Wed Dec 24 00:39:43 UTC 2025
Hello everyone, I have a bit of a Christmas treat, I'm currently
working to improve dmd's error messages.
The goal is to introduce a new message style for diagnostic
reporting, similar to Rust's compiler output.
Here is an example that is a rethink of an error from a recent PR
using my WIP code:
```
╭ scope_infer_diagnostic.d(12)
12 │ │ void outer() @safe {
13 │ │ int x;
14 │ │ inner((const(char)[] s) { x++; });
│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Cannot call `inner`
due to it being @system
15 │ │ }
╭ scope_infer_diagnostic.d(8)
8 │ void inner(Writer)(scope Writer w) {
│ ┌─┘ Failed to infer `@safe`
9 │ │ callee(w); // scope violation: w passed to non-scope
parameter
│ │ ^^^^^^^^^^ Due to `callee` parameter `w` not being
scope
10 │ │ }
╭ scope_infer_diagnostic.d(3)
3 │ │ void callee(Writer)(Writer w) @trusted {
│ │ ^^^^^^^^ `w` is not `scope`
4 │ │ globalPtr = cast(void*)&w; // escapes w
│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Cannot infer `w` as `scope`
as it escapes into `globalPtr` which is a global variable
5 │ │ w("x");
6 │ │ }
```
Here is an image of this, but in color straight from IntelliJ:
https://gist.github.com/rikkimax/f39721fe9f9377efe6896b30ad39c860?permalink_comment_id=5916804#gistcomment-5916804
I want to note that dmd doesn't store start and end locations for
expressions, so those squiggles that are the length of an
expression won't generate like that, unfortunately.
The reason I am exploring this is for the fast DFA engine,
assuming it gains tracing support.
It requires a way to output a range of lines of code, then
annotate them step by step on why it thinks something should
error.
Current output just isn't suited to this, let alone for a slow
DFA where outputs get fed back into inputs.
For the next step I need to identify what in dmd needs to change
so I have some idea of what to do after that.
So far I have identified the following modules:
1. dmd.console
2. dmd.errors
3. dmd.errorsink
4. dmd.sarif
That is a lot of modules for message output in dmd, that are not
currently packagerised.
I will likely want three more if I keep the current structure for
the diagnostic reports.
There are some cleanup work worth doing in these modules as well,
and I suspect some logic should be split out of dmd.errors as its
utility code that should be shared.
I would appreciate any insights into this area of dmd, and how it
could be improved. I haven't needed to mess around with this area
before and don't have a lot of opinions on it.
More information about the Digitalmars-d
mailing list