[−][src]Trait rusttyc::types::Abstract
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 returnsT
.
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 plusAbstract::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.
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()
.
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.