Skip to main content

Ty

Enum Ty 

Source
pub enum Ty {
Show 17 variants Int, Float, Bool, Char, String, Bytes, Unit, Fn { params: Vec<Ty>, ret: Box<Ty>, }, Future(Box<Ty>), Sum { def_id: DefId, args: Vec<Ty>, }, Record { def_id: DefId, args: Vec<Ty>, }, Array(Box<Ty>), Param(u32), Assoc { on: Box<Ty>, assoc: DefId, }, Var(u32), Never, Error,
}
Expand description

A type. This is the shared type representation across typeck, HIR and monomorphization (spec 12-TYPESYSTEM.md §3, trimmed to the Phase 1 feature set).

Variants§

§

Int

64-bit signed integer (the default integer type).

§

Float

64-bit float (the default float type).

§

Bool

§

Char

§

String

§

Bytes

An immutable byte buffer.

Structurally identical to Ty::String – both are a {len, ptr} GC leaf header; a runtime-made value’s bytes follow it inline in the same object, a String literal’s are static data – and semantically distinct: only String carries a UTF-8 guarantee. Nothing converts between them implicitly. This reaches codegen as the same opaque MirTy::Ptr every other heap pointer already lowers to, so neither backend needs an arm for it – not because every operation on it is an intrinsic (index_of/contains in std/bytes/lib.nova are pure Nova control flow), but because codegen dispatches on MIR types, and Ptr is not new.

§

Unit

The unit type ().

§

Fn

A function type fn(A, B) -> R.

Fields

§params: Vec<Ty>
§ret: Box<Ty>
§

Future(Box<Ty>)

A future produced by calling an async fn; the payload is the function’s declared return type (the future’s output).

Compiler-constructed only: there is no surface syntax that builds one, and no impls may be written on it (head() returns None). At runtime it is the same 2-word fat pointer as a function value — { poll_code, state_ptr } — which is why it sits beside Ty::Fn here rather than being a record in std/core. Nova has no lang-item mechanism: Option and Result are ordinary prelude sums the compiler does not know by name, so a std record could not be recognized.

§

Sum

A user-defined sum type with generic arguments.

Fields

§def_id: DefId
§args: Vec<Ty>
§

Record

A user-defined record (struct) type with generic arguments.

Fields

§def_id: DefId
§args: Vec<Ty>
§

Array(Box<Ty>)

A heap array [T] with elements of a single type.

§

Param(u32)

A generic type parameter of the enclosing item (T).

§

Assoc

A projection onto a trait’s associated type: <on>::Name, where assoc is the associated type’s own DefId (see DefKind::AssocType).

This is the one Ty variant that is not a type by itself — it is a request for one, answerable only with the impl table. It is therefore normalized away at three seams (normalize_ty called from typeck, check_impl_conformance, and mono after subst), and the unifier never has to decide a projection against a concrete type.

on is Param(k) inside a generic body and a concrete type at an ordinary use site.

It can also be an unsolved Var, which the design doc §4.2 claims is unreachable. That claim holds for the case it argues: check_method_call rejects an uninferred receiver with E0011 before any return type is computed, so a receiver’s projection is never on a Var. It does not hold for a generic call, where the type arguments are fresh variables that argument unification narrows as it goes — fn f<I: It>(y: I::Item, x: I) reaches the first parameter with Assoc { on: Var(0) } and nothing has solved Var(0) yet. Checker::instantiate applies the current substitution before normalizing, which covers every ordering where the determining argument comes first; the reverse order is a genuine (order-dependent) limitation of resolving at seams instead of deferring, and it reports an ordinary type mismatch naming the projection rather than anything worse.

Fields

§on: Box<Ty>
§assoc: DefId
§

Var(u32)

An unsolved inference variable (only during type checking).

§

Never

The never type ! (return, panic); coerces to anything.

§

Error

Placeholder after a type error, suppresses cascading errors.

Implementations§

Source§

impl Ty

Source

pub fn subst(&self, args: &[Ty]) -> Ty

Substitute Param(i) with args[i]. Used for generic instantiation and monomorphization.

Source

pub fn mentions_param(&self, idx: u32) -> bool

Whether this type (transitively) mentions the generic parameter idx.

Source

pub fn has_params(&self) -> bool

Whether this type (transitively) contains any generic Param.

Source

pub fn has_vars(&self) -> bool

Whether this type (transitively) contains any inference variable.

Source

pub fn has_assoc(&self) -> bool

Whether this type (transitively) contains an associated-type projection.

Lets a caller ask “is there anything here for normalize_ty to do?” before paying for a normalization pass — and, more importantly, before taking a step that is only correct because a projection is present. The call seams in nova-typeck resolve their inference variables before normalizing, which they must not do to an ordinary signature type.

Source

pub fn has_error(&self) -> bool

Whether this type (transitively) contains Ty::Error.

Ty::Error means “a diagnostic about this type has already been reported”, and it behaves oppositely at the two consumers that read it. At InferCtx::unify it absorbs: it unifies with anything, so a poisoned type silently stops cascading. Ty derives PartialEq with no such absorption, so at a consumer that compares two types directly an Error on one side instead forces a mismatch, and the second diagnostic renders it as the meaningless {error}.

This is for that second kind of consumer: it asks “is either side already poisoned?” so the comparison can be skipped rather than turned into noise. Transitive rather than a top-level == Ty::Error check because the poison is usually nested — an impl binding an unresolvable type makes the trait’s Option<Self::Item> normalize to Option<{error}>, which is not itself Ty::Error.

Source

pub fn head(&self) -> Option<TyHead>

The nominal head of this type, if it has one — used to key impl lookups. Generic arguments do not participate (Phase 1 has no overlapping impls per head).

Source

pub fn match_pattern(&self, ground: &Ty, out: &mut Vec<Option<Ty>>) -> bool

One-directional match: treat self as a pattern that may contain Param(k) and match it against the concrete ground type, recording each Param(k) → ground binding into out (grown as needed). A parameter seen twice must bind to the same type. Returns false on a structural mismatch. Used to recover a generic impl’s type arguments from a concrete receiver type (e.g. Box<T> vs Box<Int> → T=Int).

Trait Implementations§

Source§

impl Clone for Ty

Source§

fn clone(&self) -> Self

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 Ty

Source§

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

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

impl PartialEq for Ty

Source§

fn eq(&self, other: &Self) -> 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 Ty

Auto Trait Implementations§

§

impl Freeze for Ty

§

impl RefUnwindSafe for Ty

§

impl Send for Ty

§

impl Sync for Ty

§

impl Unpin for Ty

§

impl UnsafeUnpin for Ty

§

impl UnwindSafe for Ty

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.