ADR-152: A Fixed-Size Array Is 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

1. Context

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].

2. Decisions

D1 — 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.

D2 — It is a value, and it copies as its elements do.

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.

D3 — It is indexed as a list is, and an index out of range aborts.

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.

D4 — A literal takes the array type where the use asks for one.

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.

3. Consequences

4. What this does not decide

5. How a literal meets its use

This site is open source. Improve this page.