Array[T, N]Status: Accepted
Date: September 19, 2026
Related: ADR-284 (a C value struct’s [f64; 3] field),
ADR-135 §4 (a container that does not allocate) and D2 (a
literal takes its type from its use), ADR-119 (the bare-metal
target and its allocation profile), ADR-293 (an index out of
range aborts), ADR-287 (comptime), Part I 4.5 and 4.6
Two records point here. ADR-284 leaves a C value struct’s
[f64; 3] field undecided, and ADR-135 §4 leaves a container
that does not allocate — which the bare-metal target’s startup profile
(ADR-119) needs, since a Vec allocates and that profile allows
no allocation after start.
The question is the spelling and the literal. Rust’s [T; N] is a new type
form; this language’s type grammar already writes every parameterised type
with brackets — Vec[T], Shared[T], HashMap[K, V].
Array[T, N], in the bracket generic the type language already has.struct Vector3 { parts: Array[f64, 3] }
let origin: Array[f64, 3] = [0.0, 0.0, 0.0]
N is a comptime integer (ADR-287) — a literal, or a constant
that folds. No new type form, no second way of writing a parameter, and the
thing a reader already knows about Vec[T] transfers.
An Array[T, N] is N elements inline: in a struct it is part of the struct,
as an argument it is passed as a value, and nothing is allocated. That is what
makes it the answer to both of the records above — the C field is laid out the
way C lays it out, and the profile with no allocator has a container.
Array[i64, 3] is passed by value the way a tuple of three i64 is, and
Array[String, 3] is lent the way three Strings are.
xs[i] hands back a T — an index is the program’s own arithmetic and a wrong
one is a bug (ADR-293, Part III A.2) — and len() is the N
it was declared with, known while the program is built.
let origin: Array[f64, 3] = [0.0, 0.0, 0.0]
Which is ADR-135 D2’s rule for the empty list extended to a
full one: the literal takes the type its use gives it, and a use that asks for
Array[f64, 3] gets an array rather than a Vec. A literal with no use to
constrain it is a Vec, which is what that record already decided.
A literal whose length does not match N is NK1157, naming both numbers,
because the length is part of the type: Array[f64, 3] is compatible with
nothing but itself.
startup profile has a container.&xs[1..3], which is the range and the view
question together and which no program here has asked.Array needs one; whether
the type language gains them generally is a question with one program behind
it, and this record answers only its own.Array[T, N] with no literal has no value.let, a call argument, a
declared result and a struct literal’s field. A literal anywhere else is a
Vec, and a Vec is not accepted where an array is wanted — that is the
ordinary mismatch.Array[T, N] is wanted becomes the array of what its elements agreed on, so
[1, 2] where an Array[&str, 2] is wanted is refused by that position’s
own mismatch; only the length has a code of its own.Vec[T] is walked through
where an array is what it holds, and an array’s own elements are walked the
same way, every one of them: let grid: Vec[Array[f64, 2]] = [[1.0, 2.0],
[3.0, 4.0]] is a program, and Array[Array[i64, 2], 2] lowers both levels.