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

Infering array-keys is erroneous #7423

Open
drupol opened this issue Jun 8, 2022 · 4 comments · May be fixed by phpstan/phpstan-src#2058
Open

Infering array-keys is erroneous #7423

drupol opened this issue Jun 8, 2022 · 4 comments · May be fixed by phpstan/phpstan-src#2058
Labels
Milestone

Comments

@drupol
Copy link

drupol commented Jun 8, 2022

Hi,

Recently I've been working on a tool that I was using internally to generate random typed values.
I pushed it online 3 days ago so I can use it everywhere easily, find the tool here: https://github.com/loophp/typed-generators

I noticed an issue while working on the ArrayType and I'm opening this issue to know if this issue is legit.
I reproduced the issue on the PHPStan playground here: https://phpstan.org/r/518a80cb-3a3d-460a-8bc5-e0791d732063
Sorry for the size of the snippet, while writing this issue I'm still looking for a reproducer with smaller amount of code.
I added some comments in the snippet to show you were PHPStan fails to infer the proper type.

IMHO, I think there is a bug somewhere because when changing the type definition from ArrayType<TKey|VKey, T|V> to ArrayType<VKey|TKey, T|V> (line 118), the PHPStan output is different.

The same snippet in PSalm is behaving correctly: https://psalm.dev/r/b48de03f7e

@rvanvelzen
Copy link
Contributor

Using int|string instead of array-key might help here

@phpstan-bot
Copy link
Contributor

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

@@ @@
-PHP 8.0 – 8.1 (1 error)
+PHP 8.0 – 8.1 (4 errors)
 ==========
 
+127: PHPDoc tag @var with type Snippet\ArrayType<TKey of (int|string), T|V> is not subtype of native type $this(Snippet\ArrayType<TKey of (int|string), T>).
+130: PHPDoc tag @var with type list<Snippet\TypeGenerator<TKey of (int|string)>> is not subtype of native type non-empty-list<Snippet\TypeGenerator>.
+134: PHPDoc tag @var with type list<Snippet\TypeGenerator<T|V>> is not subtype of native type non-empty-list<Snippet\TypeGenerator>.
 148: Expected type array<int|string, int|string>, actual: array<string, int|string>
 
-PHP 7.1 – 7.4 (2 errors)
+PHP 7.1 – 7.4 (5 errors)
 ==========
 
 109: Method Snippet\ArrayType::__invoke() should return array<TKey of (int|string), T> but returns array<TKey of (int|string), T>|false.
+127: PHPDoc tag @var with type Snippet\ArrayType<TKey of (int|string), T|V> is not subtype of native type $this(Snippet\ArrayType<TKey of (int|string), T>).
+130: PHPDoc tag @var with type list<Snippet\TypeGenerator<TKey of (int|string)>> is not subtype of native type non-empty-list<Snippet\TypeGenerator>.
+134: PHPDoc tag @var with type list<Snippet\TypeGenerator<T|V>> is not subtype of native type non-empty-list<Snippet\TypeGenerator>.
 148: Expected type array<int|string, int|string>, actual: array<string, int|string>
Full report

PHP 8.0 – 8.1 (4 errors)

Line Error
127 `PHPDoc tag @var with type Snippet\ArrayType<TKey of (int
130 `PHPDoc tag @var with type list<Snippet\TypeGenerator<TKey of (int
134 `PHPDoc tag @var with type list<Snippet\TypeGenerator<T
148 `Expected type array<int

PHP 7.1 – 7.4 (5 errors)

Line Error
109 `Method Snippet\ArrayType::__invoke() should return array<TKey of (int
127 `PHPDoc tag @var with type Snippet\ArrayType<TKey of (int
130 `PHPDoc tag @var with type list<Snippet\TypeGenerator<TKey of (int
134 `PHPDoc tag @var with type list<Snippet\TypeGenerator<T
148 `Expected type array<int

@phpstan-bot
Copy link
Contributor

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

@@ @@
-PHP 8.0 – 8.1 (1 error)
+PHP 8.0 – 8.1 (2 errors)
 ==========
 
+127: PHPDoc tag @var with type Snippet\ArrayType<TKey of (int|string), T|V> is not subtype of native type $this(Snippet\ArrayType<TKey of (int|string), T>).
 148: Expected type array<int|string, int|string>, actual: array<string, int|string>
 
-PHP 7.1 – 7.4 (2 errors)
+PHP 7.1 – 7.4 (3 errors)
 ==========
 
 109: Method Snippet\ArrayType::__invoke() should return array<TKey of (int|string), T> but returns array<TKey of (int|string), T>|false.
+127: PHPDoc tag @var with type Snippet\ArrayType<TKey of (int|string), T|V> is not subtype of native type $this(Snippet\ArrayType<TKey of (int|string), T>).
 148: Expected type array<int|string, int|string>, actual: array<string, int|string>
Full report

PHP 8.0 – 8.1 (2 errors)

Line Error
127 `PHPDoc tag @var with type Snippet\ArrayType<TKey of (int
148 `Expected type array<int

PHP 7.1 – 7.4 (3 errors)

Line Error
109 `Method Snippet\ArrayType::__invoke() should return array<TKey of (int
127 `PHPDoc tag @var with type Snippet\ArrayType<TKey of (int
148 `Expected type array<int

@phpstan-bot
Copy link
Contributor

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

@@ @@
-PHP 8.0 – 8.1 (1 error)
+PHP 8.0 – 8.1 (3 errors)
 ==========
 
+127: PHPDoc tag @var with type Snippet\ArrayType<TKey of (int|string), T|V> is not subtype of native type $this(Snippet\ArrayType<TKey of (int|string), T>).
+134: PHPDoc tag @var with type list<Snippet\TypeGenerator<T|V>> is not subtype of type non-empty-list<Snippet\TypeGenerator<T>|Snippet\TypeGenerator<V>>.
 148: Expected type array<int|string, int|string>, actual: array<string, int|string>
 
-PHP 7.1 – 7.4 (2 errors)
+PHP 7.1 – 7.4 (4 errors)
 ==========
 
 109: Method Snippet\ArrayType::__invoke() should return array<TKey of (int|string), T> but returns array<TKey of (int|string), T>|false.
+127: PHPDoc tag @var with type Snippet\ArrayType<TKey of (int|string), T|V> is not subtype of native type $this(Snippet\ArrayType<TKey of (int|string), T>).
+134: PHPDoc tag @var with type list<Snippet\TypeGenerator<T|V>> is not subtype of type non-empty-list<Snippet\TypeGenerator<T>|Snippet\TypeGenerator<V>>.
 148: Expected type array<int|string, int|string>, actual: array<string, int|string>
Full report

PHP 8.0 – 8.1 (3 errors)

Line Error
127 `PHPDoc tag @var with type Snippet\ArrayType<TKey of (int
134 `PHPDoc tag @var with type list<Snippet\TypeGenerator<T
148 `Expected type array<int

PHP 7.1 – 7.4 (4 errors)

Line Error
109 `Method Snippet\ArrayType::__invoke() should return array<TKey of (int
127 `PHPDoc tag @var with type Snippet\ArrayType<TKey of (int
134 `PHPDoc tag @var with type list<Snippet\TypeGenerator<T
148 `Expected type array<int

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants