phpstan
phpstan copied to clipboard
Template type is overriden by the native typehint of the method
Bug report
Code snippet that reproduces the problem
https://phpstan.org/r/97f95150-498a-4722-a0fb-cbe13af32bf3 is working fine but https://phpstan.org/r/24aaa27a-e6a5-478b-a85f-b25af078d5af is throwing a lot of errors:
- Cannot access property $foo on array|SimpleXMLElement.
- PHPStan is asking to specify in iterable type array|SimpleXMLElement.
In the same way, https://phpstan.org/r/adeaffc9-e53c-48ee-93aa-748069f6308b is working fine https://phpstan.org/r/f5f77c8d-2329-4ec4-ac9c-4fde412fd663 is throwing an error:
- Offset 'count' does not exist on array{count: int}|string.
Expected output
No errors
I saw you marked this as an easy fixes @ondrejmirtes. I'd like to work on it ; any advice what should I do/where should I look ?
IMHO It's caused by this commit: https://github.com/phpstan/phpstan-src/commit/c3d09898e8195346c66d66fa7908fa65e27e451a
This shows the current behaviour: https://phpstan.org/r/0c1858ce-f4bc-45cc-8742-3a161b0f0022
We probably need to rethink it for generics.
Didn't know this was an expected behavior for non-generic. I'm surprised by the behavior
/**
* @param array<int, string> $foo
*/
public function doBaz(array|false $foo): void
{
assertType('array<int, string>|false', $foo);
assertNativeType('array|false', $foo);
assertType('array<int, string>|false', $this->doLorem());
}
It's different for Psalm https://psalm.dev/r/ac26cd17e4
But, yeah, it should at least respect generics.
Edit: It's really weird for psalm cf https://psalm.dev/r/98340f0135 and https://psalm.dev/r/3a3b729ab0
I tried to debug the getType method, but the issue I have is that when I dump the $phpDocType
I get an
PHPStan\Type\ArrayType
described as array<int, int>
.
Is there a way to know the type is coming from the generic ?
Is there a way to know the type is coming from the generic ?
I saw you contributed a lot @staabm ; maybe do you know how/if this is possible ?
I tried to debug the getType method, but the issue I have is that when I dump the $phpDocType I get an PHPStan\Type\ArrayType described as array<int, int>.
You should use a step-debugger, like xdebug. Otherwise its a time consuming try & error.
maybe do you know how/if this is possible ?
I am not that much into generics.
I tried to solve
/**
* @phpstan-template T of array|false
*/
interface Templated
{
/**
* @param T $foo
*/
public function doBaz(array|false $foo): void;
}
/**
* @phpstan-implements Templated<array<int, string>>
*/
class BarTemplated implements Templated
{
public function doBaz(array|false $foo): void
{
assertType('array<int, string>', $foo);
assertNativeType('array', $foo);
}
}
first, but doesn't seems to be an easy fix to me.
I still don't understand how/where the template are resolved.
If I could do the intersection of the decideType
value and the resolved template type, this could be the solution...