vimeo/psalm

pslam suggesting not-helpful reference page

Open

#9,131 opened on Jan 18, 2023

View on GitHub
 (4 comments) (0 reactions) (0 assignees)PHP (5,369 stars) (668 forks)batch import
Help wanteddocumentation

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:

  1. a different page be linked that talks about the pslam internal types like positive-int and declarations like @psalm-param or @psalm-var
  2. 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.

Contributor guide