← board

Typed-constant array of string is broken (segfault ≤2 elems, bogus error ≥3)

Symptom

A typed constant array whose element type is string either silently produces broken data (runtime segfault on first access) or is rejected with a misleading capacity error, depending on element count:

const A: array[0..0] of string = ('a');            { compiles, SEGFAULT reading A[0] }
const A: array[0..1] of string = ('a','b');        { compiles, SEGFAULT reading A[0] }
const A: array[0..2] of string = ('a','b','c');    { error: too many array constant elements }

The same shapes with non-managed element types work fine:

const P: array[0..4] of integer = (2,3,5,7,11);    { OK }
const C: array[0..2] of char    = ('a','b','c');   { OK -> abc }

So the trigger is the string (managed) element type, not the element count or the index base (0-based and 1-based both fail identically).

Isolation (stable v97)

Declaration Compiles? Runs?
array[0..4] of integer = (...) yes OK
array[0..2] of char = (...) yes OK
array[0..0] of string = ('a') yes SIGSEGV
array[0..1] of string = ('a','b') yes SIGSEGV
array[0..2] of string = ('a','b','c') notoo many array constant elements

Two distinct failure modes from one root: the const-array element emitter doesn't handle managed-string elements (emits no/garbage string handle → deref segfaults), and the element counter appears to overcount string entries (3 literals trip the MAX_* element ceiling, hence the bogus "too many" at 3 — note this is a different defect from the genuine capacity wall in [[bug-array-const-too-many-elements-synapse]], which needs many elements).

Likely cause

The typed-const array path emits element data assuming a fixed scalar element size and a plain literal value. A string element needs a managed-string constant (a pointer to const string data + length, ARC-aware), which the const emitter does not build — so the slot holds garbage and the overrun also confuses the element-count check. Look at where typed-const array initializers are lowered (consteval / static data emission) and add a managed-string element case mirroring how a single const s: string = '...' is emitted.

Additional isolation (2026-06-30, found independently while building lib/asmcore)

Hit the same too many array constant elements () message via a different trigger axis: element string length, not just element count. Minimal repro, a single-element array:

const a: array[0..0] of AnsiString = ('r0');   { error: too many array constant elements () }
const a: array[0..0] of AnsiString = ('ab');   { same error }
const a: array[0..0] of AnsiString = ('0');    { compiles (didn't verify runtime correctness) }
const a: array[0..0] of AnsiString = ('r');    { compiles (didn't verify runtime correctness) }

So with a 1-element array (which this ticket's table shows segfaults rather than erroring, for 1-char elements 'a'), a 2+ character string literal flips it straight to the "too many" error instead of compiling-then- segfaulting. Consistent with this ticket's existing hypothesis ("the element counter appears to overcount string entries") — looks like whatever counts elements is counting something proportional to string content (characters, bytes, or similar) rather than array elements, so both element count and per-element string length shift when the bogus ceiling trips. Real-world trigger: array[0..15] of AnsiString register-name tables ('rax', 'r10', etc., 2-3 chars each) — exactly the multi-char-string-array idiom this ticket already flags as "very common."

Acceptance