New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Array shape mangled when union with empty array is created? #10834
Comments
Hmm, right. The title is even more correct than I tested. If I change the |
The array gets simplified if it's too big, for performance reasons. So in these situations the precision of being an array shape might get lost. |
That's what I expected already. Thinking out loud, might it be an idea to add special handling for an empty array (so just |
Yeah, of course it can be improved. The logic happens in |
👍🏻 , already found those based on searching in And to add to the "it's 'just' mangled". This obviously leads to errors later on where undefined array keys are being reported on this mangled type. While, just tested, it works fine when for example using |
Fixed phpstan/phpstan-src#3003 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Bug report
I have a method which returns a very big array shape (
array{....}
). But when I use this shape in a ternary / null coalesce operation with a "fallback" to[]
the type get's manged. In this case the shape is lost and it's converted into a generic array where the key type some of the keys but as a union, and after a certain amount (seems to be 64 and above) the keys are just "lost" (not added to the union), and the same happens to the value types, these are combined into a union as well, and new / unique types after the first 64 seem to be lost.So see the linked example. Line 12 correctly dumps the array shape (
array{1: string, ..., 64: float}|null
), while when combining it with a?? []
(on line 13) it's converted intoarray<1|2|3|...|63, bool|int|string>
(notice thatfloat
is only used as type for key64
, and is not part of the converted generic either). And the same happens when using a normal ternary (truty ? shape() : []
).Also not that dropping a single array key isn't enough (while it would limit the size to 63, which is the number of items in the array key union), and at least 2 keys need to be dropped.
While the code is (very) badly designed I would still like to report this and see if this is something which maybe can be fixed (but it might as well be an artificial limit as these big shapes might hurt performance?)
Code snippet that reproduces the problem
https://phpstan.org/r/8b1640c3-2c07-4c7a-85fc-c143048ef03d
Expected output
Line 13 should log:
(which is the same as line 12, except
|null
now beingarray{}
)And line 15 should be
array{}|array{1: ...}|null
Did PHPStan help you today? Did it make you happy in any way?
PHPStan is helping me a lot with refactoring and adding type hints to a very old code base. Generate baseline, refactor, run again, and if there are no (new) errors I'm pretty sure I didn't break anything 😄.
The text was updated successfully, but these errors were encountered: