← board

const/value open-array of a managed element loses its length (High = -1)

Symptom

A const (or value) open-array parameter whose element type is managed (AnsiString) receives a wrong implicit length when the argument is a fixed array: High(a) comes back as -1 (length 0). The element type matters — the same code with array of Integer is correct.

Minimal repro

program oas;
procedure P(const a: array of AnsiString);
var i: Integer;
begin
  writeln('high=', High(a));
  for i := 0 to High(a) do writeln(a[i]);
end;
var arr: array[0..2] of AnsiString;
begin
  arr[0] := 'x'; arr[1] := 'y'; arr[2] := 'z';
  P(arr);            { prints high=-1 and nothing else; expected high=2, x y z }
end.

Control — array of Integer is fine:

function P(const a: array of Integer; n: Integer): Integer; begin P := High(a) + n; end;
{ P(arr, 5) = 7, P(arr, v) = 3  -- High(a)=2, correct }

Likely cause

The implicit high/length companion for a const/value open array of a managed element type is not materialised from a fixed-array argument (it reads as -1). The fix for var/out (bug-var-open-array-fixed-arg-length) did not cover the const/value path for managed elements; compare the two and the data-pointer vs length companion for a fixed-array lvalue with a managed element type.

Impact

Any library taking const items: array of AnsiString (menus, tables, option lists) is unusable — silently empty same-unit, a crash cross-unit. Found writing test/lib_tui_app.pas. Worked around in Track B by keeping the menu widget to the pure MenuNavigate logic and leaving item rendering to the caller (a plain indexed loop, no managed open-array parameter); MenuDraw was removed until this is fixed — no library code bent to a wrong shape.

Acceptance

Fix log