phpstan
phpstan copied to clipboard
Strict comparison using `===` on a possibly empty array and `[]` always evaluates to false
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.
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
Try using level 5. You used max level.
Nope, that's not it.
another example of array_filter and count https://phpstan.org/r/c94175a1-1278-4f3d-9424-fe069e1bc5ec
@pistej your example isn't realistic, in your case PHPStan knows exactly what's going on.
sorry my bad, this is maybe better: https://phpstan.org/r/ab0c3d35-e645-449c-b27c-fbc089b784b2
@pistej Please open a separate bug report for this. Looks like a problem in array_filter extension.
@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 |
@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. |
@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. |
@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
@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. |
@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> |
work on a regression test
It's not fixed. We don't want the Else branch is unreachable because ternary operator condition is always true. error either.
@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
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.