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

False positive: Parameter x of function y expects z, *NEVER* given #5474

Closed
driskell opened this issue Aug 17, 2021 · 11 comments · Fixed by phpstan/phpstan-src#1504
Closed
Labels
Milestone

Comments

@driskell
Copy link

driskell commented Aug 17, 2021

Bug report

When you perform an equality check between arrays, it turns the data types of the arrays to "NEVER" if they are identical, within the scope of the conditional. This seems strange as I'd expect unreachable code errors but either way it works. (So line 22 should report an error rather than the NEVER on line 23)

However, if you don't use literals and compare against a RETURNED array that has a shape, it cannot know if it will at runtime be different or not. But it still turns into NEVER. The exact same comparison but without one side being wrapped in a function works fine.

In summary: The error on line 31 should not be there. The error on line 23 is confusing and it should be an impossible message on 22.

No issue with non-identity comparison "!=".

Code snippet that reproduces the problem

https://phpstan.org/r/93c01ef0-94da-41cb-818b-e9628ba65649

Expected output

No errors.

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

It helped me today, yesterday, the day before, and I've happily worked around this for now using != instead of !== so you can resolve in your own time 👍

@ondrejmirtes
Copy link
Member

Hi, thank you for your kind words!

Personally I'd expect the error on line 31 to disappear (https://phpstan.org/r/7edf1fe5-c2af-4a49-a156-430ff3b74e66), all the others are expected. Aditionally line 22 should report an error (it's always false).

@ondrejmirtes ondrejmirtes added this to the Easy fixes milestone Aug 17, 2021
@driskell
Copy link
Author

@ondrejmirtes Yes absolutely. I will update my description. I had that other error in there just to demonstrate but perhaps it wasn't necessary.

@phpstan-bot
Copy link
Contributor

@driskell After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
+18: Function returnData3() should return array<string, int> but return statement is missing.
 23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
 31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
Full report
Line Error
18 Function returnData3() should return array<string, int> but return statement is missing.
23 Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
31 Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.

@phpstan-bot
Copy link
Contributor

@ondrejmirtes After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
+18: Function returnData3() should return array<string, int> but return statement is missing.
 23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
 26: Strict comparison using !== between array('test' => 1) and array('test' => 5) will always evaluate to true.
 31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
Full report
Line Error
18 Function returnData3() should return array<string, int> but return statement is missing.
23 Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
26 Strict comparison using !== between array('test' => 1) and array('test' => 5) will always evaluate to true.
31 Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.

@phpstan-bot
Copy link
Contributor

@driskell After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
-31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
+23: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
+31: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
Full report
Line Error
23 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
31 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.

@phpstan-bot
Copy link
Contributor

@ondrejmirtes After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
-26: Strict comparison using !== between array('test' => 1) and array('test' => 5) will always evaluate to true.
-31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
+23: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
+26: Strict comparison using !== between array{test: 1} and array{test: 5} will always evaluate to true.
+31: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
Full report
Line Error
23 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
26 Strict comparison using !== between array{test: 1} and array{test: 5} will always evaluate to true.
31 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.

@phpstan-bot
Copy link
Contributor

@driskell After the latest commit in 1.6.x, PHPStan now reports different result with your code snippet:

@@ @@
-23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
-31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
+22: Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
+23: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
+31: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
Full report
Line Error
22 Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
23 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
31 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.

@phpstan-bot
Copy link
Contributor

@ondrejmirtes After the latest commit in 1.6.x, PHPStan now reports different result with your code snippet:

@@ @@
-23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
-26: Strict comparison using !== between array('test' => 1) and array('test' => 5) will always evaluate to true.
-31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
+22: Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
+23: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
+26: Strict comparison using !== between array{test: 1} and array{test: 5} will always evaluate to true.
+31: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
Full report
Line Error
22 Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
23 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
26 Strict comparison using !== between array{test: 1} and array{test: 5} will always evaluate to true.
31 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.

@phpstan-bot
Copy link
Contributor

@driskell After the latest commit in 1.8.x, PHPStan now reports different result with your code snippet:

@@ @@
-23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
-31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
+22: Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
+23: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
Full report
Line Error
22 Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
23 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.

@phpstan-bot
Copy link
Contributor

@ondrejmirtes After the latest commit in 1.8.x, PHPStan now reports different result with your code snippet:

@@ @@
-23: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
-26: Strict comparison using !== between array('test' => 1) and array('test' => 5) will always evaluate to true.
-31: Parameter #1 $data of function testData expects array('test' => int), *NEVER* given.
+22: Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
+23: Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
+26: Strict comparison using !== between array{test: 1} and array{test: 5} will always evaluate to true.
Full report
Line Error
22 Strict comparison using !== between array{test: 1} and array{test: 1} will always evaluate to false.
23 Parameter #1 $data of function testData expects array{test: int}, *NEVER* given.
26 Strict comparison using !== between array{test: 1} and array{test: 5} will always evaluate to true.

@github-actions
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 Aug 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants