Make IntegerRangeType->isSubTypeOf analyse Unions#416
Make IntegerRangeType->isSubTypeOf analyse Unions#416GKFX wants to merge 2 commits intophpstan:masterfrom
Conversation
1fc2d6d to
40ea36d
Compare
There was a problem hiding this comment.
It sounds to me like the correct answer here is 'maybe', since the second type might be a string, in which case an integer is not a sub-type of it.
There was a problem hiding this comment.
I think int<5,10> is a subclass of int|string; certainly float|string is a superclass of both float and string according to the isSuperTypeOf method on the UnionType.
There was a problem hiding this comment.
The message is wrong here (mentions isSuperTypeOf instead of isSubTypeOf)
src/Type/IntegerRangeType.php
Outdated
There was a problem hiding this comment.
(Sorry I messed up the line range selection here... the comment is meant for the entire method unionIntRanges())
Code to pretty much do the exact same thing already exists in TypeCombinator::union(). In fact, a UnionType should probably never even contain mergeable integer ranges (or const ints). This is currently not enforced, but the idea is to use TypeCombinator::union(...) instead of new UnionType([...]) whenever in doubt that there might be overlapping types.
I understand that in your example you end up with a union type 1|2|3|4 which is then tested against int<1,4>. This currently doesn't work properly. I wonder if the cleaner solution wouldn't just be to disallow adjacent integers in unions and enforce the usage of integer ranges (e.g. always int<1,2> instead of 1|2. This ensures that there's only way one to represent the same thing. With this the sub-type check would automatically start to work correctly.
There was a problem hiding this comment.
Same here, although this specific union shouldn't even exist in practice, since the 5 should be merged into int<6, 10>.
|
Looks like this PR will fix these cases: https://phpstan.org/r/93116f33-5437-4d97-b06f-d04949258051 Can you add integration tests to respective rules? Thanks! |
40ea36d to
7b0412a
Compare
|
Based on jlherren's feedback, I started this again to take advantage of the existing functionality in |
bad292c to
835c69d
Compare
|
Hi, there's still too many failing tests. Do you plan to finish this PR? Thanks! |
835c69d to
26e77a7
Compare
Partially resolves phpstan/phpstan#3339
26e77a7 to
ceed528
Compare
ceed528 to
ab4a783
Compare
|
Hi Ondrej, with the approach of converting all |
|
I had time to have a look at this again, here are my thoughts:
I believe this approach would fix the issue in far fewer lines of code (but I might be mistaken of course). |
efd31ce to
0471f87
Compare
|
This is old and stale, feel free to start fresh on top of current master in a new PR. Thanks! |
This commit allows
int<m,n>to be recognised as a subtype of unions likem|m+1|m+2|...|n-1|norint<m,n-1>|n. It also creates a new interfacePHPStan\Type\ImplementsSubTypeOfUnionwhich indicates toUnionType->superTypeOfthat it should callisSubTypeOfon the other object. (Previously there was no need for such an interface as IterableType was the only such type.)This resolves a modified form of phpstan/phpstan#3339: https://phpstan.org/r/00e327fa-55e9-41b8-8b6e-3e8924d9a3d4
It doesn't address the fact that in the original snippet PHPStan thinks
$imight take any value in the range [PHP_INT_MIN,2].