Rework ArrayReplaceFunctionReturnTypeExtension#3958
Rework ArrayReplaceFunctionReturnTypeExtension#3958ondrejmirtes merged 2 commits intophpstan:1.12.xfrom
Conversation
293ea40 to
2e5bfcf
Compare
|
This pull request has been marked as ready for review. |
|
I know I'm maybe a bit fast suggesting this, but we could create a |
Yeah, I would prefer this to be done in a follow up PR to separate (and validate separately by ondrej)
|
5dea1cc to
a8f870a
Compare
|
/cc @herndlm Waiting for LGTM from you here :) |
|
I guess this is fine. And also brings value of course. Let's see if we can refactor array_merge and array_replace stuff a bit as follow-up I'd say :) |
| /** @var array<int|string, ConstantIntegerType|ConstantStringType> $keyTypes */ | ||
| $keyTypes = []; | ||
| foreach ($argType->getConstantArrays() as $constantArray) { | ||
| foreach ($constantArray->getKeyTypes() as $keyType) { |
There was a problem hiding this comment.
I don't think this is what you want. Let's say you have array{foo: int}|array{bar: string}.
You'll end up with two values in $keyTypes and you'll create a flat array out of them. Also you'll overwrite a value if two or more arrays in a union share the same key but with different type.
There was a problem hiding this comment.
I'm not sure to understand your point.
This is the current behavior we have with array_replace vs array_merge
https://phpstan.org/r/4ec3a6a9-2645-4565-a81e-577b518eb7c3
Since both function are working almost the same way, I copied and adapt the logic from ArrayMergeFunctionReturnTypeExtension
In which we're doing
foreach ($argType->getConstantArrays() as $constantArray) {
foreach ($constantArray->getKeyTypes() as $keyType) {
With this PR, we're now getting
array{bar?: int, foo: 'thing'}
with both array_merge and array_replace
|
Thank you. |
Close phpstan/phpstan#12828
I basically copy the ArrayMergeFunctionReturnTypeExtension with the following change
phpstan-src/src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php
Line 87 in 4c41073
$keyType instanceof ConstantIntegerType ? null : $keyType,is replaced by$keyTypebecausephpstan-src/src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php
Line 106 in 4c41073
if (!(new IntegerType())->isSuperTypeOf($keyType)->yes()) {is replaced byif (!$argType->isList()->yes()) {because of the same reason.