Commit Graph
2 Commits
Author SHA1 Message Date
Chris Tate 6589911a3b Address review and CI: aliases that kept a layout, recursive layouts, divergence scan
- A const that kept its initializer's layout (`const view: Counted[] = entries`)
  is typed by its annotation, so a call that passed it compared the annotated
  layout with the parameter's and copied it. The const now records its
  initializer's type, and a call that passes it binds that type, at function
  and module scope.
- Comparing two recursive layouts (`{ kids: Tree[]; note? }` against
  `{ kids: Plain[] }`) recursed without end and stopped compilation with
  "Maximum call stack size exceeded". A pair already being compared now holds
  for the fields that reach it again.
- The divergence scan reported SC6001 for calls and consts whose layout the
  lowering kept, which the coverage test refuses for corpus programs. The
  lowering records those arguments and initializers, and the scan skips them.
2026-10-26 06:28:48 -05:00
Chris Tate c32adf6f85 Keep the layout of arrays and records passed to wider parameter types
An array or record converts by copying it when its layout differs from the
type it flows into (`{ id; name; owned?: true }[]` into a `{ id; name }[]`
parameter). JavaScript passes the same object, so a callee's `push`, index
stores and element-field writes reached the caller's array in Node but a
copy in the compiled program, and `===` against the original was false.

When an argument names an existing array or record whose layout has every
field of the parameter's type plus optional fields, a direct call of a
declared function now targets an instance of the function lowered with that
parameter bound to the argument's own type. The body reads and writes the
caller's value; a value it stores converts into the argument's layout by
completing the optional fields as absent. Instances are keyed by the
parameter layouts. An instance whose body does not lower is discarded with
everything it recorded, and the call converts as declared.

With the same rule, a non-exported function whose every return names such
a value returns its layout (including the parameter's element or field),
and a const keeps its initializer's layout when the initializer names an
existing value or is a call.
2026-10-26 05:07:05 -05:00