phpstan icon indicating copy to clipboard operation
phpstan copied to clipboard

Narrowing a type by extending loses information of parent

Open BackEndTea opened this issue 1 year ago • 7 comments
trafficstars

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

BackEndTea avatar Jul 22 '24 08:07 BackEndTea

I think you should use generics: https://phpstan.org/r/c3562717-43a9-4f1c-ad23-416386d1afe2

staabm avatar Jul 22 '24 18:07 staabm

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.

BackEndTea avatar Jul 22 '24 19:07 BackEndTea

Right now you need to repeat the @return. It's a known issue and already is present here on GitHub.

ondrejmirtes avatar Jul 23 '24 07:07 ondrejmirtes

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

BackEndTea avatar Jul 24 '24 06:07 BackEndTea

I'll be damned, can't find it either. Alright, this one will be the canonical one :)

ondrejmirtes avatar Jul 24 '24 06:07 ondrejmirtes

@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

phpstan-bot avatar Sep 04 '24 14:09 phpstan-bot

@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

phpstan-bot avatar Oct 12 '24 15:10 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 Oct 30 '25 01:10 github-actions[bot]