pub enum DiagCode {
Show 71 variants
UnterminatedBlockComment,
UnterminatedTemplate,
UnexpectedCharacter,
UnterminatedTextLiteral,
InvalidEscape,
UnterminatedCharLiteral,
CharLiteralIsNotOneCharacter,
UnexpectedToken,
ExpectedStatementSeparator,
InternalNotASourceFile,
UnknownName,
UnknownType,
NameIsNotAType,
DuplicateDeclaration,
NestedFunction,
RecursiveTypeDeclaration,
FunctionReadsOuterBinding,
NotARecordLiteralHead,
RetiredKeyword,
TypeMismatch,
InfiniteType,
AnnotationConflict,
NotEquatable,
NotIterable,
NotOrderable,
WrongTypeArgumentCount,
DuplicateMember,
CompoundAssignNonNumeric,
ReturnOutsideFunction,
BreakOutsideLoop,
IntLiteralOutOfRange,
NotHashable,
NotNumeric,
OperatorNotDefined,
ValueBreakOutsideLoopExpression,
GenericFunctionAsValue,
NoTupleElement,
NotIndexable,
NotAnAssignmentTarget,
NameHasNoFunctionValue,
ParserTemplateOutsideRead,
CallArityMismatch,
InternalMissingType,
NoMethodOnType,
NoFieldOnType,
MissingRecordFields,
UnknownRecordField,
DuplicateRecordField,
NonExhaustiveMatch,
UnreachableArm,
UnknownEnumVariant,
NotAPatternForType,
RefutableBinding,
PayloadArityMismatch,
MalformedParserExpression,
ParserConversion,
UnknownAtomic,
InvalidCaptureName,
UnknownCaptureKind,
UnknownConstructor,
InvalidConstructorArgument,
MixedCaptureNaming,
DuplicateCaptureName,
ConstructorArity,
EmptySeparator,
DuplicateSectionField,
EmptyFieldList,
UnnamedScalarBlockItem,
DuplicateChoiceCase,
MisplacedRepeatedTail,
TemplateScan,
}Expand description
The closed set of diagnostics the compiler can emit.
Every (category, number) pair is written in exactly one place —
DiagCode::code’s exhaustive match — so allocating a code is a
compile-time act with a name rather than an integer literal at a call site.
DiagnosticCode::new is pub(crate) for the same reason: an unregistered
number has no route into a Diagnostic.
The allocation is ADR-051. Adding a variant means amending it first;
every_code_is_distinct is what catches a collision if you do not.
The numbers are not contiguous and are not meant to be: Y09x is internal
errors, Y11x member errors, Y12x match errors. Renumbering them would
change identifiers users have already seen.
Variants§
UnterminatedBlockComment
T001 — a /* with no matching */.
UnterminatedTemplate
T002 — a backtick template with no closing backtick.
UnexpectedCharacter
T003 — a character the lexer cannot classify.
UnterminatedTextLiteral
T004 — a text literal with no closing quote.
InvalidEscape
T005 — a \ escape the lexer does not recognize. Shared by both
literal spellings, with one message each: the escape tables of "…" and
'…' are the same table (ADR-141), so a \x is the same mistake in
either.
UnterminatedCharLiteral
T006 — a character literal with no closing quote.
CharLiteralIsNotOneCharacter
T007 — a character literal that does not name exactly one character.
Two messages under one code, because '' and 'ab' are one rule broken
in two directions. This is the code that closes "##"[0]’s silent
truncation at the front end (ADR-141 Decision 2).
UnexpectedToken
P001 — a token that cannot appear here.
ExpectedStatementSeparator
P002 — two statements with no ; and no line break between them.
InternalNotASourceFile
N000 — internal: the parse tree’s root is not a SOURCE_FILE.
UnknownName
N001 — a name that is not in scope.
UnknownType
N002 — a type annotation naming a type that does not exist.
NameIsNotAType
N003 — a name used in type position that names a value.
DuplicateDeclaration
N004 — one name declared twice in one scope.
NestedFunction
N005 — a function declared inside a function.
RecursiveTypeDeclaration
N006 — a struct/enum declaration that refers to itself, directly or
through a cycle (ADR-063).
A declaration mistake, so it is in this category next to N004/N005
rather than in Y0xx: the mistake is what was declared, and there is no
pair of types to have failed to unify.
FunctionReadsOuterBinding
N007 — a fn body naming a binding declared outside it (ADR-068).
A declaration mistake in the same sense N005 is: the name resolves, and
what is wrong is where it was declared relative to what reads it. A fn
does not capture (§4.9/§4.10 — closures do, functions do not), so the
binding has no storage the body can reach.
It has two message forms. The usual one names both ways out, a parameter
or a closure. When the fn is recursive — directly or mutually — it names
only the parameter and carries an advisory help: line saying why: a
closure cannot name itself, which is N001. One code either way, because
it is the same mistake with one fewer way out.
NotARecordLiteralHead
N008 — a record literal whose head does not name a struct.
A declaration mistake in N003’s sense: a record literal’s head is a type
position, and the name reaches the wrong sort of declaration. Reported in
inference and not at lowering, so praxis check rejects a literal on a
non-struct head rather than letting it produce a value with no
representation.
RetiredKeyword
N009 — a retired keyword written where a statement starts.
let is the only one so far: it was the binding keyword before ADR-125
chose var, so it is the first thing a reader of an old example meets.
Not N001: it is not a name that happens to be missing, and treating it
as one gives the wrong help. The suggestion budget is max(1, len/3),
let is three characters, so the budget is 1 — and the nearest name in
scope one edit away is Set. The rule is right in general (it is
rustc’s); the outcome for a retired keyword is not, because the answer is
known exactly and is not a spelling correction.
let stays a legal identifier (var let = 5 compiles), which is why
this is raised where a statement starts rather than in the lexer.
TypeMismatch
Y001 — two types that could not be unified.
InfiniteType
Y002 — an occurs-check failure.
AnnotationConflict
Y003 — an annotation that conflicts with what inference derived.
NotEquatable
Y004 — a type whose values cannot be compared with ==.
NotIterable
Y005 — a type that cannot be iterated.
NotOrderable
Y006 — a type that has no ordering.
WrongTypeArgumentCount
Y007 — a type constructor given the wrong number of type arguments.
Option[Int, Text] is the same mistake.
DuplicateMember
Y008 — a struct/enum declaring one field or variant twice.
CompoundAssignNonNumeric
Y010 — a compound assignment whose operands are not numeric.
ReturnOutsideFunction
Y011 — return outside a function.
BreakOutsideLoop
Y012 — break/continue outside a loop.
IntLiteralOutOfRange
Y013 — an integer literal outside the representable range.
NotHashable
Y014 — a Map/Set key type that cannot be hashed.
NotNumeric
Y015 — a non-numeric type where a numeric one is required.
OperatorNotDefined
Y016 — an operator not defined for these operand types.
ValueBreakOutsideLoopExpression
Y017 — a break carrying a value out of a while/for.
GenericFunctionAsValue
Y018 — a generic fn used as a value (ADR-061).
A monomorphic one is a closure over its adapter; a generic one has no
instantiation to adapt, because monomorphization is driven by call sites
and a value has none. |x| id(x) is the spelling that works — the
closure’s body is a call site.
NoTupleElement
Y019 — a .0 element access on something that has no such element: a
receiver that is not a tuple, or an index past its arity.
Not Y112 (“no field on this type”): a tuple has no field names, so a
message about a missing field would name the wrong thing. Both are
emitted in inference and both reach praxis check (ADR-093); the reason
for the separate code is the message.
NotIndexable
Y020 — a subscript on a type that has none, in either direction: s[0]
on a Set, t[0] = c on a Text (which can be read through a subscript
and is immutable, so it has no element store), or grid[x] — the wrong
arity for a receiver that does index, since grid[x, y] is the
spelling §6.4 gives.
Not Y110 (“no such method”): a subscript names no method, so a message
about one would name something the program did not write. Both are
emitted in inference and both reach praxis check (ADR-093); the reason
for the separate code is the message.
NotAnAssignmentTarget
Y021 — an assignment whose left side is not a place at all: f() = 1,
a + b[0] = 1. A field is a place and is not among them: p.x = 5
stores (§4.5).
NameHasNoFunctionValue
Y022 — a prelude builtin or an enum constructor named without being
called.
GenericFunctionAsValue’s neighbour,
one symbol kind over. A user fn in value position becomes a closure
over its adapter (ADR-061); a builtin and a constructor have no adapter to
close over, so there is nothing for the name to lower to — without this
code var h = abs then out(h(-3)) prints nothing and exits 0.
out(pi) is the shape a reader meets first: pi is a nullary function,
so the missing parentheses are the whole mistake.
ParserTemplateOutsideRead
Y023 — a backtick parser template written where a value is expected
(ADR-084). §7.1 says the parser-expression sublanguage is entered
at read or at parse(text, …) and nowhere else, so `n = {int}`
standing alone is a template with nothing to parse.
Reported from inference, not the parser, so praxis check sees it. The
token still parses to a LITERAL node so the tree round-trips the source
and one mistake produces one diagnostic.
CallArityMismatch
Y024 — a call whose argument count does not match the function’s
(ADR-089).
A name in Praxis has exactly one signature — no arity-based overloading,
no optional or default parameters — so a count mismatch is never a
candidate for some other overload and can be reported as the mistake it
is. It sits next to Y007, which names collection arity, and Y110,
which names method arity; without it the mistake arrives as a Y001
showing two whole function types to diff by eye.
Raised from TypeDb::unify, which compares the two lengths anyway, so
every function-to-function unification reports it rather than just a
direct call.
InternalMissingType
Y099 — internal: a type the compiler expected was absent.
NoMethodOnType
Y110 — no such method on this type at this arity.
NoFieldOnType
Y112 — no such field on this type.
MissingRecordFields
Y113 — a record literal missing one or more fields.
UnknownRecordField
Y114 — a record literal or pattern naming a field the type does not
have.
DuplicateRecordField
Y115 — a record literal or pattern naming one field twice. In a
pattern the second sub-pattern would silently replace the first, so one
of the two bindings the program wrote would never happen.
NonExhaustiveMatch
Y120 — a match that does not cover every value.
UnreachableArm
Y121 — a match arm an earlier arm already covers.
UnknownEnumVariant
Y122 — a pattern naming a variant the scrutinee’s type has not.
NotAPatternForType
Y123 — a pattern whose shape cannot match the scrutinee, or one no
value can have at all: a one-element tuple pattern, or a record pattern
whose head names something that is not a record.
RefutableBinding
Y125 — a pattern that must match every value but can fail: a literal or
a variant in a binding position, such as a for header.
A binding has no second arm for an item to fall through to, so a pattern that tests would silently skip the steps it does not match.
PayloadArityMismatch
Y124 — a pattern whose sub-patterns do not fit the variant’s payload
(ADR-134).
Two shapes reach this code:
- More sub-patterns than the variant has slots.
Wrap(a, b)against a one-slot variant would read a payload the object does not have. - A bare variant name for a variant that carries a payload.
A => …againstA(Int)says nothing about the valueAholds, and it reads like a payload-less variant to anyone who did not check the declaration. WriteA(_)to say “any payload” out loud.
Naming fewer inside parentheses is legal and is padded with wildcards,
so Some(_) and Some(n) are one test. Bare Some is not a third
spelling of it.
MalformedParserExpression
I000 — a parser expression the lowerer cannot read at all.
ParserConversion
I001 — a parser AST that could not be converted to a type or plan.
UnknownAtomic
I010 — an atomic parser name that does not exist.
InvalidCaptureName
I011 — an invalid capture name in a template.
UnknownCaptureKind
I012 — a capture kind that does not exist.
UnknownConstructor
I013 — a parser constructor that does not exist.
InvalidConstructorArgument
I014 — a constructor argument that is invalid or in excess.
MixedCaptureNaming
I020 — named and anonymous captures mixed in one template (§7.3).
DuplicateCaptureName
I021 — one capture name used twice in a template.
ConstructorArity
I022 — a constructor called with the wrong number of arguments.
EmptySeparator
I023 — an empty separator, which cannot advance a cursor.
DuplicateSectionField
I024 — a section or block field declared twice.
EmptyFieldList
I025 — a sections/choice with no field or case at all.
UnnamedScalarBlockItem
I026 — a positional block item returning a scalar with no name.
DuplicateChoiceCase
I027 — a choice case declared twice.
MisplacedRepeatedTail
I028 — a misplaced or repeated repeated(...) tail.
TemplateScan
I030 — a backtick template the scanner could not read.
Implementations§
Source§impl DiagCode
impl DiagCode
Sourcepub const ALL: &'static [DiagCode]
pub const ALL: &'static [DiagCode]
Every code, so a test can assert the allocation is injective.
code’s exhaustive match forces a new variant to be
numbered; only all_lists_every_variant forces it to be listed here,
and a variant missing from this list is one the injectivity test never
checks.
Sourcepub const fn code(self) -> DiagnosticCode
pub const fn code(self) -> DiagnosticCode
The rendered code. The one place a (category, number) pair exists.