Description
if you have a bit of code such as this:
function foo(int $length): string
{
return random_bytes($length);
}
https://psalm.dev/r/be5350cc96
Even though the signature for random_bytes() is just int, psalm somehow knows that it's expecting a positive, non-zero, value there, which leads to an error message since the caller has only asserted that it's an int: ERROR: ArgumentTypeCoercion - src/File.php - Argument 1 of random_bytes expects positive-int, but parent type int provided. Psalm then refers to https://psalm.dev/193 (which expands to https://psalm.dev/docs/running_psalm/issues/ArgumentTypeCoercion/ today.)
That page however has no useful information about the actual issue in this specific scenario where users are using language primitives. To solve this, I would suggest either:
- a different page be linked that talks about the pslam internal types like
positive-intand declarations like@psalm-paramor@psalm-var - that page be expanded on to talk about the above.
I would think the first of those would be preferable, but I don't know at the point in the code where the error is generated, if psalm has enough information to know if it's a user class or a primitive type.
For the benefit of anyone who lands on this bug in the future searching on the error message, our solution was a mix of:
/**
* @psalm-param positive-int $length
*/
function foo(int $length): string
{
return random_bytes($length);
}
and
function foo(int $length): string
{
/** @psalm-var positive-int $length */
return random_bytes($length);
}
depending on the context and how much of a headache it meant to propagate that internal psalm pseudo-primitive out into our codebase.