psalm icon indicating copy to clipboard operation
psalm copied to clipboard

Interface method's docblock not inherited properly with generics

Open Shira-3749 opened this issue 10 months ago • 1 comments

Interface method's docblock is not inherited properly with generics in this case: https://psalm.dev/r/dd85197efc

Copy-pasting the entire doc-comment onto Collection::toArray() fixes this, but that's not ideal: https://psalm.dev/r/f7036c58c3

For comparison, it works as-is in PHPStan: https://phpstan.org/r/2185731e-afd0-4e07-905a-33908ee99f6a

Shira-3749 avatar Apr 26 '24 10:04 Shira-3749

I found these snippets:

https://psalm.dev/r/dd85197efc
<?php declare(strict_types=1);

/**
 * @template-covariant T
 */
interface ReadableList
{
    /**
     * @return list<T>
     */
    function toArray(): array;
}

/**
 * @template T
 * @implements ReadableList<T>
 * @psalm-consistent-constructor
 */
class Collection implements ReadableList
{
    /**
     * @param list<T> $values
     */
    function __construct(protected array $values = [])
    {}
    
    function toArray(): array
    {
        return $this->values;
    }
}

/**
 * @template T of scalar
 * @extends Collection<T>
 */
class ScalarList extends Collection
{
}

/**
 * @param ScalarList<string> $strings
 * @psalm-suppress UnusedVariable
 */
function example(ScalarList $strings): void
{
    /** @psalm-check-type $x = list<string> */
	$x = $strings->toArray();
}
Psalm output (using commit 08afc45):

ERROR: CheckType - 48:2 - Checked variable $x = list<string> does not match $x = list<T:ScalarList as scalar>
https://psalm.dev/r/f7036c58c3
<?php declare(strict_types=1);

/**
 * @template-covariant T
 */
interface ReadableList
{
    /**
     * @return list<T>
     */
    function toArray(): array;
}

/**
 * @template T
 * @implements ReadableList<T>
 * @psalm-consistent-constructor
 */
class Collection implements ReadableList
{
    /**
     * @param list<T> $values
     */
    function __construct(protected array $values = [])
    {}
    
    /**
     * (copy-pasted doc-comment)
     *
     * @return list<T>
     */
    function toArray(): array
    {
        return $this->values;
    }
}

/**
 * @template T of scalar
 * @extends Collection<T>
 */
class ScalarList extends Collection
{
}

/**
 * @param ScalarList<string> $strings
 * @psalm-suppress UnusedVariable
 */
function example(ScalarList $strings): void
{
    /** @psalm-check-type $x = list<string> */
	$x = $strings->toArray();
}
Psalm output (using commit 08afc45):

No issues!

psalm-github-bot[bot] avatar Apr 26 '24 10:04 psalm-github-bot[bot]