fix(parser): preserve indirect ArrayAccess ??= semantics - #71
Conversation
a65a361 to
753fcc6
Compare
matyhtf
left a comment
There was a problem hiding this comment.
Please rebase this branch onto the latest master; #45, #52, #59, #63, and #66 have now been merged.
The write phase currently dispatches only as isArray() ? item(..., true) : offsetSet(...). The second branch is not equivalent to Zend dimension assignment for a dynamic mixed/php::Var container. For example:
function f(mixed $value): void {
$value['k'] ??= 7;
}
f(1);Zend throws Cannot use a scalar value as an array. Variant::offsetSet() currently does nothing for an integer, so this lowering can return 7 while leaving the target unchanged. Other runtime representations also differ: null must become an array, false follows PHP's deprecated conversion behavior, invalid scalars must throw, and string offsets have their own key/range errors.
Please route the write through a PHPX helper that implements Zend write-dimension semantics for the complete runtime value domain, while retaining the explicit ArrayAccess path only after proving the runtime value is an object. Add PHPT coverage for dynamic null, false, int/float/bool, string keys/offsets, arrays, references, and ArrayAccess objects.
Summary
Follow-up to #70 and the direct-variable fix in
4e13e7b. This preserves PHP??=semantics when an array-dimension target may dispatch throughArrayAccessindirectly or change representation between phases.offsetExists()once andoffsetGet()only for a present offsetArrayAccessdimensionsFailure mechanism and invariant
An
ArrayAccessoffsetGet()result is a value, not a writable bucket. In addition, a key expression,offsetExists(), or the RHS can mutate an aliased key/container. The read phase must use one stabilized receiver/key pair, while the write phase must resolve the current target after the RHS. Missing outer dimensions must not be created before the RHS.The previous lowering handled a plain variable but did not enforce that invariant for nested dimensions, property/magic-property targets, references, or object/array representation changes.
Coverage matrix
ArrayAccess-to-object targetsoffsetExists()and from the RHSNative objects and the features documented as incompatible remain outside this path.
Verification
ArrayAccessCoalesceAssignCodegenTest: 5 tests, 32 assertions