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

Strict comparison using === on a possibly empty array and [] always evaluates to false #7805

Closed
paulbalandan opened this issue Aug 17, 2022 · 17 comments · Fixed by phpstan/phpstan-src#2111
Labels
Milestone

Comments

@paulbalandan
Copy link

Bug report

PHPStan evaluates [] as array{}, so a possibly empty array compared against it will be reported as false.

Code snippet that reproduces the problem

Strict comparison using === between array and array{} will always evaluate to false.
https://phpstan.org/r/d426c53a-8ada-4f53-a719-3ca296c3459d

If adding a docblock on the possible array shape, a similar error occurs.
Strict comparison using === between array{} and array{} will always evaluate to false.
https://phpstan.org/r/348c3626-bfe6-4f25-9085-3684be966060

Please note that the first error only occurs if treatPhpDocTypesAsCertain is set to false. There are no errors if set to true.
There's a completely different error Else branch is unreachable... for the second scenario, but that is already reported.

Expected output

The code should be valid.

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

Yes, definitely.

@ondrejmirtes ondrejmirtes added this to the Easy fixes milestone Aug 17, 2022
@ondrejmirtes
Copy link
Member

This is super-weird. I can't reproduce it locally with your exact code, and also dumped types look like I'd expect: https://phpstan.org/r/283e2e30-07b8-4811-9dc5-f574237291d3

@paulbalandan
Copy link
Author

Try using level 5. You used max level.

@ondrejmirtes
Copy link
Member

Nope, that's not it.

@pistej
Copy link

pistej commented Sep 2, 2022

another example of array_filter and count https://phpstan.org/r/c94175a1-1278-4f3d-9424-fe069e1bc5ec

@ondrejmirtes
Copy link
Member

@pistej your example isn't realistic, in your case PHPStan knows exactly what's going on.

@pistej
Copy link

pistej commented Sep 2, 2022

sorry my bad, this is maybe better: https://phpstan.org/r/ab0c3d35-e645-449c-b27c-fbc089b784b2

@ondrejmirtes
Copy link
Member

@pistej Please open a separate bug report for this. Looks like a problem in array_filter extension.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-PHP 8.0 – 8.2 (4 errors)
+PHP 8.0 – 8.2 (3 errors)
 ==========
 
 14: Function foo() has no return type specified.
 22: Dumped type: array{Limit, Limit, Limit}
-24: Dumped type: array{Limit, Limit, Limit}
-27: Strict comparison using === between array{Limit, Limit, Limit} and array{} will always evaluate to false.
+24: Dumped type: array{0?: Limit, 1?: Limit, 2?: Limit}
 
-PHP 7.4 (5 errors)
+PHP 7.4 (4 errors)
 ==========
 
  4: Promoted properties are supported only on PHP 8.0 and later.
 14: Function foo() has no return type specified.
 22: Dumped type: array{Limit, Limit, Limit}
-24: Dumped type: array{Limit, Limit, Limit}
-27: Strict comparison using === between array{Limit, Limit, Limit} and array{} will always evaluate to false.
+24: Dumped type: array{0?: Limit, 1?: Limit, 2?: Limit}
 
 PHP 7.1 – 7.3 (3 errors)
 ==========
Full report

PHP 8.0 – 8.2 (3 errors)

Line Error
14 Function foo() has no return type specified.
22 Dumped type: array{Limit, Limit, Limit}
24 Dumped type: array{0?: Limit, 1?: Limit, 2?: Limit}

PHP 7.4 (4 errors)

Line Error
4 Promoted properties are supported only on PHP 8.0 and later.
14 Function foo() has no return type specified.
22 Dumped type: array{Limit, Limit, Limit}
24 Dumped type: array{0?: Limit, 1?: Limit, 2?: Limit}

PHP 7.1 – 7.3 (3 errors)

Line Error
23 Syntax error, unexpected ')' on line 23
23 Syntax error, unexpected T_STRING, expecting T_PAAMAYIM_NEKUDOTAYIM on line 23
23 Syntax error, unexpected T_VARIABLE, expecting ')' on line 23

@phpstan-bot
Copy link
Contributor

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

@@ @@
-8: Strict comparison using === between array and array{} will always evaluate to false.
+8: Strict comparison using === between array<mixed, mixed> and array{} will always evaluate to false.
Full report
Line Error
8 Strict comparison using === between array<mixed, mixed> and array{} will always evaluate to false.

@phpstan-bot
Copy link
Contributor

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

@@ @@
  3: Function foo() has no return type specified.
  3: Function foo() has parameter $params with no value type specified in iterable type array.
  6: Dumped type: array&hasOffset('help')
- 8: Dumped type: array
-10: Strict comparison using === between array and array{} will always evaluate to false.
+ 8: Dumped type: array<mixed~'help', mixed>
+10: Strict comparison using === between array<mixed, mixed> and array{} will always evaluate to false.
Full report
Line Error
3 Function foo() has no return type specified.
3 Function foo() has parameter $params with no value type specified in iterable type array.
6 Dumped type: array&hasOffset('help')
8 Dumped type: array<mixed~'help', mixed>
10 Strict comparison using === between array<mixed, mixed> and array{} will always evaluate to false.

@phpstan-bot
Copy link
Contributor

@paulbalandan After the latest push in 1.9.x, PHPStan now reports different result with your code snippet:

@@ @@
-8: Strict comparison using === between array and array{} will always evaluate to false.
+No errors

@phpstan-bot
Copy link
Contributor

@paulbalandan After the latest push in 1.9.x, PHPStan now reports different result with your code snippet:

@@ @@
-11: Strict comparison using === between array{} and array{} will always evaluate to false.
+11: Else branch is unreachable because ternary operator condition is always true.
Full report
Line Error
11 Else branch is unreachable because ternary operator condition is always true.

@phpstan-bot
Copy link
Contributor

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

@@ @@
  3: Function foo() has no return type specified.
  3: Function foo() has parameter $params with no value type specified in iterable type array.
  6: Dumped type: array&hasOffset('help')
- 8: Dumped type: array
-10: Strict comparison using === between array and array{} will always evaluate to false.
+ 8: Dumped type: array<mixed~'help', mixed>
Full report
Line Error
3 Function foo() has no return type specified.
3 Function foo() has parameter $params with no value type specified in iterable type array.
6 Dumped type: array&hasOffset('help')
8 Dumped type: array<mixed~'help', mixed>

@staabm
Copy link
Contributor

staabm commented Oct 12, 2022

work on a regression test

@ondrejmirtes
Copy link
Member

It's not fixed. We don't want the Else branch is unreachable because ternary operator condition is always true. error either.

@phpstan-bot
Copy link
Contributor

@paulbalandan After the latest push in 1.9.x, PHPStan now reports different result with your code snippet:

@@ @@
-11: Strict comparison using === between array{} and array{} will always evaluate to false.
+No errors

@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 Jan 16, 2023
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.

5 participants