Skip to main content

Type

Enum Type 

Source
pub enum Type {
    Variable(Name),
    Type(QualName, Vec<Type>),
    Record(BTreeMap<Name, Type>),
    Arrow(Box<Type>, Box<Type>),
    Tuple(Tuple<Type>),
    Unit,
}
Expand description

A canonical type.

§Why there is no span on this type, or on TypeConstructor

Every other canonical node this module builds carries a [NodeSpan] taken from the parser node it came from. A Type deliberately does not.

The reason ERR-3 recorded is that a Type does not always come from the module being canonicalized: Type::from_parser_type resolves a name through the Environment, which clones types straight out of the Interfaces of the modules this one imports, so the Type handed back may well have been written in a different file — and a bare span on it would be read as a position in the importing module’s source. ERR-5 settled that half: a SpanLabel can now carry a file of its own, so “written in another file” is no longer the obstacle.

The other half is unfinished work, not an impossibility. parser::Type carries a [NodeSpan] per node like every other parser node, and Type::from_parser_type is the recursive walk over it — tpe.span is in hand at every level, and each branch of an Arrow arrives as its own spanned parser::Type. Those spans are discarded here by choice. Keeping them means a span field on every canonical Type node, plus a decision about what a Type cloned out of an Environment should then report — where it was written, or where it was used. Nobody has written that.

What exists instead is coarser and enough for the diagnostics that exist: the declaration a Type is the type of — Value’s own span, UnionType’s, Infix’s — is what a diagnostic wants to underline (“defined here”), not a position inside the type expression itself. Interface::values pairs each value’s Type with that declaration’s [NodeSpan], and Interface::source_span pairs it with the file, once Interface::file is set. A type error still points at the whole declaration that failed rather than the sub-expression that disagrees, which is ERR-4, a separate limit in the typer’s own Term/Constraint translation.

Variants§

§

Variable(Name)

§

Type(QualName, Vec<Type>)

A named type applied to its arguments, the name being the QualName of the declaration it resolved to.

The module is part of the identity of the type, not decoration on it: a type Size in Widget and a type Size in Gadget are two types, and two values of them are interchangeable nowhere. Carrying only the spelling made them one value here, which is what AST-4 closed. The package is part of it for the same reason: a local Size and a wrapped dependency’s, reached as AcmeWidgets.Size, both declare Size.Size.

The name is the declaration’s, never the spelling that reached it. import Widget as W followed by W.Size records Widget.Size, the same rule name resolution states for values: an alias names a route to a declaration and not a second declaration. A dependency’s namespace is a route too.

§

Record(BTreeMap<Name, Type>)

A record type: each label, and the type of the field it names.

A map rather than the list the source wrote, because a record type is a set of fields: { a : Int, b : Char } and { b : Char, a : Int } are one type, and are one value here. The map is ordered by label (Name’s Ord), so walking it is the label order two spellings of a type agree on. A label appears once: Type::from_parser_type reports a repeated one as Error::RepeatedLabel and builds no Record.

§

Arrow(Box<Type>, Box<Type>)

§

Tuple(Tuple<Type>)

A tuple type. Zelkova keeps Elm’s restriction of two or three elements, which [Tuple] carries in its shape.

§

Unit

The unit type, ().

A form of its own rather than a Type::Type naming a declaration: () is syntax, declared nowhere and resolved through no environment, so no module can declare a type that shares its spelling and there is no name for a lookup to find. Contrast the scalars, which are declared in std/core and known by the qualified name of that declaration.

Implementations§

Source§

impl Type

Source

pub fn arrow_count(&self) -> usize

How many arguments a value of this type takes before its result is not a function: the length of its arrow spine. Int -> Int -> Bool is 2, Int is 0.

Trait Implementations§

Source§

impl Clone for Type

Source§

fn clone(&self) -> Type

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Type

Source§

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

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Type

Source§

fn eq(&self, other: &Type) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Type

Auto Trait Implementations§

§

impl Freeze for Type

§

impl RefUnwindSafe for Type

§

impl Send for Type

§

impl Sync for Type

§

impl Unpin for Type

§

impl UnsafeUnpin for Type

§

impl UnwindSafe for Type

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.