Finalize on a bare dynamic array or variant
Split out of [[feature-a-implement-initialize-and-finalize-over-the-arc-helpers]] while landing it, 2026-08-21.
What works and what does not
| lvalue | Initialize | Finalize |
|---|---|---|
| record with managed members | PXXRecordInitialize |
PXXRecordFinalize |
| record with none | no-op (FPC parity) | no-op |
| AnsiString | raw zero store | desugared to x := '' |
| unmanaged | no-op | no-op |
| bare dynamic array | compile error | compile error |
| zero 16 bytes | PXXVarClear(@v) — done 2026-08-24 |
An error, deliberately, not a no-op — a silent no-op on a managed type is the exact defect the parent ticket was filed for, so the gap says so out loud.
Why it stopped there
PXXDynArrayRelease(data, desc) needs the array's ELEMENT layout descriptor.
Records reach theirs through IR_CONST_DATA with
-(RECORD_RTTI_DATAREF_BASE + ci), resolved by the pre-link fixup pass in
compiler.pas. A per-SYMBOL element descriptor is GetOrAllocSymRTTI(symIdx),
which is codegen-level — and SYM_RTTI_DATAREF_BASE (300000) is declared in
defs.inc but has no fixup branch, so there is no IR-level route to it.
So the work is one of:
- Give
SYM_RTTI_DATAREF_BASEa real fixup branch, making per-symbol descriptors reachable from IR the way record ones are. Probably the right fix — the constant already exists and reads as if it worked. - Or route the bare cases through the record path by other means.
Variants are cheaper and separable: Finalize(v) is PXXVarClear(@v) (already
idempotent — it clears in place), and Initialize(v) is zeroing 16 bytes, since
varEmpty is 0. That half could land on its own.
Why it is low prio
The gap is genuinely narrow: a record containing a dynamic array or variant is
fully handled (PXXRecordFinalize walks to PXXDynArrayRelease with the
sub-descriptor), and a bare one has a one-line workaround that does exactly what
Finalize must — a := nil releases the old reference and nils, and VarClear(v)
exists. Neither is on the parent ticket's motivating path (a GetMem'd record).
Gate
Track A: repro proving a bare dyn array's elements are released and a copy taken
beforehand survives; test_initialize_finalize extended; self-host
byte-identical.