Skip to main content
Version: v1.0.0-beta.0

Type

std::meta::typ contains methods on the built-in Type type used for representing a type in the source program.

Functions

fresh_type_variable
pub comptime fn fresh_type_variable() -> Type {}

Source code: noir_stdlib/src/meta/typ.nr#L57-L59

Creates and returns an unbound type variable. This is a special kind of type internal to type checking which will type check with any other type. When it is type checked against another type it will also be set to that type. For example, if a is a type variable and we have the type equality (a, i32) = (u8, i32), the compiler will set a equal to u8.

Unbound type variables will often be rendered as _ while printing them. Bound type variables will appear as the type they are bound to.

This can be used in conjunction with functions which internally perform type checks such as Type::implements or Type::get_trait_impl to potentially grab some of the types used.

Note that calling Type::implements or Type::get_trait_impl on a type variable will always fail.

Example:

serialize-setup
trait Serialize<let N: u32> {}

impl Serialize<1> for Field {}

impl<T, let N: u32, let M: u32> Serialize<N * M> for [T; N]
where
T: Serialize<M>,
{}

impl<T, U, let N: u32, let M: u32> Serialize<N + M> for (T, U)
where
T: Serialize<N>,
U: Serialize<M>,
{}

Source code: test_programs/compile_success_empty/comptime_type/src/main.nr#L14-L29

fresh-type-variable-example
let typevar1 = std::meta::typ::fresh_type_variable();
let constraint = quote { Serialize<$typevar1> }.as_trait_constraint();
let field_type = quote { Field }.as_type();

// Search for a trait impl (binding typevar1 to 1 when the impl is found):
assert(field_type.implements(constraint));

// typevar1 should be bound to the "1" generic now:
assert_eq(typevar1.as_constant().unwrap(), 1);

// If we want to do the same with a different type, we need to
// create a new type variable now that `typevar1` is bound
let typevar2 = std::meta::typ::fresh_type_variable();
let constraint = quote { Serialize<$typevar2> }.as_trait_constraint();
let array_type = quote { [(Field, Field); 5] }.as_type();
assert(array_type.implements(constraint));

// Now typevar2 should be bound to the serialized pair size 2 times the array length 5
assert_eq(typevar2.as_constant().unwrap(), 10);

Source code: test_programs/compile_success_empty/comptime_type/src/main.nr#L129-L149

Methods

as_array

as_array
pub comptime fn as_array(self) -> Option<(Type, Type)> {}

Source code: noir_stdlib/src/meta/typ.nr#L76-L78

If this type is an array, return a pair of (element type, size type).

Example:

comptime {
let array_type = quote { [Field; 3] }.as_type();
let (field_type, three_type) = array_type.as_array().unwrap();

assert(field_type.is_field());
assert_eq(three_type.as_constant().unwrap(), 3);
}

as_constant

as_constant
pub comptime fn as_constant(self) -> Option<u32> {}

Source code: noir_stdlib/src/meta/typ.nr#L83-L85

If this type is a constant integer (such as the 3 in the array type [Field; 3]), return the numeric constant.

as_integer

as_integer
pub comptime fn as_integer(self) -> Option<(bool, u8)> {}

Source code: noir_stdlib/src/meta/typ.nr#L90-L92

If this is an integer type, return a boolean which is true if the type is signed, as well as the number of bits of this integer type.

as_mutable_reference

as_mutable_reference
comptime fn as_mutable_reference(self) -> Option<Type> {}

Source code: noir_stdlib/src/meta/typ.nr#L96-L98

If this is a mutable reference type &mut T, returns the mutable type T.

as_slice

as_slice
pub comptime fn as_slice(self) -> Option<Type> {}

Source code: noir_stdlib/src/meta/typ.nr#L102-L104

If this is a slice type, return the element type of the slice.

as_str

as_str
pub comptime fn as_str(self) -> Option<Type> {}

Source code: noir_stdlib/src/meta/typ.nr#L108-L110

If this is a str<N> type, returns the length N as a type.

as_struct

as_struct
pub comptime fn as_struct(self) -> Option<(StructDefinition, [Type])> {}

Source code: noir_stdlib/src/meta/typ.nr#L114-L116

If this is a struct type, returns the struct in addition to any generic arguments on this type.

as_tuple

as_tuple
pub comptime fn as_tuple(self) -> Option<[Type]> {}

Source code: noir_stdlib/src/meta/typ.nr#L120-L122

If this is a tuple type, returns each element type of the tuple.

get_trait_impl

get_trait_impl
pub comptime fn get_trait_impl(self, constraint: TraitConstraint) -> Option<TraitImpl> {}

Source code: noir_stdlib/src/meta/typ.nr#L143-L145

Retrieves the trait implementation that implements the given trait constraint for this type. If the trait constraint is not found, None is returned. Note that since the concrete trait implementation for a trait constraint specified from a where clause is unknown, this function will return None in these cases. If you only want to know whether a type implements a trait, use implements instead.

Example:

comptime {
let field_type = quote { Field }.as_type();
let default = quote { Default }.as_trait_constraint();

let the_impl: TraitImpl = field_type.get_trait_impl(default).unwrap();
assert(the_impl.methods().len(), 1);
}

implements

implements
pub comptime fn implements(self, constraint: TraitConstraint) -> bool {}

Source code: noir_stdlib/src/meta/typ.nr#L166-L168

true if this type implements the given trait. Note that unlike get_trait_impl this will also return true for any where constraints in scope.

Example:

fn foo<T>() where T: Default {
comptime {
let field_type = quote { Field }.as_type();
let default = quote { Default }.as_trait_constraint();
assert(field_type.implements(default));

let t = quote { T }.as_type();
assert(t.implements(default));
}
}

is_bool

is_bool
pub comptime fn is_bool(self) -> bool {}

Source code: noir_stdlib/src/meta/typ.nr#L172-L174

true if this type is bool.

is_field

is_field
pub comptime fn is_field(self) -> bool {}

Source code: noir_stdlib/src/meta/typ.nr#L178-L180

true if this type is Field.

is_unit

is_unit
comptime fn is_unit(self) -> bool {}

Source code: noir_stdlib/src/meta/typ.nr#L184-L186

true if this type is the unit () type.

Trait Implementations

impl Eq for Type
impl Hash for Type

Note that this is syntactic equality, this is not the same as whether two types will type check to be the same type. Unless type inference or generics are being used however, users should not typically have to worry about this distinction unless std::meta::typ::fresh_type_variable is used.