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

Appendix C: The Diagnostic Codes

The complete list of diagnostic codes issued by Lune’s compiler and evaluator. Here the book confines itself to being a map: the detailed explanation of each code (what happened, the smallest reproduction, how to fix it) is not copied here but left to lune explain CODE (:explain CODE in the REPL). The same content is readable in the diagnostic catalogue and in documents/ERROR_INDEX.md (the Japanese version is ERROR_INDEX_JA.md).

$ lune explain TYP0007          # read one code
$ lune explain --index          # list the explanations of every code

The first three letters of a code are its family, corresponding directly to a stage of the compiler. What the families mean and how to read them is §11.2.

You will never meet a code without an explanation. test_every_emitted_code_has_an_explanation in tests/test_explanations.py checks that every code the compiler can issue has one, so adding a code without writing its explanation makes the test fail.

How to read the table

  • Chapters that mention it — the chapters where the code appears in the text. Chapter 11 is about the machinery of diagnostics itself, so it touches nearly all of them.
  • Working example — chapters where books/examples-en/ contains a verified example that actually reproduces the code. Use it as a way in when you want to produce one yourself. A — means the book has no example aimed at that code (LAY0002 and REC0001, for instance, take some contriving to produce deliberately).
  • Codes issued as warnings say “(warning)” in the meaning column. A warning does not make --check fail.

The list

CodeFamilyMeaningChapters that mention itWorking example
LAY0001layoutinconsistent indentation11—
LAY0002layoutunmatched closing bracket11—
LXL0001lexingunexpected character2, 112
LXL0002lexingunterminated string or character literal11—
LXL0003lexingunterminated block comment11—
LXL0004lexingtabs are not allowed in indentation11—
MOD0001module resolutionmodule not found or unreadable10, 1110
MOD0002module resolutioncyclic module import10, 1110
MOD0003module resolutionmodule declaration mismatch10, 1110
PRS0001parsingunexpected token2, 6, 112
PRS0002parsinga particular token was required10, 11—
REC0001record checkingduplicate field in a record declaration11—
REC0002record checkingunknown record field6, 116
REC0003record checkingmissing record field6, 11—
REC0004record checkingfield given twice in a construction6, 11—
REC0005record checkinga field that was never declared6, 11—
REC0006record checkingrecords are built with named fields6, 11, 13—
RUN0005run timerecursive thunk evaluation3, 4, 10, 11, 124
RUN0006run timeruntime error2, 4, 6, 9, 11, 124
TYP0001type checkingundefined name1, 4, 10, 11, 121, 4, 11
TYP0003type checkingtype mismatch1, 2, 7, 8, 11, 122, 7
TYP0004type checkingvalue is not callable3, 11—
TYP0005type checkingwrong number of arguments1, 3, 111
TYP0006type checkingthe subject of a for must be a List9, 119
TYP0007type checkingnon-exhaustive match5, 7, 11, 135, 7, 11
TYP0008type checkinga refutable pattern in a binding5, 9, 115
TYP0009type checkingunreachable match case (warning)5, 7, 11, 125
TYP0010type checkingcannot infer a parameter’s type (warning)3, 11—
TYP0011type checkinga recursive function needs a result type2, 3, 113
TYP0012type checkingnamed arguments are not supported here11, 13—
TYP0013type checkingassignment to an immutable binding9, 119

About the gaps in the numbering

You may have noticed that the numbers are not consecutive: TYP0002 and RUN0001–RUN0004 are missing.

The RUN codes were, at the design stage, going to divide runtime errors by kind (RUN0004 was reserved for “non-exhaustive match at run time”). The implementation abandoned that plan, keeping only the forcing of a recursive thunk as its own RUN0005 and collecting the rest into the general RUN0006. An undefined variable, forcing a failed thunk, a type mismatch in the standard library and a non-exhaustive match at run time are all RUN0006. TYP0002 is simply unused. See documents/ERROR_DIAGNOSTICS_SPEC.md for details.

The gaps will not be filled in. A number that once meant one thing coming to mean another later would harm readers more than a gap does. An error number is a key for looking things up, not a serial number.

Where this appendix comes from

The code, family and meaning columns of this table are built from documents/ERROR_INDEX.md. That index is itself not hand-written but generated from the compiler’s catalogue.

$ ./bin/lune explain --index > documents/ERROR_INDEX.md

So this table comes from the catalogue in lune/explanations.py — the same primary source as the implementation. When a code is added or changed, regenerate the index and then update this table.