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

Incorrect variable may not be defined warning #806

Closed
jbafford opened this issue Jan 29, 2018 · 4 comments
Closed

Incorrect variable may not be defined warning #806

jbafford opened this issue Jan 29, 2018 · 4 comments

Comments

@jbafford
Copy link
Contributor

Summary of a problem or a feature request

phpstan incorrectly reports that a variable might not be defined. Specifically, the value target of a foreach is reported as might not be defined after the loop, even when there is sufficient information to show that the loop must have iterated at least once for the code to be reached.

Code snippet that reproduces the problem

  1. https://phpstan.org/r/6762e042fa172646410eca60449b7354
  2. https://phpstan.org/r/5735aae73a39f48bd76c3a75e5bbf127
  3. https://phpstan.org/r/3b98070636c0974658810607a3dfec06
  4. https://phpstan.org/r/d2ccf447a0b83e8280a7a28e81855c4b

Expected output

There should be no error reported. This error is new in phpstan 0.9.2. It did not appear in 0.9.1.

In all four cases, phpstan reports incorrectly that the value variable of a foreach may not be defined after the loop, even though it must be if the code is reached.

In case 1, the value is always defined, because a non-empty array will always result in the foreach value variable being set. In case 2, the array is explicitly checked for non-empty status, but the error is still displayed. (The error is still displayed if the if($arr) test is moved to cover both the foreach and the reference to is variable.)

Cases 3 and 4 are slightly more complicated, because there is a proxy used to determine if the array was empty. In 3, a variable is incremented in each loop iteration, and if non-zero, would indicate the presence of the variable. Case 4 (which most closely resembles my actual code), uses a !== test between two initially null variables, one of which is used as a loop counter, and the other which (in production code) may be changed to obtain the value of the loop counter at some point. In any case, given the initial values of the variables, the test only succeeds if there has been at least one loop iteration, which means the value variable must be present.

I'm uncertain if this is one issue, or multiple issues; if multiple, I can split this issue up as necessary.

@ondrejmirtes
Copy link
Member

Hi, thanks for the report! The thing that got fixed in 0.9.2 is:

https://phpstan.org/r/5faa326a7fcea698ee5e7b695beb6a7d

	public function sayHello(array $arr): void
	{
		foreach ($arr as $i) {
		}
		var_dump($i);
	}

No error is reported on that 0.9.1, hiding potential bugs.

All your examples have in common the fact that there's no logic in PHPStan's engine that would tell "this loop ran at least once, the variable must exist then!". That never worked and will be an objective of some future release.

I'd recommend you to wrap accessing the variable with an if (isset($i)), PHPStan will understand that. Anything indirect like count won't work in the current version.

Let's leave this issue open - it contains useful examples that will serve as test cases once this logic will be implemented.

@ondrejmirtes
Copy link
Member

The first example is solved with 5716b2e, the second one inspired me to do at least this d0bcfa1, but the other ones are not feasible without a feature called Dependent types.

@ondrejmirtes
Copy link
Member

Second example is now solved: phpstan/phpstan-src@4f71570

I don't feel like examples involving $cnt are very valuable, so I'm gonna skip those.

@github-actions
Copy link

github-actions bot commented May 4, 2021

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 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants