Arrays and Vec

coil splits fixed-size arrays from growable vectors (Rust-style).

Fixed arrays — [T; N]#

Homogeneous, fixed length. N is part of the type and is inferred from literals when possible; otherwise it must be written explicitly.

let a = [1, 2, 3];          // [int; 3]
let b: [int; 3] = [0, 0, 0];
a[1] = 9;                   // element assign only
RuleBehavior
Literal [e, …]Infers [T; N] with N = element count
Literal where Vec<T> is expectedBuilds the Vec (let v: Vec<int> = [1, 2], sum([1, 2]))
Annotation [T]Error (E0119), in params and returns too — use [T; N] or Vec<T>
Empty []Only under Vec<T> or [T; 0]
GrowthForbidden — no arr[] =; use Vec

Locals of type [T; N] (N ≥ 1) are laid out as N consecutive frame slots. Each slot holds one Value:

Element TSlot contents
int / float / bool / byteImmediate bits (fully on the stack)
string, class, enum, Vec, …Heap pointer
Nested [U; M]Heap pointer to an ObjArray row (nested data is not flattened)

Escaping into a single-value context (call, return, store into a heap object) boxes the spine into a non-growable heap array. Copying or assigning one stack array local into another copies slots without boxing (forward per-element STORE, so values never pile into the destination slot range).

[T; 0] stays a single empty heap array. Params/returns of [T; N] still pass one heap pointer at the call boundary today, so a parameter aliases the caller’s array: a callee’s a[0] = 0 is seen by the caller. Copy into a local first (let b = a;) when the callee must not change the caller’s array.

x.len() is the one length spelling (the free len(x) was removed; calling it is E0101). Structural array / Vec / tuple / string .len() lowers to ArrayLen, or a constant for a fixed size. Element-wise zip / LA helpers still require fixed lengths.

Vec<T> — growable heap vector#

let v: Vec<int> = Vec::new();
v.push(1);
v.push(2);
let x = v[0];
v[0] = 7;
match v.pop() {
    Option::Some(n) => { /* … */ },
    Option::None => { /* … */ },
};

Methods#

MethodNotes
Vec::new()Empty vector
Vec::with_capacity(n)Empty with reserved capacity
Vec::from(arr)Copy a fixed [T; N] into a Vec
v.push(x)Append
v.pop()Option<T>
v.insert(i, x)Insert at index (panics if i is out of range)
v.remove(i)Option<T>
v.clear()Drop all elements
v.reserve(n)Ensure capacity for len + n
v.capacity() / v.len()Ints
v[i] / v[i] = xIndex get/set (see Out-of-range index)
(0..n).to_vec()Collect a numeric Range / RangeInclusive into Vec<T>

Rest parameters T... xs pack into Vec<T>. Spread accepts [T; N] anywhere in the arguments. A Vec<T> spread must be the last argument and fill a T... xs rest parameter: f(...v) passes v itself as the pack, which is how a rest pack is forwarded. A Vec has no static length, so spreading one into fixed parameters is error E0119.

Numeric ranges (int / byte / float) expose inherent .to_vec() — same step and empty-decreasing rule as for. See Ranges.

IO buffers (to_bytes, read/write) use Vec<byte>.

Out-of-range index#

Runtime a[i] / v[i] panics on a negative or too-large index, or a non-array target. A write v[i] = x with a bad index also panics. The expression type stays T (not Result). Literal OOB on [T; N] and tuples is a compile error.

Proven counted-loop reads/writes rewrite to unchecked / pin opcodes (archive minor 12–13). Prefer i < a.len() in loops.


↑ ↓ navigate ↵ open