[1, 2, 3], the Empty One Takes Its Type From Its First Use, and a [ at the Start of a Line Begins a LiteralStatus: Accepted
Date: September 19, 2026
Related: ADR-285 (a literal no use constrains takes the first type that holds it), ADR-298 D1 (what a reserved word costs), ADR-291 (a let takes one name or a flat tuple), Part I 2.2 and 4.5
A list is the language’s most-written container, and without a literal it
can only be built a push at a time. The grammar had no [ in expression
position at all, so the syntax is free and the only cost of taking it is the
two questions below.
Two things are the owner’s rather than the compiler’s.
What [] is. An empty literal carries no element type. Either it takes
one from a later use — which is ADR-285’s rule for a number
literal applied to a container — or it is refused with a request for the type.
What a [ at the start of a statement means. After an expression
statement, a line beginning [ is either an index of what came before or a new
literal. Rust reads it as an index and needs a ;; JavaScript reads it the
same way and is famous for it.
[a, b, c] is a list, and [] is an empty one.let xs = [1, 2, 3]
let empty: Vec[i64] = []
let rows = [Row(id: 1), Row(id: 2)]
Changed by ADR-152 D4: a literal standing where its use asks for an Array[T, N] is that array; a literal with no such use is a Vec[T].
The elements are expressions, a trailing comma is allowed, and the type is
Vec[T] where T is what the elements agree on. A literal whose elements do
not agree on a type is NK1154, naming the two, exactly as a let with an
annotation is; where an element has no type yet — a bare 1 fits every
numeric type — it names the kind, so [1, "two"] is refused here.
[] takes the type from the first use, and is refused where none exists.This is ADR-285’s rule one level up: a number literal with
nothing beside it is a value rather than a type, and the first use that needs
a type is what gives it one. So let xs: Vec[i64] = [] is an i64 list,
let mut xs = [] followed by xs.push(1) is an i64 list, and
let xs = [] with no use at all is NK1153 — this empty list has no element
type; write one, or give it a first element. The question is asked once the
whole body has been walked, because the use that answers it stands after the
let.
Refused and not guessed. A default element type would be a type nobody wrote, and the one thing this checker may never do is claim something the program does not say (Part III C.4).
[ at the start of a line begins a literal.An index is written on the line its receiver is on. A statement that begins
with [ is a list literal, always, and there is no lookahead and no ; to
write.
An index across a line break is a shape nobody writes, which is the whole argument: the alternative costs every reader of every list literal a moment of doubt, to keep working a line nobody has typed. Rust and JavaScript both chose the other way and both have the footgun in their style guides.
let xs = [1, 2, 3] is a program, and a list built a push at a time is
one built in a loop, where a push is what the program means.for’s head does:
for p in [1, 2].vec![…], which is what a Vec already is below.{k: v}, which collides with a block and with a struct
literal and is a question of its own.