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

Checks on array keys arent added to the type information #2911

Closed
BackEndTea opened this issue Jan 27, 2020 · 26 comments
Closed

Checks on array keys arent added to the type information #2911

BackEndTea opened this issue Jan 27, 2020 · 26 comments
Labels
Milestone

Comments

@BackEndTea
Copy link
Contributor

Bug report

Code snippet that reproduces the problem

https://phpstan.org/r/db3495e0-2cc4-4acb-ba04-ce742258680a

A smaller variant of the original snippet:
https://phpstan.org/r/e2636992-cccb-46db-9f06-56a4e34c0855

Output:

+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Line | test.php                                                                                                                                           |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| 64   | Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>. |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+

Expected output

I would expect no issue, as within the method i make sure the two keys are the correct value.

The array merge makes sure the keys exist are there. Since it is a const the keys are (should) be known to phpstan. The rest of the method asserts they are correct.

I would've expected phpstan to add the new information of the shape of the array to the type system.

@BackEndTea BackEndTea changed the title Array keys arent made more specific Checks on array keys arent added to the type information Jan 27, 2020
@ondrejmirtes ondrejmirtes added this to the Easy fixes milestone Jan 27, 2020
@ondrejmirtes
Copy link
Member

You could rewrite the logic so that it's more apparent to PHPStan what's going on. Something like:

// ... create $removeValue and $limitValue however you want...

return [
    'remove' => $removeValue,
    'limit' => $limitValue,
];

@BackEndTea
Copy link
Contributor Author

Didn't think of just rewriting the method 😅. Shouldn't be too hard in this case.

@bbatsche
Copy link

bbatsche commented Mar 5, 2020

I'm running into a similar issue when using array_replace() to apply user customization on top of default values from a class: https://phpstan.org/r/9f70fe22-c99a-4b12-8a7b-6dec25a26c6d

@eigan
Copy link

eigan commented Jul 22, 2020

Another simplified example spotted today: https://phpstan.org/r/74d26602-a918-47a3-8aba-1db613ddeeef

@phpstan-bot
Copy link
Contributor

@BackEndTea PHPStan now reports different result with your code snippet:

@@ @@
-64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit is never read, only written.
+64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
Full report
Line Error
25 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
30 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
64 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.

@phpstan-bot
Copy link
Contributor

@BackEndTea PHPStan now reports different result with your code snippet:

@@ @@
+17: Method ArrayItemRemoval::getResultSettings() is unused.
 28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
Full report
Line Error
17 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
28 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.

@phpstan-bot
Copy link
Contributor

@eigan PHPStan now reports different result with your code snippet:

@@ @@
-10: Parameter #1 $array of function bar expects array('bar' => string), array given.
+10: Parameter #1 $array of function bar expects array('bar' => string), array&nonEmpty given.
Full report
Line Error
10 Parameter #1 $array of function bar expects array('bar' => string), array&nonEmpty given.

@phpstan-bot
Copy link
Contributor

@BackEndTea PHPStan now reports different result with your code snippet:

@@ @@
-64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+PHP 8.0 (3 errors)
+==========
+
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit is never read, only written.
+64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
+
+PHP 7.1 – 7.4 (8 errors)
+==========
+
+ 9: Method MutatorConfig::getMutatorSettings() return type has no value type specified in iterable type array.
+25: Property ArrayItemRemoval::$remove has no typehint specified.
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit has no typehint specified.
+30: Property ArrayItemRemoval::$limit is never read, only written.
+45: Method ArrayItemRemoval::getResultSettings() has parameter $settings with no value type specified in iterable type array.
+45: Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.
+70: Method ArrayItemRemoval::configException() has parameter $settings with no value type specified in iterable type array.
Full report

PHP 8.0 (3 errors)

Line Error
25 Method ArrayItemRemoval::configException() has parameter $settings with no value type specified in iterable type array.
30 Method ArrayItemRemoval::configException() has parameter $settings with no value type specified in iterable type array.
64 Method ArrayItemRemoval::configException() has parameter $settings with no value type specified in iterable type array.

PHP 7.1 – 7.4 (8 errors)

Line Error
9 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
25 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
25 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
30 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
30 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
45 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
45 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
70 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.

@phpstan-bot
Copy link
Contributor

@BackEndTea PHPStan now reports different result with your code snippet:

@@ @@
-28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+PHP 8.0 (3 errors)
+==========
+
+17: Method ArrayItemRemoval::getResultSettings() has parameter $settings with no value type specified in iterable type array.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
+17: Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.
+
+PHP 7.4 (2 errors)
+==========
+
+17: Method ArrayItemRemoval::getResultSettings() is unused.
+28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+
+PHP 7.1 – 7.3 (3 errors)
+==========
+
+17: Method ArrayItemRemoval::getResultSettings() has parameter $settings with no value type specified in iterable type array.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
+17: Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.
Full report

PHP 8.0 (3 errors)

