Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/noir-lang/noir/llms.txt

Use this file to discover all available pages before exploring further.

The Noir standard library provides several generic container types for storing and retrieving data. Because Noir targets fixed-circuit compilation, most containers have compile-time or explicitly bounded sizes.

Option<T>

Option<T> expresses the presence (Some(value)) or absence (None) of a value. It is automatically in scope — no import required.
// Internal representation
pub struct Option<T> {
    _is_some: bool,
    _value: T,
}

Constructing values

let none: Option<u32> = Option::none();
let some: Option<u32> = Option::some(42);

Methods

pub fn is_some(&self) -> bool
pub fn is_none(&self) -> bool
Returns true if the option is Some or None respectively.
let x = Option::some(3);
assert(x.is_some());
assert(!x.is_none());
pub fn unwrap(self) -> T
Asserts self.is_some() and returns the wrapped value. Fails if the option is None.
let x = Option::some(10);
let value = x.unwrap(); // 10
pub fn unwrap_or(self, default: T) -> T
Returns the wrapped value when Some, or default when None.
let x: Option<u32> = Option::none();
let value = x.unwrap_or(99); // 99
pub fn unwrap_or_else<Env>(self, default: fn[Env]() -> T) -> T
Returns the wrapped value when Some, or calls default() when None.
let x: Option<u32> = Option::none();
let value = x.unwrap_or_else(|| 0);
pub fn unwrap_unchecked(self) -> T
Returns the inner value without asserting is_some(). When the option is None, the return value is unspecified (zeroed memory). Use only when you have already verified the option is Some through another path.
pub fn expect<let N: u32, MessageTypes>(self, message: fmtstr<N, MessageTypes>) -> T
Asserts is_some() with a custom error message, then returns the value.
let x: Option<u32> = Option::none();
let value = x.expect(f"Expected a value but got None");
pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> Option<U>
Applies f to the value if Some(x), returning Some(f(x)). Returns None if the option is None.
let x = Option::some(4_u32);
let doubled = x.map(|n| n * 2); // Some(8)
pub fn map_or<U, Env>(self, default: U, f: fn[Env](T) -> U) -> U
pub fn map_or_else<U, Env, EEnv>(self, default: fn[EEnv]() -> U, f: fn[Env](T) -> U) -> U
Like map, but returns a default value instead of None when the option is None.
pub fn and<U>(self, other: Option<U>) -> Option<U>
pub fn and_then<U, Env>(self, f: fn[Env](T) -> Option<U>) -> Option<U>
and returns None if self is None, otherwise returns other.
and_then (flat_map) calls f with the Some value, returning its result; returns None if self is None.
pub fn or(self, other: Option<T>) -> Option<T>
pub fn or_else<Env>(self, default: fn[Env]() -> Option<T>) -> Option<T>
Returns self if it is Some, otherwise returns other / default().
pub fn filter<Env>(self, predicate: fn[Env](T) -> bool) -> Option<T>
Returns Some(x) if self is Some(x) and predicate(x) is true. Otherwise returns None.
pub fn flatten(self) -> Option<T>  // where self: Option<Option<T>>
Flattens Option<Option<T>> into Option<T>. Returns None if the outer option is None.

BoundedVec<T, MaxLen>

A growable array bounded by a compile-time maximum length MaxLen. Internally backed by a fixed-size array, so element access is always O(1).
let mut vec: BoundedVec<Field, 10> = BoundedVec::new();
for i in 0..5 {
    vec.push(i as Field);
}
assert(vec.len() == 5);
assert(vec.max_len() == 10);
Always specify the maximum length via a type annotation. Omitting it defaults MaxLen to zero, which will cause a constraint failure at runtime when you push an element.

Construction

pub fn new() -> Self

// Creates an empty vector. All backing storage is zeroed.
let v: BoundedVec<u32, 8> = BoundedVec::new();
assert(v.len() == 0);

Element access

pub fn get(self, index: u64) -> T
pub fn get_unchecked(self, index: u64) -> T
get performs a bounds check and fails the constraint if index >= len. get_unchecked skips the check — only use it when you have already verified the index is in range.
fn first_and_last<N>(v: BoundedVec<u32, N>) -> (u32, u32) {
    (v.get(0), v.get(v.len() - 1))
}

Mutation

pub fn set(&mut self, index: u64, value: T)
pub fn set_unchecked(&mut self, index: u64, value: T) -> T
pub fn push(&mut self, elem: T)
pub fn pop(&mut self) -> T
MethodDescription
setWrites a value at index; fails if index >= len
set_uncheckedWrites without a bounds check
pushAppends to the end; panics if len == MaxLen
popRemoves and returns the last element; panics if len == 0
let mut v: BoundedVec<u32, 5> = BoundedVec::new();
v.push(10);
v.push(20);
assert(v.pop() == 20);
assert(v.len() == 1);

Length and capacity

pub fn len(self) -> u64
pub fn max_len(_self: BoundedVec<T, MaxLen>) -> u64
pub fn storage(self) -> [T; MaxLen]
max_len() always returns MaxLen. storage() gives direct access to the backing array — note that elements at indices >= len may be zeroed.

Bulk operations

pub fn extend_from_array<Len>(&mut self, array: [T; Len])
pub fn extend_from_bounded_vec<Len>(&mut self, vec: BoundedVec<T, Len>)
Both methods append all elements; they panic if the resulting length would exceed MaxLen.
let mut v: BoundedVec<u32, 10> = BoundedVec::new();
v.extend_from_array([1, 2, 3]);
assert(v.len() == 3);

Functional methods

pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> BoundedVec<U, MaxLen>
pub fn mapi<U, Env>(self, f: fn[Env](u32, T) -> U) -> BoundedVec<U, MaxLen>
pub fn for_each<Env>(self, f: fn[Env](T) -> ())
pub fn for_eachi<Env>(self, f: fn[Env](u32, T) -> ())
pub fn any<Env>(self, predicate: fn[Env](T) -> bool) -> bool
let v: BoundedVec<u32, 5> = BoundedVec::from_array([1, 2, 3]);
let doubled = v.map(|x| x * 2); // [2, 4, 6]
let has_large = v.any(|x| x > 2); // true

HashMap<K, V, MaxLen, B>

A bounded, compile-time-sized hash map using open addressing with quadratic probing. It stores up to MaxLen entries, but due to hash collisions the practical maximum may be lower. The load factor is capped at 0.75 — inserting beyond this limit causes a constraint failure. K must implement Hash + Eq. B is a BuildHasher. The recommended hasher is BuildHasherDefault<Poseidon2Hasher>.
use std::hash::poseidon2::Poseidon2Hasher;
use std::hash::BuildHasherDefault;

type MyMap = HashMap<Field, u32, 12, BuildHasherDefault<Poseidon2Hasher>>;

let mut map: MyMap = HashMap::default();
map.insert(1, 100);
map.insert(2, 200);

let val = map.get(1).unwrap(); // 100

Construction

// Creates an empty map using the type's default hasher
pub fn default() -> Self
where B: BuildHasher + Default

// Creates a map with an existing hasher instance
pub fn with_hasher(_build_hasher: B) -> Self
where B: BuildHasher

Insertion and removal

pub fn insert(&mut self, key: K, value: V)
where K: Eq + Hash, B: BuildHasher

pub fn remove(&mut self, key: K)
where K: Eq + Hash, B: BuildHasher
insert overrides the previous value if the key already exists. remove is a no-op if the key is absent.
map.insert(42, 999);
map.remove(42);
assert(!map.contains_key(42));

Lookup

pub fn get(&self, key: K) -> Option<V>
where K: Eq + Hash, B: BuildHasher

pub fn contains_key(&self, key: K) -> bool
where K: Eq + Hash, B: BuildHasher
if map.contains_key(7) {
    let value = map.get(7).unwrap();
    println(value);
}

Size and capacity

pub fn len(&self) -> u32
pub fn is_empty(&self) -> bool
pub fn capacity(_self: &Self) -> u32
pub fn clear(&mut self)
capacity() always returns MaxLen. clear() removes all entries.

Iteration

pub fn entries(&self) -> BoundedVec<(K, V), N>
pub fn keys(&self) -> BoundedVec<K, N>
pub fn values(&self) -> BoundedVec<V, N>

pub fn iter_mut(&mut self, f: fn(K, V) -> (K, V))
where K: Eq + Hash, B: BuildHasher

pub fn iter_keys_mut(&mut self, f: fn(K) -> K)
where K: Eq + Hash, B: BuildHasher

pub fn iter_values_mut(&mut self, f: fn(V) -> V)

pub fn retain(&mut self, f: fn(K, V) -> bool)
// Double every value in the map
map.iter_values_mut(|v| v * 2);

// Remove entries where the key is zero
map.retain(|k, _v| k != 0);

// Iterate over all entries
let entries = map.entries();
for i in 0..map.capacity() {
    if i < entries.len() {
        let (k, v) = entries.get(i);
        println(f"{k} -> {v}");
    }
}
iter_mut and iter_keys_mut rebuild the internal hash table as they run because keys affect slot positions. Prefer iter_values_mut when only values need to change.

UHashMap<K, V, B>

UHashMap is an unbounded, dynamically-growing hash map for use in unconstrained or comptime code. Most operations on UHashMap are unconstrained — their results are not constrained when returned into constrained code.
use std::hash::poseidon2::Poseidon2Hasher;
use std::hash::BuildHasherDefault;

unconstrained fn build_map() -> UHashMap<Field, u32, BuildHasherDefault<Poseidon2Hasher>> {
    let mut map: UHashMap<Field, u32, BuildHasherDefault<Poseidon2Hasher>> = UHashMap::default();
    map.insert(1, 2);
    map.insert(3, 4);
    map
}
UHashMap exposes the same method surface as HashMap:
MethodDescription
default() / with_hasher(b)Construct an empty map
insert(key, value)Insert or update a key
get(key) -> Option<V>Look up a key
remove(key)Delete a key
contains_key(key) -> boolCheck for presence
len() -> u32Current number of entries
is_empty() -> boolTrue when empty
clear()Remove all entries
entries()All (K, V) pairs as a vector
keys() / values()All keys or values as vectors
iter_mut(f)Mutate keys and values
iter_keys_mut(f)Mutate keys only
iter_values_mut(f)Mutate values only
retain(f)Keep only matching entries
UHashMap results are not constrained. If you return values from a UHashMap into constrained Noir code, you must manually add the necessary constraints to ensure correctness.

Build docs developers (and LLMs) love