Skip to main content

ErrorKind

Enum ErrorKind 

Source
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.

Fields

§left: Box<Type>
§right: Box<Type>
§origin: Box<Origin>
§

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

§variable: String

The variable as the source wrote it, a.

§binder: Binder

What the variable was written in.

§tpe: Box<Type>

What the body would need it to be, written with the source’s names for the other rigid variables it holds. Boxed for the reason UnificationFailed’s types are.

§origin: Box<Origin>
§

CircularType

A type variable would have to occur inside its own solution.

Fields

§tpe: Box<Type>

The type the variable would have had to contain itself in. Boxed for the reason above.

§origin: Box<Origin>
§

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.

Fields

§name: String
§span: NodeSpan

Where the name was written.

§

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

§label: Name
§span: NodeSpan
§supplier: Supplier

What could supply the record type, which is what the note says.

§

MissingField

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

§record: Box<Type>

The record type, as solved. Boxed for the reason UnificationFailed’s types are.

§label: Name
§span: NodeSpan
§because: Option<Cause>

Where the record type came from — the annotation, typically — when something brought it in; the secondary label goes under it.

§

NotARecord

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.

Fields

§tpe: Box<Type>
§label: Name
§span: NodeSpan
§because: Option<Cause>
§

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

§class: QualName
§tpe: Box<Type>

Boxed for the reason UnificationFailed’s types are.

§needed_by: Option<Box<Predicate>>
§origin: Box<Origin>
§

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

§class: QualName
§variable: String

The variable as the source wrote it, a.

§written: Written

What is missing the constraint.

§origin: Box<Origin>
§

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

§class: QualName
§stated: String

What the declaration has to state, constraints and type: Eq a => a -> a -> Bool.

§origin: Box<Origin>
§

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.

Fields

§class: QualName
§origin: Box<Origin>

Trait Implementations§

Source§

impl Debug for ErrorKind

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.