- 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.
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.