[ ] When there is exactly one overload found for a failed declref, don't say "no matching overload, here are the non-matching ones", because it is very likely that the user intended to refer to precisely that decl. Instead, tell the user why the declref failed (e.g., missing argument 3, too many arguments, or argument 1 can't unify to the parameter type, etc.)
[ ] When there are more than one overload found, the current approach of listing all non-matching overloads still makes sense, but:
the same information from the previous item should be listed for each overload (the reasons why each overload isn't viable), and
the overloads should be ranked in decreasing order of how close they are to viable, using some heuristics
[ ] When there are no overloads (viable or otherwise), search for declarations in the same scope with similar names and suggest them to the user.
[ ] Special-case various operators. E.g., "could not add values of types u32 and u64, try casting one or the other with 'as'" (that latter part would be best implemented as a suggestion, see below)
Unification
[ ] "Note: expression could've unified to any of..." message should be made nicer and more fluent
pretty-print types (#123)
special cases for when there are 0 or 1 possibilities
use commas, "and" instead of array syntax
special case for the error type (which probably consists of not printing the error message at all, actually)
[ ] the errors when switch and if expressions fail to unify should try to find a maximal subset of switch cases or if bodies that do unify together (within reason), and state clearly and succinctly in the error message:
what possible types (or constraints) the compatible subset of cases want to have
what possible types (or constraints) each of the incompatible cases want to have, deduplicating if possible
Formatting
[ ] Highlight different parts of a range in different ways
For example, with operator expressions, I used to highlight the whole range—operands and operator—the exact same way, which was confusing and ambiguous. Now, I just highlight the operator, which I don't think is ever ambiguous, but can still be somewhat confusing. I really like the way Swift does it: highlight the operands with tildes (~) and the operator with carets (^):
let x: Int8 = -(127 + 1)
~~~ ^ ~
[ ] Show multiple ranges from the same line, well, on the same line.
[ ] Support printing out real ranges for builtin declarations and procedurally generated code. This will involve serializing the HIR nodes to actual Dusk code.
Relatedly, this must support IDE features like go to definition
Suggestions
[ ] Create a way for the compiler to be able to provide suggestions along with diagnostics
[ ] Display suggestions in the CLI
[ ] Surface suggestions as code actions from DLS
Miscellaneous infrastructure
Provide a way for the interpreter to gracefully terminate itself at any time, instead of panicking
[x] Never panic when calling into the interpreter from pure Rust code
[ ] Never panic, even when the interpreter receives a call from FFI code, or when the FFI code itself crashes (requires moving arbitrary code execution into a separate process)
Declrefs
u32
andu64
, try casting one or the other with 'as'" (that latter part would be best implemented as a suggestion, see below)Unification
error
type (which probably consists of not printing the error message at all, actually)switch
andif
expressions fail to unify should try to find a maximal subset ofswitch
cases orif
bodies that do unify together (within reason), and state clearly and succinctly in the error message:Formatting
~
) and the operator with carets (^
):Suggestions
Miscellaneous infrastructure