pub enum ErrorKind {
UnificationFailed {
left: Box<Type>,
right: Box<Type>,
origin: Box<Origin>,
},
RigidVariable {
variable: String,
binder: Binder,
tpe: Box<Type>,
origin: Box<Origin>,
},
CircularType {
tpe: Box<Type>,
origin: Box<Origin>,
},
UnboundVariable {
name: String,
span: NodeSpan,
},
RecordTypeUnknown {
label: Name,
form: RecordUse,
span: NodeSpan,
supplier: Supplier,
},
MissingField {
record: Box<Type>,
label: Name,
form: RecordUse,
span: NodeSpan,
because: Option<Cause>,
},
NotARecord {
tpe: Box<Type>,
label: Name,
form: RecordUse,
span: NodeSpan,
because: Option<Cause>,
},
NoInstance {
class: QualName,
tpe: Box<Type>,
needed_by: Option<Box<Predicate>>,
origin: Box<Origin>,
},
MissingConstraint {
class: QualName,
variable: String,
written: Written,
origin: Box<Origin>,
},
ConstraintNeedsAnnotation {
class: QualName,
stated: String,
origin: Box<Origin>,
},
UndeterminedConstraint {
class: QualName,
origin: Box<Origin>,
},
}Expand description
What went wrong, and — for everything unification can raise — where.
Each variant carries the Origin of the constraint that failed, so a type
error can put its caret under the sub-expression that disagrees instead of across
the declaration containing it. The declaration is still named by Error, one
level up, which is the frame that knows it.
Variants§
UnificationFailed
Two types were required to match and do not.
The two are written in the order the message reads them out — declared side first where the source had one. Neither is reliably “the type of the text the origin points at”: by the time a constraint fails, unification has substituted into both sides and may have decomposed the pair the source actually wrote.
RigidVariable
A type variable the declaration is universally quantified over — one its annotation wrote, or one of an instance’s head or of the member signature an instance’s binding is held to — would have to be a type of its own, which a declaration cannot ask of a variable that stands for every type a caller may choose (An annotation is a promise).
Raised where unify meets a rigid variable and anything but that variable: a
concrete type, or another rigid variable of the same declaration.
Fields
CircularType
A type variable would have to occur inside its own solution.
Fields
UnboundVariable
A name the typer’s environment does not know. type_check turns this into a
Solved::UnboundName rather than an Error; that variant says why.
name is environment_key’s package:Module.name lookup key, copied
verbatim from Reference::name — not a spelling. message()’s arm for this
variant renders it as-is, which would print the package if this variant were
ever surfaced as a rendered Error; today type_check never does that (see
above), so the leak has no path to a user yet. Whoever gives this variant a
live path — ERR-8’s planned warning is the likely first one — has to carry a
displayable name (the bare local name, or a QualName rendered the way
Spellings would) alongside this key rather than rendering it directly.
RecordTypeUnknown
A field access, an update, an accessor or a record pattern whose record type nothing else in the declaration supplied: once unification had run over the whole declaration, the type it reads a field of was still a variable (A use does not decide a record’s type).
span is the whole form — person.name, { r | x = 1 }, .name, { name } —
since what is missing is a type for it, not a label in one.
Fields
span: NodeSpanMissingField
A field access, an update, an accessor or a record pattern naming a label the record type it is read against does not have. An update naming one is the update that would add a field (Updating a record).
span is the label for an access, an update’s field and a record pattern’s entry,
and the whole accessor for an accessor, whose label is all of it but the ..
Fields
span: NodeSpanNotARecord
A field access, an update, an accessor or a record pattern whose record is not a record at all: the type it reads a field of was solved to a type of another form.
span is where MissingField’s would be, and because is
as there.
NoInstance
A class is required of a type, and the type has no instance of it: a declared type,
a tuple or () that no instance in reach is declared for, or a function type,
which no instance can be.
The type is the one the obligation had once unification was done, so it can be
the argument of an instance’s context rather than the type the use was at:
needed_by is then the obligation the use raised,
which asked for this one through an instance of its own.
Fields
MissingConstraint
A class is required of a type variable the declaration’s type holds, and the
constraints its annotation (or an instance’s context) wrote do not provide it: the
constraint to add is the fix. The exception is a variable an instance binding’s
member signature binds, which no context of the instance can constrain:
Written::MemberSignature says so.
Fields
ConstraintNeedsAnnotation
A class is required of a type variable the type of a declaration with no
annotation holds. A constraint is never inferred
(DEC-24 decision 5),
so the declaration has to state it.
Fields
UndeterminedConstraint
A class is required of a type variable that is not part of the declaration’s type. Nothing determines the type the class is needed at, and no annotation on this declaration can.