-
Notifications
You must be signed in to change notification settings - Fork 509
Fix NumericString to array key #3326
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
Fix NumericString to array key #3326
Conversation
e170a71
to
c42d877
Compare
@@ -233,10 +233,7 @@ public function testBug4671(): void | |||
{ | |||
$this->treatPhpDocTypesAsCertain = true; | |||
$this->strictUnnecessaryNullsafePropertyFetch = false; | |||
$this->analyse([__DIR__ . '/data/bug-4671.php'], [[ | |||
'Offset numeric-string on array<string, string> in isset() does not exist.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was wrong
41feb8b
to
3ed0134
Compare
if ($offsetType instanceof UnionType) { | ||
$results = []; | ||
foreach ($offsetType->getTypes() as $innerType) { | ||
$results[] = $this->hasOffsetValueType($innerType); | ||
$results[] = $this->recursiveHasOffsetValueType($innerType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the previous logic, toArrayKey was again called, creating a new UnionType for numeric string and an infinite loop.
This pull request has been marked as ready for review. |
This pull request has been marked as ready for review. |
Hey, this area is really tricky. This isn't the right fix, I'd tackle this completely differently. Your change would break too many scenarios. My idea is: Introduce We can't fix |
I'll give these changes a bit more thought, stay tuned and thanks, I appreciate it 😊 |
I agree
Which one ? Looking at tests and issues, it seems to only solve issues without breaking tests. I was worried too that it would open a rabbit hole, but according to the CI it seems not. I agree it would be the case if I wanted to change the behavior for
I definitely agree on this Currently string->toArrayKey is considered as string but numeric-string->toArrayKey is considered as int.
That especially because numeric-string can include float string that the arrayKey shouldn't be considered as only int. Imho, 'numeric-string' should be considered as
Sure, I'm not in hurry. |
01b2d1a
to
4d7af2a
Compare
2957e0a
to
205d0c3
Compare
Hi, I rebased the branch and really would like to move forward this PR if possible @ondrejmirtes. Can we talk again about it ? I do agree that one day we will need So NumericString->toArrayKey should be Int|Numeric-string, and not just Int. At first sight, with all the existing non-regression tests, this change seems to fix a lot of existing issues without introducing a regresion. |
205d0c3
to
27a9b38
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm willing to try this again and see what the impact is on real-world projects.
src/Type/IntersectionType.php
Outdated
@@ -1029,7 +1029,10 @@ public function toArray(): Type | |||
public function toArrayKey(): Type | |||
{ | |||
if ($this->isNumericString()->yes()) { | |||
return new IntegerType(); | |||
return new UnionType([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be TypeCombinator::union()
instead of new UnionType
to ensure type normalization.
Thank you. |
You're welcome, please feel free to ping me after your tests if you need extra work on this and I can help. |
This is causing infinite recursion on one of the test projects. I'm investigating details. |
I had one infinite loop with PHPStan codebase/tests which I fixed this way https://github.com/phpstan/phpstan-src/pull/3326/files#r1718409129 if it can help for the other one you found. |
I'm sorry, it wasn't fault of this PR but a different one. |
Closes phpstan/phpstan#4163
Fixes phpstan/phpstan#4671 (already closed with wrong result)
Closes phpstan/phpstan#8592
Closes phpstan/phpstan#11390
Closes phpstan/phpstan#12413