Repository navigation
Conversation
The result of ASSIGN_OBJ_OP and ASSIGN_STATIC_PROP_OP is coerced to the property type, but only DOUBLE->LONG and LONG/DOUBLE->STRING coercions were modelled. Other coercions resulted in an empty or too narrow type. When the property is unknown, BOOL and DOUBLE were also missing. Inferred result type of `$o->p OP= $v` in weak mode: property | value | old | new | runtime -----------+--------+------------+--------------+------------------------------ int | float | long | long | int ?int | float | long | long | int int|float | float | double | double | float int|false | float | long | long | int string | int | string | string | string string|bool| int | string | string | string bool | int | (empty) | bool | bool float | int | (empty) | double | float float|bool | string | (empty) | double|bool | float, bool if non-numeric int|string | float | long | long|string | int, string for INF/NAN int|bool | float | long | long|bool | int, bool for INF/NAN (unknown) | any | +long|str | +scalar | any scalar In strict mode, only int -> float coercion remains, e.g. a float property with an int value infers double, and an unknown property only adds double to the value type.
arnaud-lb
reviewed
Oct 9, 2026
Comment on lines
+2575
to
+2576
| /* The result of a compound assignment to a property must satisfy the property type. | ||
| * A value that doesn't may be coerced to one of the scalar types of the property. */ |
Member
There was a problem hiding this comment.
Pre-existing, but this is not true for unset properties with a __get:
class B {
public bool $b = false;
function __construct() { unset($this->b); }
function __get($n) { return 100; }
}
function f(B $o) { $r = ($o->b += 1); return [is_bool($r), $r]; }
var_dump(f(new B));
// opcache off: [false, int(2)] opcache on: [true, int(2)]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The result of ASSIGN_OBJ_OP and ASSIGN_STATIC_PROP_OP is coerced to the property type, but only DOUBLE->LONG and LONG/DOUBLE->STRING coercions were modelled. Other coercions resulted in an empty or too narrow type. When the property is unknown, BOOL and DOUBLE were also missing.
Inferred result type of
$o->p OP= $vin weak mode:intlonglong?intlonglongint|floatdoubledoubleint|falselonglongstringstringstringstring|boolstringstringboolboolfloatdoublefloat|booldouble|boolint|stringlonglong|stringint|boollonglong|bool+long|string+scalarIn strict mode, only int -> float coercion remains, e.g. a float property with an int value infers double, and an unknown property only adds double to the value type.