vimeo / psalm

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

Implementing constructor in a child class leads to false-positive MixedArgumentTypeCoercion #6139

Open fluffycondor opened 3 years ago

fluffycondor commented 3 years ago

https://psalm.dev/r/4a0d04f312 Psalm interprets list<Foo> as parent type array<array-key, mixed>. If I just remove constructor from the child class, which is completely useless in this particular example, the error disappears: https://psalm.dev/r/49da1a4776

psalm-github-bot[bot] commented 3 years ago

I found these snippets:

https://psalm.dev/r/4a0d04f312 ```php $elements */ public function __construct(array $elements = []) { print_r($elements); } } /** * @template TKey of array-key * @template T of Bar * @extends Collection */ class BarCollection extends Collection { /** @param array $elements */ public function __construct(array $elements = []) { parent::__construct($elements); } } interface Bar {} class Foo implements Bar {} class Baz { /** * @var Collection */ private Collection $foos; /** * @param list $foos; */ public function __construct(array $foos) { $this->foos = new BarCollection($foos); } } ``` ``` Psalm output (using commit 0317f1d): INFO: MixedArgumentTypeCoercion - 43:35 - Argument 1 of BarCollection::__construct expects array, parent type array provided ```
https://psalm.dev/r/49da1a4776 ```php $elements */ public function __construct(array $elements = []) { print_r($elements); } } /** * @template TKey of array-key * @template T of Bar * @extends Collection */ class BarCollection extends Collection {} interface Bar {} class Foo implements Bar {} class Baz { /** * @var Collection */ private Collection $foos; /** * @param list $foos; */ public function __construct(array $foos) { $this->foos = new BarCollection($foos); } } ``` ``` Psalm output (using commit 0317f1d): No issues! ```
weirdan commented 3 years ago

That's a docblock parser issue. Drop the semicolon in $foos; and it works as expected: https://psalm.dev/r/4a60b84656

psalm-github-bot[bot] commented 3 years ago

I found these snippets:

https://psalm.dev/r/4a60b84656 ```php $elements */ public function __construct(array $elements = []) { print_r($elements); } } /** * @template TKey of array-key * @template T of Bar * @extends Collection */ class BarCollection extends Collection { /** @param array $elements */ public function __construct(array $elements = []) { parent::__construct($elements); } } interface Bar {} class Foo implements Bar {} class Baz { /** * @var Collection */ private Collection $foos; /** * @param list $foos */ public function __construct(array $foos) { $this->foos = new BarCollection($foos); } } ``` ``` Psalm output (using commit 0317f1d): No issues! ```