phpstan-src icon indicating copy to clipboard operation
phpstan-src copied to clipboard

Don't loose known offset-types in array_merge()

Open staabm opened this issue 1 month ago • 8 comments

the result of array_merge will always contain all string keys we see along the way. ~~we can't reason about the values when not all arrays are constant, but we can remember the keys.~~ since string keys overwrite each other, we know the value of the last string keys in the chain. of other string based offsets we at least know about their existance.

best reviewed with whitespaces ignored

Followup could be doing the same for

  • the + operator when merging arrays
  • array_replace
  • spread operator

staabm avatar Nov 13 '25 21:11 staabm

This pull request has been marked as ready for review.

phpstan-bot avatar Nov 13 '25 21:11 phpstan-bot

I like this 👍 Before looking at the code I thought I'd solve this with HasOffsetValueType as well.

ondrejmirtes avatar Nov 14 '25 08:11 ondrejmirtes

the result of array_merge will always contain all keys we see along the way.

This is not correct for int keys, as those will be renumbered. (This is the reason array_replace() was added.)

https://3v4l.org/2h5Qn

claudepache avatar Nov 14 '25 09:11 claudepache

@claudepache thanks - I also realized it. Adjusted the PR accordingly, please have another look

staabm avatar Nov 14 '25 09:11 staabm

This pull request has been marked as ready for review.

phpstan-bot avatar Nov 14 '25 14:11 phpstan-bot

Could it solve https://github.com/phpstan/phpstan/issues/13805 ?

VincentLanglet avatar Nov 15 '25 10:11 VincentLanglet

Could it solve phpstan/phpstan#13805 ?

there is no array_merge call in this issue. but I think we might be able to apply a similar logic for this case. there are even more use-cases see the PR description (just added spread operator to the list).

staabm avatar Nov 15 '25 10:11 staabm

Looking at this I think we should add Type->getOffsetTypes() which returns a array of all known offsets of a type (const-ints/string), no matter its known by keys (const array), or by additional accessories.

This would ease building logic on top of it without the need for checking individual type classes

staabm avatar Dec 07 '25 10:12 staabm