vimeo / psalm

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

Unknown template type defaulting to `empty` instead of `mixed` #6046

Open mr-feek opened 3 years ago

mr-feek commented 3 years ago

https://psalm.dev/r/565d4d6d18

Expected functionality would be to treat the template types as mixed.

Adding @var annotation makes the error disappear

https://psalm.dev/r/455d3d9fe6

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

I found these snippets:

https://psalm.dev/r/565d4d6d18 ```php $items * @return void */ public function __construct($items = []) {} /** * @param TKey $key * @param TValue $value * @return $this */ public function put($key, $value): self { return $this; } } $collection = new Collection(); $collection->put('key', 22221); $collection->put('key', []); $collection->put('key', ''); ``` ``` Psalm output (using commit c27b51b): ERROR: InvalidScalarArgument - 29:18 - Argument 1 of Collection::put expects empty, "key" provided ERROR: InvalidScalarArgument - 29:25 - Argument 2 of Collection::put expects empty, 22221 provided ERROR: InvalidScalarArgument - 30:18 - Argument 1 of Collection::put expects empty, "key" provided ERROR: InvalidArgument - 30:25 - Argument 2 of Collection::put expects empty, array provided ERROR: InvalidScalarArgument - 31:18 - Argument 1 of Collection::put expects empty, "key" provided ERROR: InvalidScalarArgument - 31:25 - Argument 2 of Collection::put expects empty, "" provided ```
https://psalm.dev/r/455d3d9fe6 ```php $items * @return void */ public function __construct($items = []) {} /** * @param TKey $key * @param TValue $value * @return $this */ public function put($key, $value): self { return $this; } } /** @var Collection $collection */ $collection = new Collection(); $collection->put('key', 22221); $collection->put('key', []); $collection->put('key', ''); ``` ``` Psalm output (using commit c27b51b): No issues! ```
weirdan commented 3 years ago

Psalm uses your default value to infer the type: https://psalm.dev/r/7926ff16a1

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

I found these snippets:

https://psalm.dev/r/7926ff16a1 ```php $items * @return void */ public function __construct($items = ["a" => 1]) {} /** * @param TKey $key * @param TValue $value * @return $this */ public function put($key, $value): self { return $this; } } $collection = new Collection(); /** @psalm-trace $collection */; $collection->put('key', 22221); $collection->put('key', []); $collection->put('key', ''); ``` ``` Psalm output (using commit 3abea66): INFO: Trace - 29:32 - $collection: Collection<"a", 1> ERROR: InvalidArgument - 30:18 - Argument 1 of Collection::put expects "a", "key" provided ERROR: InvalidArgument - 30:25 - Argument 2 of Collection::put expects 1, 22221 provided ERROR: InvalidArgument - 31:18 - Argument 1 of Collection::put expects "a", "key" provided ERROR: InvalidArgument - 31:25 - Argument 2 of Collection::put expects 1, array provided ERROR: InvalidArgument - 32:18 - Argument 1 of Collection::put expects "a", "key" provided ERROR: InvalidArgument - 32:25 - Argument 2 of Collection::put expects 1, "" provided ```
mr-feek commented 3 years ago

@weirdan would you consider this as a bug or as expected?

weirdan commented 3 years ago

I'd say it's consistent, but just not very useful in this case. As long as array<empty,empty> is a valid type.