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

Incorrect expected return type with union type and generic #6438

Closed
tjveldhuizen opened this issue Jan 22, 2022 · 4 comments · Fixed by phpstan/phpstan-src#994
Closed

Incorrect expected return type with union type and generic #6438

tjveldhuizen opened this issue Jan 22, 2022 · 4 comments · Fixed by phpstan/phpstan-src#994
Labels
Milestone

Comments

@tjveldhuizen
Copy link

Bug report

When I use this combination of generics and union types, PHPStan reports an error falsely.

Code snippet that reproduces the problem

https://phpstan.org/r/a630ff19-a6d5-4b16-b677-1c543bce7310

Expected output

No error expected

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

PHPStan absolutely helps us to have more trust in changes to our legacy codebase, which still needs a lot of tests.

@ondrejmirtes ondrejmirtes added this to the Generics milestone Jan 22, 2022
@arnaud-lb
Copy link
Contributor

Shorter snippet: https://phpstan.org/r/73ff0bed-e705-4c3f-9f5d-18f03f934fb7

Appears to be caused by https://github.com/phpstan/phpstan-src/blob/f8c1bef517be0777cc2897b893bfcae97cbd254e/src/Type/TypeCombinator.php#L79-L81

The problem is that the TemplateBooleanType gets replaced by a BooleanType here because TemplateBooleanType is an instance of BooleanType.

One solution could be to move the implementation of TypeCombinator::remove() to Type, so that template types could implement their own logic. WDYT @ondrejmirtes ?

@ondrejmirtes
Copy link
Member

Yeah, moving things to the Type interface always cleans stuff up, I'm for it :)

@phpstan-bot
Copy link
Contributor

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

@@ @@
-PHP 8.0 – 8.1 (1 error)
+PHP 8.0 – 8.1 (2 errors)
 ==========
 
+10: PHPDoc tag @param for parameter $value with type T of bool|int is not subtype of native type bool|int.
 16: Method HelloWorld::getValueDescription() should return array{value: T of bool|int, description: string}|null but returns array{value: int|true, description: string}.
 
-PHP 7.1 – 7.4 (2 errors)
+PHP 7.1 – 7.4 (3 errors)
 ==========
 
 10: Method HelloWorld::getValueDescription() uses native union types but they're supported only on PHP 8.0 and later.
+10: PHPDoc tag @param for parameter $value with type T of bool|int is not subtype of native type bool|int.
 16: Method HelloWorld::getValueDescription() should return array{value: T of bool|int, description: string}|null but returns array{value: int|true, description: string}.
Full report

PHP 8.0 – 8.1 (2 errors)

Line Error
10 `PHPDoc tag @param for parameter $value with type T of bool
16 `Method HelloWorld::getValueDescription() should return array{value: T of bool

PHP 7.1 – 7.4 (3 errors)

Line Error
10 Method HelloWorld::getValueDescription() uses native union types but they're supported only on PHP 8.0 and later.
10 `PHPDoc tag @param for parameter $value with type T of bool
16 `Method HelloWorld::getValueDescription() should return array{value: T of bool

@github-actions
Copy link

github-actions bot commented Mar 8, 2022

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 Mar 8, 2022
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.

4 participants