[][src]Trait rusttyc::types::Abstract

pub trait Abstract: Eq + Sized + Clone + Debug {
    type Err: Debug;
    type VariantTag: Debug + Clone + Copy + PartialEq + Eq;
    fn variant(&self) -> Option<Self::VariantTag>;
fn unconstrained() -> Self;
fn meet(&self, other: &Self) -> Result<Self, Self::Err>;
fn variant_arity(tag: Self::VariantTag) -> usize;
fn from_tag(tag: Self::VariantTag, children: Vec<Self>) -> Self; fn is_unconstrained(&self) -> bool { ... }
fn arity(&self) -> Option<usize> { ... } }

An abstract type that will be inferred during the type checking procedure.

This trait that needs to be implemented by all (rust-) types that represent a type in the type checking procedure.

Requirements

The abstract types need to follow a lattice structure where the top element is the least constrained, most abstract type possible.

Refinement

This value needs to be provided by the Abstract::unconstrained function. Types will be refined successively using the fallible meet function. If the types are incompatible, i.e., would result in a contradictory type, the meet needs to return a Result::Err. Otherwise, it returns a Result::Ok containing the resulting type. The function needs to follow the rules for abstract meets. Intuitively, these are:

  • The result of a meet needs to be more or equally concrete than either argument.
  • Meeting two types returns the greatest upper bound, i.e., the type that is more or equally concrete to either argument and there is no other, less concrete type meeting this requirement. This especially entails that meeting any type T with an unconstrained type returns T.

Variants

Type can have variants. An integer, for example, has the 0-ary variant identifying it as integers. An optional type on the other hand is 1-ary, i.e., it has one sub-type. Unconstrained type might not have a variant at all.

The type checking procedure needs to construct and destruct types based on their variant.

  • Construction works over Abstract::from_tag taking an array of children, i.e., sub-types, and returning an abstract type.
  • Destruction works over Abstract::variant to obtain information about the variant itself plus Abstract::variant_arity to get its arity. Access to individual subtypes is not required.

Variant Stability

Not every type has a defined variant. However, it needs to comply with two rules:

  • If a type has a variant, it may not change when turning more concrete. Thus, abstract types with ambiguous variants must not return a variant.
  • A leaf type, i.e., a fully resolved non-contradictory type must provide a variant. A consequence is that the meet of two types with different tag will result in an error if both tags are defined.

Example

For a full example of an abstract type system, refer to the crate documentation and the examples. TODO: link!

Associated Types

type Err: Debug

Result of a meet of two incompatible type, i.e., it represents a type contradiction. May contain information regarding why the meet failed.

type VariantTag: Debug + Clone + Copy + PartialEq + Eq

A type that represents different possible variants of the abstract type.

Loading content...

Required methods

fn variant(&self) -> Option<Self::VariantTag>

Returns the type variant of self, if it exists. Refer to the documentation of Abstract for the responsibilities of this function.

fn unconstrained() -> Self

Returns the unconstrained, most abstract type.

fn meet(&self, other: &Self) -> Result<Self, Self::Err>

Attempts to meet two abstract types. Refer to the documentation of Abstract for the responsibilities of this function.

fn variant_arity(tag: Self::VariantTag) -> usize

Provides the arity of a variant. May be 0.

fn from_tag(tag: Self::VariantTag, children: Vec<Self>) -> Self

Creates an abstract type based with the given tag and children.
It is guaranteed that Self::variant_arity(tag) == children.len().

Panics

May panic if Self::variant_arity(tag) != children.len().

Loading content...

Provided methods

fn is_unconstrained(&self) -> bool

Determines whether or not self is the unconstrained type.

fn arity(&self) -> Option<usize>

Provides the arity of the variant of self if it is defined.

Loading content...

Implementors

Loading content...