You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This one has me stumped after trying many different variants of the PHPDoc tags on throwOnFailure(). As best I can tell, PHPStan is widening the incoming type from <something>|false to <something>|bool, which it then narrows to <something>|true per the conditional return type.
<?phpdeclare(strict_types=1);
classA
{
privateint$Counter = 0;
/** * @return stdClass */publicfunctiongetMayFail()
{
// PHPStan reports "Method A::getMayFail() should return stdClass but returns stdClass|true."return$this->throwOnFailure($this->mayFail());
}
/** * @template T * * @param T $result * @return (T is false ? never : T) */publicfunctionthrowOnFailure($result)
{
if ($result === false) {
thrownewException('Operation failed');
}
return$result;
}
/** * @return stdClass|false */publicfunctionmayFail()
{
$this->Counter++;
return$this->Counter % 2 ? new stdClass() : false;
}
}
If I change the DocBlock to this, it works:
/** * @template T * * @param T|false $result * @return ($result is false ? never : T) */
...but other tools (Intelephense, at least) don't like it and it isn't amenable to adding a second template for the failure value (e.g. so the caller can specify whether false or -1 are regarded as failures); and the original syntax should work 😉
Just flagging that after triggering Type false is not always the same as T. It breaks the contract for some argument types, typically subtypes. and chasing that down, it seems possible/likely this might be related to phpstan/phpstan-src#2652, as mentioned in #9961...
Bug report
This one has me stumped after trying many different variants of the PHPDoc tags on
throwOnFailure()
. As best I can tell, PHPStan is widening the incoming type from<something>|false
to<something>|bool
, which it then narrows to<something>|true
per the conditional return type.If I change the DocBlock to this, it works:
...but other tools (Intelephense, at least) don't like it and it isn't amenable to adding a second template for the failure value (e.g. so the caller can specify whether
false
or-1
are regarded as failures); and the original syntax should work 😉Code snippet that reproduces the problem
https://phpstan.org/r/06424f05-e1f9-4d72-903b-0f2cc1cc183b
Expected output
No errors; types should narrow to exclude
false
without addingtrue
.Did PHPStan help you today? Did it make you happy in any way?
In this moment it isn't making me happy 🤣 But I'm finally leveling up to 9 across my projects and am appreciating the quality improvements ❤️
The text was updated successfully, but these errors were encountered: