vimeo / psalm

A static analysis tool for finding errors in PHP applications
https://psalm.dev
MIT License
5.55k stars 661 forks source link

False-positive `InvalidArgument` when calling methods on a different instance of a generic class #10854

Open Shira-3749 opened 6 months ago

Shira-3749 commented 6 months ago

When calling methods on a different instance of the same generic class, the argument types aren't resolved correctly:

psalm-github-bot[bot] commented 6 months ago

I found these snippets:

https://psalm.dev/r/b4c4f99a60 ```php value; } /** @param T $value */ function setValue(mixed $value): void { $this->value = $value; } /** * @template T2 * @param self $another */ function example(self $another): void { /** @psalm-trace $anotherValue */ $anotherValue = $another->getValue(); $another->setValue($anotherValue); // expects T, but should expect T2 } } ``` ``` Psalm output (using commit ef3b018): INFO: Trace - 30:9 - $anotherValue: T2:fn-example::example as mixed ERROR: InvalidArgument - 32:28 - Argument 1 of Example::setValue expects T:Example as mixed, but T2:fn-example::example as mixed provided ```
https://psalm.dev/r/a5a7b5ed21 ```php $values */ function __construct(private array $values = []) { } /** @param T $value */ function add(mixed $value): void { $this->values[] = $value; } /** * @param positive-int $size * @return self> */ function chunk(int $size): self { /** * @var self> $chunks * @psalm-trace $chunks */ $chunks = new self(); foreach (\array_chunk($this->values, $size) as $chunk) { /** @psalm-trace $chunk */ $chunk = new static($chunk); $chunks->add($chunk); // expects T, but should expect static } return $chunks; } } ``` ``` Psalm output (using commit ef3b018): INFO: Trace - 31:9 - $chunks: Collection&static> INFO: Trace - 35:13 - $chunk: Collection&static ERROR: InvalidArgument - 37:26 - Argument 1 of Collection::add expects T:Collection as mixed, but Collection&static provided ```