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 (668 forks)batch import
Help wanteddocumentation

Repository metrics

Stars
 (5,369 stars)
PR merge metrics
 (Avg merge 3d 12h) (5 merged PRs in 30d)

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