Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

9. Errors and diagnostics

9.1 The diagnostic model

Every problem Korrin reports is a diagnostic: a stable error code, a one-line message, one or more labelled spans of source, and optional notes and a help line. Diagnostics are produced by four stages — lexer, parser, resolver, interpreter — and rendered the same way regardless of origin (ADR 0008).

9.2 Stability of codes

Once a code is assigned a meaning it keeps it forever. Wording may improve; the code–meaning mapping does not change. New codes are appended. The authoritative list is the ErrorCode enum in crates/korrin/src/diagnostics.rs; this section is its prose companion.

9.3 When does a program stop?

  • Lexer and parser errors are collected — one mistake does not hide the rest — and reported together. The program does not run.
  • Resolver errors are all reported in one pass. The program does not run.
  • A runtime error stops execution immediately at the offending expression. Output written before that point has already been produced.

9.4 Codes

Lexical — E00xx

CodeMeaning
E0001A character that cannot begin any token (includes a lone !).
E0002A string literal with no closing " before the end of the line.
E0003A \ escape that Korrin does not define.
E0004A malformed number literal (1.2.3, 10abc).
E0005A number literal outside the range of its type.
E0006A tab character in a line's leading indentation.
E0007A dedent to a column that matches no enclosing block.
E0008An opening (, [, or { with no matching close.

Syntax — E01xx

CodeMeaning
E0101A token where the grammar does not allow it (includes a chained comparison).
E0102A required token (:, ), in, a name, end of line, …) was missing.
E0103An expression was required and none was found.
E0104The left side of = is not a name, attribute, or index.
E0105(reserved) An indented block with no statements.
E0106A for header not of the form for NAME in EXPR:.

Static — E02xx

CodeMeaning
E0201return outside any function.
E0202break outside any loop.
E0203continue outside any loop.
E0204(reserved — self is an ordinary name)
E0205super outside any method.
E0206super in a class with no parent.
E0207Two parameters of one function share a name.
E0208A class names itself as its own parent.

Runtime — E03xx

CodeMeaning
E0301Read of a name with no binding in scope.
E0302Call of a value that is not a function or class.
E0303A call with the wrong number of arguments.
E0304An operator, builtin, or method got a value of the wrong type.
E0305Integer or float division/modulo by zero.
E0306An integer operation overflowed the 64-bit range.
E0307A list or string index outside its bounds (includes list.pop / list.remove_at / list.insert out of range).
E0308Indexing a value that does not support it.
E0309Access of an attribute a value does not have (an unknown instance field/method, or an unknown method on str / list / map).
E0310A map[key] lookup for an absent key.
E0311A value that is not hashable used as a map key.
E0312(reserved for the future error-handling feature)
E0313Function-call nesting exceeded the interpreter's recursion limit.

9.5 Examples

x = 1 + undefined_name
# error: E0301
fn f(a, a):
    return a
# error: E0207
print(10 % 0)
# error: E0305