Skip to content
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

Updating an array in foreach is wrongly inferred when strict mode is used. #10922

Closed
VincentLanglet opened this issue Apr 23, 2024 · 10 comments
Closed

Comments

@VincentLanglet
Copy link
Contributor

Bug report

In the following example
https://phpstan.org/r/ec2a3c8e-4b32-443f-81b1-f2ba78836f3e
the array is understood as

Dumped type: array<string, array{foo: string, bar: ''}>

but with strict mode we're getting
https://phpstan.org/r/5a249928-665b-4b87-aff3-9e98b53c7fad

Dumped type: array<string, array{foo: string, bar?: ''}>

we have to update the array to a non-empty-array in order to get the right result
https://phpstan.org/r/0302aab8-0877-413b-9dff-ad41d7a8afcf

Code snippet that reproduces the problem

https://phpstan.org/r/5a249928-665b-4b87-aff3-9e98b53c7fad

Expected output

I expect to get

array<string, array{foo: string, bar: ''}>

even if the array in the foreach is empty.

Because if the array is empty, it's [] and it respect the definition array<string, array{foo: string, bar: ''}>.

This would avoid an error on the following code: https://phpstan.org/r/483aa742-4928-47f0-a0b2-02a07d8a684f

Did PHPStan help you today? Did it make you happy in any way?

No response

@ondrejmirtes
Copy link
Member

This is a well known shortcoming. PHPStan does not understand when a whole array is being overwritten in a foreach.

If you create a new array and assign all the values to it, it's going to understand it well.

@VincentLanglet
Copy link
Contributor Author

This is a well known shortcoming. PHPStan does not understand when a whole array is being overwritten in a foreach.

That was I thought, but then why does PHPStan seems to understand the whole-update when strict mode is not enabled ?
https://phpstan.org/r/ec2a3c8e-4b32-443f-81b1-f2ba78836f3e

If it's possible in non-strict mode, maybe it could in strict mode too (?)

@ondrejmirtes
Copy link
Member

No idea, looks like a bug inside a bug

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Apr 23, 2024

No idea, looks like a bug inside a bug

I'll be curious to take a look, any idea where I should look at in the phpstan-src code for those "array-type-update" ?

Edit: Since it's related to polluteScopeWithAlwaysIterableForeach: true options, it might be in NodeScopeResolver.

@ondrejmirtes
Copy link
Member

Here's the foreach handling: https://github.com/phpstan/phpstan-src/blob/26d72e822ab547c2472b3cc4c3cf19ea7be79f8c/src/Analyser/NodeScopeResolver.php#L985-L1075

It's best to set a breakpoint and look at the result of $scope->debug() to see what's going on.

@VincentLanglet
Copy link
Contributor Author

Here's the foreach handling: phpstan/phpstan-src@26d72e8/src/Analyser/NodeScopeResolver.php#L985-L1075

It's best to set a breakpoint and look at the result of $scope->debug() to see what's going on.

Thanks, I have some ideas I'd like to test but I have difficulties writing a NodeScopeResolver test.

Is there a way to add a test here https://github.com/phpstan/phpstan-src/blob/26d72e822ab547c2472b3cc4c3cf19ea7be79f8c/tests/PHPStan/Analyser/NodeScopeResolverTest.php#L13 but asking for polluteScopeWithAlwaysIterableForeach: false ? Or where should I add my test ?

@ondrejmirtes
Copy link
Member

Create a new class extending TypeInferenceTestCase, creating a config file, reference the config file in getAdditionalConfigFiles

@VincentLanglet
Copy link
Contributor Author

Thanks, I found something phpstan/phpstan-src#3029

@ondrejmirtes
Copy link
Member

Fixed phpstan/phpstan-src#3029

Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants