phpstan
phpstan copied to clipboard
Narrowing a type by extending loses information of parent
Bug report
When a method has a return type, which gets narrowed in the child class, any information from the parent seems to be lost.
I think that this could be solved by making a child return type an intersection between its return type and that of the parent?
Code snippet that reproduces the problem
https://phpstan.org/r/9d725389-4e11-4b53-aa3f-df765c811e21
Expected output
I'd expect the dumped types to be array<string> for the Fail class, and array<string>|(callable(): array<string>) for the Good class (which already works).
And there should be no error for Fail::check.
Did PHPStan help you today? Did it make you happy in any way?
No response
I think you should use generics: https://phpstan.org/r/c3562717-43a9-4f1c-ad23-416386d1afe2
At that point i could also just add the @return array<string> myself. That also works, but seems unnecessary when all i'm doing is narrowing the type.
Right now you need to repeat the @return. It's a known issue and already is present here on GitHub.
@ondrejmirtes Could you link me to the issue? I can't seem to find it. I'd love to take a stab at this if i can, and that might be easier with more context from the other issue.
I'll be damned, can't find it either. Alright, this one will be the canonical one :)
@staabm After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:
@@ @@
29: Dumped type: array
30: Dumped type: array|(callable(): mixed)
-PHP 7.2 – 7.4 (3 errors)
+PHP 7.4 (7 errors)
==========
+ 9: Method Base::check() has invalid return type mixed.
+ 9: PHPDoc tag @return with type T is not subtype of native type mixed.
+15: Return type array of method Fail::check() is not covariant with return type mixed|null of method Base<array>::check().
24: Method Good::check() uses native union types but they're supported only on PHP 8.0 and later.
+24: Return type array|(callable) of method Good::check() is not covariant with return type mixed|null of method Base<array|(callable)>::check().
+29: Dumped type: array
+30: Dumped type: array|(callable(): mixed)
+
+PHP 7.2 – 7.3 (7 errors)
+==========
+
+ 9: Method Base::check() has invalid return type mixed.
+ 9: PHPDoc tag @return with type T is not subtype of native type mixed.
+15: Return type array of method Fail::check() is not compatible with return type mixed|null of method Base<array>::check().
+24: Method Good::check() uses native union types but they're supported only on PHP 8.0 and later.
+24: Return type array|(callable) of method Good::check() is not compatible with return type mixed|null of method Base<array|(callable)>::check().
29: Dumped type: array
30: Dumped type: array|(callable(): mixed)
Full report
PHP 8.0 – 8.3 (2 errors)
| Line | Error |
|---|---|
| 29 | Dumped type: array |
| 30 | `Dumped type: array |
PHP 7.4 (7 errors)
| Line | Error |
|---|---|
| 9 | Method Base::check() has invalid return type mixed. |
| 9 | PHPDoc tag @return with type T is not subtype of native type mixed. |
| 15 | `Return type array of method Fail::check() is not covariant with return type mixed |
| 24 | Method Good::check() uses native union types but they're supported only on PHP 8.0 and later. |
| 24 | `Return type array |
| 29 | Dumped type: array |
| 30 | `Dumped type: array |
PHP 7.2 – 7.3 (7 errors)
| Line | Error |
|---|---|
| 9 | Method Base::check() has invalid return type mixed. |
| 9 | PHPDoc tag @return with type T is not subtype of native type mixed. |
| 15 | `Return type array of method Fail::check() is not compatible with return type mixed |
| 24 | Method Good::check() uses native union types but they're supported only on PHP 8.0 and later. |
| 24 | `Return type array |
| 29 | Dumped type: array |
| 30 | `Dumped type: array |
@staabm After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:
@@ @@
PHP 8.0 – 8.3 (2 errors)
==========
-29: Dumped type: array
-30: Dumped type: array|(callable(): mixed)
+29: Dumped type: array<mixed>
+30: Dumped type: array<mixed>|(callable(): mixed)
-PHP 7.2 – 7.4 (3 errors)
+PHP 7.4 (7 errors)
==========
+ 9: Method Base::check() has invalid return type mixed.
+ 9: PHPDoc tag @return with type T is not subtype of native type mixed.
+15: Return type array of method Fail::check() is not covariant with return type mixed|null of method Base<array<mixed>>::check().
24: Method Good::check() uses native union types but they're supported only on PHP 8.0 and later.
-29: Dumped type: array
-30: Dumped type: array|(callable(): mixed)
+24: Return type array|(callable) of method Good::check() is not covariant with return type mixed|null of method Base<array<mixed>|(callable)>::check().
+29: Dumped type: array<mixed>
+30: Dumped type: array<mixed>|(callable(): mixed)
+
+PHP 7.2 – 7.3 (7 errors)
+==========
+
+ 9: Method Base::check() has invalid return type mixed.
+ 9: PHPDoc tag @return with type T is not subtype of native type mixed.
+15: Return type array of method Fail::check() is not compatible with return type mixed|null of method Base<array<mixed>>::check().
+24: Method Good::check() uses native union types but they're supported only on PHP 8.0 and later.
+24: Return type array|(callable) of method Good::check() is not compatible with return type mixed|null of method Base<array<mixed>|(callable)>::check().
+29: Dumped type: array<mixed>
+30: Dumped type: array<mixed>|(callable(): mixed)
Full report
PHP 8.0 – 8.3 (2 errors)
| Line | Error |
|---|---|
| 29 | Dumped type: array<mixed> |
| 30 | `Dumped type: array |
PHP 7.4 (7 errors)
| Line | Error |
|---|---|
| 9 | Method Base::check() has invalid return type mixed. |
| 9 | PHPDoc tag @return with type T is not subtype of native type mixed. |
| 15 | `Return type array of method Fail::check() is not covariant with return type mixed |
| 24 | Method Good::check() uses native union types but they're supported only on PHP 8.0 and later. |
| 24 | `Return type array |
| 29 | Dumped type: array<mixed> |
| 30 | `Dumped type: array |
PHP 7.2 – 7.3 (7 errors)
| Line | Error |
|---|---|
| 9 | Method Base::check() has invalid return type mixed. |
| 9 | PHPDoc tag @return with type T is not subtype of native type mixed. |
| 15 | `Return type array of method Fail::check() is not compatible with return type mixed |
| 24 | Method Good::check() uses native union types but they're supported only on PHP 8.0 and later. |
| 24 | `Return type array |
| 29 | Dumped type: array<mixed> |
| 30 | `Dumped type: array |
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.