Skip to main content
Version: dev

StructDefinition

std::meta::struct_def contains methods on the built-in StructDefinition type. This type corresponds to struct Name { field1: Type1, ... } items in the source program.

Methods

add_attribute

add_attribute
pub comptime fn add_attribute<let N: u32>(self, attribute: str<N>) {}

Source code: noir_stdlib/src/meta/struct_def.nr#L5-L7

Adds an attribute to the struct.

add_generic

add_generic
pub comptime fn add_generic<let N: u32>(self, generic_name: str<N>) -> Type {}

Source code: noir_stdlib/src/meta/struct_def.nr#L10-L12

Adds an generic to the struct. Returns the new generic type. Errors if the given generic name isn't a single identifier or if the struct already has a generic with the same name.

This method should be used carefully, if there is existing code referring to the struct type it may be checked before this function is called and see the struct with the original number of generics. This method should thus be preferred to use on code generated from other macros and structs that are not used in function signatures.

Example:

add-generic-example
comptime fn add_generic(s: StructDefinition) {
assert_eq(s.generics().len(), 0);
let new_generic = s.add_generic("T");

let generics = s.generics();
assert_eq(generics.len(), 1);
let (typ, numeric) = generics[0];
assert_eq(typ, new_generic);
assert(numeric.is_none());
}

Source code: test_programs/compile_success_empty/comptime_struct_definition/src/main.nr#L35-L46

as_type

as_type
pub comptime fn as_type(self) -> Type {}

Source code: noir_stdlib/src/meta/struct_def.nr#L17-L19

Returns this struct as a type in the source program. If this struct has any generics, the generics are also included as-is.

generics

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

Source code: noir_stdlib/src/meta/struct_def.nr#L29-L31

Returns each generic on this struct. Each generic is represented as a tuple containing the type, and an optional containing the numeric type if it's a numeric generic.

Example:

#[example]
struct Foo<T, U, let K: u32> {
bar: [T; K],
baz: Baz<U, U>,
}

comptime fn example(foo: StructDefinition) {
assert_eq(foo.generics().len(), 3);

// Fails because `T` isn't in scope
// let t = quote { T }.as_type();
// assert_eq(foo.generics()[0].0, t);
assert(foo.generics()[0].1.is_none());

// Last generic is numeric, so we have the numeric type available to us
assert(foo.generics()[2].1.is_some());
}

fields

fields
pub comptime fn fields(self, generic_args: [Type]) -> [(Quoted, Type)] {}

Source code: noir_stdlib/src/meta/struct_def.nr#L37-L39

Returns (name, type) pairs of each field in this struct. Any generic types used in each field type is automatically substituted with the provided generic arguments.

fields_as_written

fields_as_written
pub comptime fn fields_as_written(self) -> [(Quoted, Type)] {}

Source code: noir_stdlib/src/meta/struct_def.nr#L46-L48

Returns (name, type) pairs of each field in this struct. Each type is as-is with any generic arguments unchanged. Unless the field types are not needed, users should generally prefer to use StructDefinition::fields over this function if possible.

has_named_attribute

has_named_attribute
pub comptime fn has_named_attribute<let N: u32>(self, name: str<N>) -> bool {}

Source code: noir_stdlib/src/meta/struct_def.nr#L22-L24

Returns true if this struct has a custom attribute with the given name.

module

module
pub comptime fn module(self) -> Module {}

Source code: noir_stdlib/src/meta/struct_def.nr#L51-L53

Returns the module where the struct is defined.

name

name
pub comptime fn name(self) -> Quoted {}

Source code: noir_stdlib/src/meta/struct_def.nr#L56-L58

Returns the name of this struct

Note that the returned quoted value will be just the struct name, it will not be the full path to the struct, nor will it include any generics.

set_fields

set_fields
pub comptime fn set_fields(self, new_fields: [(Quoted, Type)]) {}

Source code: noir_stdlib/src/meta/struct_def.nr#L65-L67

Sets the fields of this struct to the given fields list where each element is a pair of the field's name and the field's type. Expects each field name to be a single identifier. Note that this will override any previous fields on this struct. If those should be preserved, use .fields() to retrieve the current fields on the struct type and append the new fields from there.

Example:

// Change this struct to:
// struct Foo {
// a: u32,
// b: i8,
// }
#[mangle_fields]
struct Foo { x: Field }

comptime fn mangle_fields(s: StructDefinition) {
s.set_fields(&[
(quote { a }, quote { u32 }.as_type()),
(quote { b }, quote { i8 }.as_type()),
]);
}

Trait Implementations

impl Eq for StructDefinition
impl Hash for StructDefinition

Note that each struct is assigned a unique ID internally and this is what is used for equality and hashing. So even structs with identical generics and fields may not be equal in this sense if they were originally different items in the source program.