Enum arithmetic_typing::Type
source · #[non_exhaustive]pub enum Type<Prim: PrimitiveType = Num> {
Any,
Dyn(DynConstraints<Prim>),
Prim(Prim),
Function(Box<Function<Prim>>),
Tuple(Tuple<Prim>),
Object(Object<Prim>),
Var(TypeVar),
}
Expand description
Enumeration encompassing all types supported by the type system.
Parametric by the PrimitiveType
.
§Notation
Self::Any
is represented asany
.Self::Dyn
types are represented as documented inDynConstraints
.Prim
itive types are represented using theDisplay
implementation of the correspondingPrimitiveType
.Var
s are represented as documented inTypeVar
.- Notation for functional and tuple types is documented separately.
§Examples
There are conversions to construct Type
s eloquently:
let tuple: Type = (Type::BOOL, Type::NUM).into();
assert_eq!(tuple.to_string(), "(Bool, Num)");
let slice = tuple.repeat(UnknownLen::param(0));
assert_eq!(slice.to_string(), "[(Bool, Num); N]");
let fn_type: Type = Function::builder()
.with_arg(slice)
.returning(Type::NUM)
.into();
assert_eq!(fn_type.to_string(), "([(Bool, Num); N]) -> Num");
A Type
can also be parsed from a string:
let slice = <Type>::try_from(&TypeAst::try_from("[(Bool, Num)]")?)?;
assert_matches!(slice, Type::Tuple(t) if t.as_slice().is_some());
let fn_type = <Type>::try_from(&TypeAst::try_from("([(Bool, Num); N]) -> Num")?)?;
assert_matches!(fn_type, Type::Function(_));
§Any
type
Self::Any
, denoted as any
, is a catch-all type similar to any
in TypeScript.
It allows to circumvent type system limitations at the cost of being extremely imprecise.
any
type can be used in any context (destructured, called with args of any quantity
and type and so on), with each application of the type evaluated independently.
Thus, the same any
variable can be treated as a function, a tuple, a primitive type, etc.
let code = "
wildcard: any = 1; // `any` can be assigned from anything
wildcard == 1 && wildcard == (2, 3);
(x, y, ...) = wildcard; // destructuring `any` always succeeds
wildcard(1, |x| x + 1); // calling `any` as a function works as well
";
let ast = Annotated::<F32Grammar>::parse_statements(code)?;
let mut env = TypeEnvironment::new();
env.process_statements(&ast)?;
// Destructure outputs are certain types that can be inferred
// from their usage, rather than `any`!
assert_matches!(env["x"], Type::Var(_));
let bogus_code = "x + 1 == 2; x(1)";
let ast = Annotated::<F32Grammar>::parse_statements(bogus_code)?;
let errors = env.process_statements(&ast).unwrap_err();
let err = errors.iter().next().unwrap();
assert_eq!(err.main_location().span(bogus_code), "x(1)");
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Any
Any type aka “I’ll think about typing later”. Similar to any
type in TypeScript.
See the dedicated section for more details.
Dyn(DynConstraints<Prim>)
Arbitrary type implementing certain constraints. Similar to dyn _
types in Rust or use of
interfaces in type position in TypeScript.
See DynConstraints
for details.
Prim(Prim)
Primitive type.
Function(Box<Function<Prim>>)
Functional type.
Tuple(Tuple<Prim>)
Tuple type.
Object(Object<Prim>)
Object type.
Var(TypeVar)
Type variable.
Implementations§
source§impl<Prim: PrimitiveType> Type<Prim>
impl<Prim: PrimitiveType> Type<Prim>
sourcepub fn slice(
element: impl Into<Type<Prim>>,
length: impl Into<TupleLen>,
) -> Self
pub fn slice( element: impl Into<Type<Prim>>, length: impl Into<TupleLen>, ) -> Self
Creates a slice type.
sourcepub fn repeat(self, length: impl Into<TupleLen>) -> Slice<Prim>
pub fn repeat(self, length: impl Into<TupleLen>) -> Slice<Prim>
Creates a slice type by repeating this type.
sourcepub fn is_concrete(&self) -> bool
pub fn is_concrete(&self) -> bool
Returns true
iff this type does not contain type / length variables.
See TypeEnvironment
for caveats of dealing with
non-concrete types.
Trait Implementations§
source§impl<Prim: PrimitiveType> Display for Type<Prim>
impl<Prim: PrimitiveType> Display for Type<Prim>
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>> From<(T, U)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>> From<(T, U)> for Type<Prim>where
Prim: PrimitiveType,
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>> From<(T, U, V)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>> From<(T, U, V)> for Type<Prim>where
Prim: PrimitiveType,
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>> From<(T, U, V, W)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>> From<(T, U, V, W)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W)) -> Self
fn from(tuple: (T, U, V, W)) -> Self
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>> From<(T, U, V, W, X)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>> From<(T, U, V, W, X)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W, X)) -> Self
fn from(tuple: (T, U, V, W, X)) -> Self
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>> From<(T, U, V, W, X, Y)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>> From<(T, U, V, W, X, Y)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W, X, Y)) -> Self
fn from(tuple: (T, U, V, W, X, Y)) -> Self
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W, X, Y, Z)) -> Self
fn from(tuple: (T, U, V, W, X, Y, Z)) -> Self
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>, A: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z, A)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>, A: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z, A)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W, X, Y, Z, A)) -> Self
fn from(tuple: (T, U, V, W, X, Y, Z, A)) -> Self
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>, A: Into<Type<Prim>>, B: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z, A, B)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>, A: Into<Type<Prim>>, B: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z, A, B)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W, X, Y, Z, A, B)) -> Self
fn from(tuple: (T, U, V, W, X, Y, Z, A, B)) -> Self
source§impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>, A: Into<Type<Prim>>, B: Into<Type<Prim>>, C: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z, A, B, C)> for Type<Prim>where
Prim: PrimitiveType,
impl<Prim, T: Into<Type<Prim>>, U: Into<Type<Prim>>, V: Into<Type<Prim>>, W: Into<Type<Prim>>, X: Into<Type<Prim>>, Y: Into<Type<Prim>>, Z: Into<Type<Prim>>, A: Into<Type<Prim>>, B: Into<Type<Prim>>, C: Into<Type<Prim>>> From<(T, U, V, W, X, Y, Z, A, B, C)> for Type<Prim>where
Prim: PrimitiveType,
source§fn from(tuple: (T, U, V, W, X, Y, Z, A, B, C)) -> Self
fn from(tuple: (T, U, V, W, X, Y, Z, A, B, C)) -> Self
source§impl<Prim: WithBoolean> From<Assertions> for Type<Prim>
impl<Prim: WithBoolean> From<Assertions> for Type<Prim>
source§fn from(value: Assertions) -> Self
fn from(value: Assertions) -> Self
source§impl<Prim: PrimitiveType> From<DynConstraints<Prim>> for Type<Prim>
impl<Prim: PrimitiveType> From<DynConstraints<Prim>> for Type<Prim>
source§fn from(constraints: DynConstraints<Prim>) -> Self
fn from(constraints: DynConstraints<Prim>) -> Self
source§impl<Prim: PrimitiveType> From<FnWithConstraints<Prim>> for Type<Prim>
impl<Prim: PrimitiveType> From<FnWithConstraints<Prim>> for Type<Prim>
source§fn from(value: FnWithConstraints<Prim>) -> Self
fn from(value: FnWithConstraints<Prim>) -> Self
Auto Trait Implementations§
impl<Prim> Freeze for Type<Prim>where
Prim: Freeze,
impl<Prim = Num> !RefUnwindSafe for Type<Prim>
impl<Prim> Send for Type<Prim>
impl<Prim> Sync for Type<Prim>
impl<Prim> Unpin for Type<Prim>where
Prim: Unpin,
impl<Prim = Num> !UnwindSafe for Type<Prim>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)