Line Error
17 Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.
17 Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.
17 Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.

PHP 7.4 (2 errors)

Line Error
17 Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.
28 Method ArrayItemRemoval::getResultSettings() return type has no value type specified in iterable type array.

PHP 7.1 – 7.3 (3 errors)

Line Error
17 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
17 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
17 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
+28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.
Full report
Line Error
17 Method ArrayItemRemoval::getResultSettings() is unused.
28 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>&nonEmpty.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-19: Method ConfigWrapper::toArray() should return array('foo' => string, 'fizz' => string) but returns array.
+No errors

@phpstan-bot
Copy link
Contributor

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

@@ @@
-19: Method ConfigWrapper::toArray() should return array('foo' => string, 'fizz' => string) but returns array.
+-1: Internal error: PHPStan\Rules\Methods\WrongCaseOfInheritedMethodRule::findMethod(): Argument #2 ($classReflection) must be of type PHPStan\Reflection\ClassReflection, null given, called in /var/task/vendor/phpstan/phpstan-strict-rules/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php on line 40
+Run PHPStan with --debug option and post the stack trace to:
+https://github.com/phpstan/phpstan/issues/new?template=Bug_report.md
Full report
Line Error
-1 Internal error: PHPStan\Rules\Methods\WrongCaseOfInheritedMethodRule::findMethod(): Argument #2 ($classReflection) must be of type PHPStan\Reflection\ClassReflection, null given, called in /var/task/vendor/phpstan/phpstan-strict-rules/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php on line 40Run PHPStan with --debug option and post the stack trace to:https://github.com/phpstan/phpstan/issues/new?template=Bug_report.md

@phpstan-bot
Copy link
Contributor

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

@@ @@
-64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit is never read, only written.
+64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns non-empty-array<string, mixed>.
Full report
Line Error
25 Property ArrayItemRemoval::$remove is never read, only written.
30 Property ArrayItemRemoval::$limit is never read, only written.
64 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns non-empty-array<string, mixed>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
+28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns non-empty-array<string, mixed>.
Full report
Line Error
17 Method ArrayItemRemoval::getResultSettings() is unused.
28 Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns non-empty-array<string, mixed>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-10: Parameter #1 $array of function bar expects array('bar' => string), array given.
+10: Parameter #1 $array of function bar expects array('bar' => string), non-empty-array given.
Full report
Line Error
10 Parameter #1 $array of function bar expects array('bar' => string), non-empty-array given.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit is never read, only written.
+64: Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.
Full report
Line Error
25 Property ArrayItemRemoval::$remove is never read, only written.
30 Property ArrayItemRemoval::$limit is never read, only written.
64 Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
+28: Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.
Full report
Line Error
17 Method ArrayItemRemoval::getResultSettings() is unused.
28 Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-19: Method ConfigWrapper::toArray() should return array('foo' => string, 'fizz' => string) but returns array.
+19: Method ConfigWrapper::toArray() should return array{foo: string, fizz: string} but returns array.
Full report
Line Error
19 Method ConfigWrapper::toArray() should return array{foo: string, fizz: string} but returns array.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-10: Parameter #1 $array of function bar expects array('bar' => string), array given.
+10: Parameter #1 $array of function bar expects array{bar: string}, non-empty-array given.
Full report
Line Error
10 Parameter #1 $array of function bar expects array{bar: string}, non-empty-array given.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+64: Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit is never read, only written.
Full report
Line Error
64 Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.
25 Property ArrayItemRemoval::$remove is never read, only written.
30 Property ArrayItemRemoval::$limit is never read, only written.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+28: Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
Full report
Line Error
28 Method ArrayItemRemoval::getResultSettings() should return array{remove: string, limit: int} but returns non-empty-array<string, mixed>.
17 Method ArrayItemRemoval::getResultSettings() is unused.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-19: Method ConfigWrapper::toArray() should return array('foo' => string, 'fizz' => string) but returns array.
+19: Method ConfigWrapper::toArray() should return array{foo: string, fizz: string} but returns non-empty-array<'fizz'|'foo', string>.
Full report
Line Error
19 `Method ConfigWrapper::toArray() should return array{foo: string, fizz: string} but returns non-empty-array<'fizz'

@phpstan-bot
Copy link
Contributor

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

@@ @@
-64: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+25: Property ArrayItemRemoval::$remove is never read, only written.
+30: Property ArrayItemRemoval::$limit is never read, only written.
Full report
Line Error
25 Property ArrayItemRemoval::$remove is never read, only written.
30 Property ArrayItemRemoval::$limit is never read, only written.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-28: Method ArrayItemRemoval::getResultSettings() should return array('remove' => string, 'limit' => int) but returns array<string, mixed>.
+17: Method ArrayItemRemoval::getResultSettings() is unused.
Full report
Line Error
17 Method ArrayItemRemoval::getResultSettings() is unused.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-10: Parameter #1 $array of function bar expects array('bar' => string), array given.
+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 Aug 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants