#[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::Anyis represented asany.Self::Dyntypes are represented as documented inDynConstraints.Primitive types are represented using theDisplayimplementation of the correspondingPrimitiveType.Vars are represented as documented inTypeVar.- Notation for functional and tuple types is documented separately.
§Examples
There are conversions to construct Types 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 exteremely 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 = r#"
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 funcion 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_span().fragment(), "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
Source§impl<Prim: PrimitiveType> PartialEq for Type<Prim>
impl<Prim: PrimitiveType> PartialEq for Type<Prim>
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§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> PipeAsRef for T
impl<T> PipeAsRef for T
Source§impl<T> PipeBorrow for T
impl<T> PipeBorrow for T
Source§impl<T> PipeDeref for T
impl<T> PipeDeref for T
Source§impl<T> PipeRef for T
impl<T> PipeRef for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
fn tap<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
Source§fn tap_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
fn tap_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&Self) -> R,
tap in debug builds, and does nothing in release builds.Source§fn tap_mut<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
fn tap_mut<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
Source§fn tap_mut_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
fn tap_mut_dbg<F, R>(self, func: F) -> Selfwhere
F: FnOnce(&mut Self) -> R,
tap_mut in debug builds, and does nothing in release builds.Source§impl<T, U> TapAsRef<U> for Twhere
U: ?Sized,
impl<T, U> TapAsRef<U> for Twhere
U: ?Sized,
Source§fn tap_ref<F, R>(self, func: F) -> Self
fn tap_ref<F, R>(self, func: F) -> Self
Source§fn tap_ref_dbg<F, R>(self, func: F) -> Self
fn tap_ref_dbg<F, R>(self, func: F) -> Self
tap_ref in debug builds, and does nothing in release builds.Source§fn tap_ref_mut<F, R>(self, func: F) -> Self
fn tap_ref_mut<F, R>(self, func: F) -> Self
Source§impl<T, U> TapBorrow<U> for Twhere
U: ?Sized,
impl<T, U> TapBorrow<U> for Twhere
U: ?Sized,
Source§fn tap_borrow<F, R>(self, func: F) -> Self
fn tap_borrow<F, R>(self, func: F) -> Self
Source§fn tap_borrow_dbg<F, R>(self, func: F) -> Self
fn tap_borrow_dbg<F, R>(self, func: F) -> Self
tap_borrow in debug builds, and does nothing in release builds.Source§fn tap_borrow_mut<F, R>(self, func: F) -> Self
fn tap_borrow_mut<F, R>(self, func: F) -> Self
Source§impl<T> TapDeref for T
impl<T> TapDeref for T
Source§fn tap_deref_dbg<F, R>(self, func: F) -> Self
fn tap_deref_dbg<F, R>(self, func: F) -> Self
tap_deref in debug builds, and does nothing in release builds.Source§fn tap_deref_mut<F, R>(self, func: F) -> Self
fn tap_deref_mut<F, R>(self, func: F) -> Self
self for modification.