phpstan icon indicating copy to clipboard operation
phpstan copied to clipboard

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

Open paulbalandan opened this issue 3 years ago • 8 comments
trafficstars

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.

paulbalandan avatar Aug 17 '22 05:08 paulbalandan

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

ondrejmirtes avatar Aug 17 '22 12:08 ondrejmirtes

Try using level 5. You used max level.

paulbalandan avatar Aug 17 '22 12:08 paulbalandan

Nope, that's not it.

ondrejmirtes avatar Aug 17 '22 12:08 ondrejmirtes

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

pistej avatar Sep 02 '22 08:09 pistej

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

ondrejmirtes avatar Sep 02 '22 08:09 ondrejmirtes

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

pistej avatar Sep 02 '22 09:09 pistej

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

ondrejmirtes avatar Sep 02 '22 16:09 ondrejmirtes

@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 avatar Sep 03 '22 12:09 phpstan-bot

@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 avatar Sep 26 '22 09:09 phpstan-bot

@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 avatar Sep 26 '22 09:09 phpstan-bot

@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 avatar Oct 12 '22 08:10 phpstan-bot

@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 avatar Oct 12 '22 08:10 phpstan-bot

@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>

phpstan-bot avatar Oct 12 '22 08:10 phpstan-bot

work on a regression test

staabm avatar Oct 12 '22 08:10 staabm

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

ondrejmirtes avatar Oct 12 '22 08:10 ondrejmirtes

@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

phpstan-bot avatar Dec 14 '22 05:12 phpstan-bot

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[bot] avatar Jan 16 '23 00:01 github-actions[bot]