vimeo / psalm

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

Wrong inferred templates on consecutive chained method call #9259

Open thomasvargiu opened 1 year ago

thomasvargiu commented 1 year ago

https://psalm.dev/r/b355396881

Probably is something related with templates on callables, but this is really weird.

As you can see here (https://psalm.dev/r/6e491c9102) the first chain call is correct, but the second one is not. If Psalm doesn't support something at least I would expect a mixed template type.

psalm-github-bot[bot] commented 1 year ago

I found these snippets:

https://psalm.dev/r/b355396881 ```php ) $function * * @psalm-return Monad * @psalm-suppress InvalidReturnType */ public function chain(callable $function): Monad {} /** * @template B * * @psalm-param callable(A): Monad $f * * @psalm-return Monad */ public function chainFirst(callable $f): Monad { return $this->chain($f)->chain(fn () => $this); } } ``` ``` Psalm output (using commit 1ee0f1b): ERROR: InvalidReturnStatement - 26:16 - The inferred type 'Monad' does not match the declared return type 'Monad' for Monad::chainFirst ERROR: InvalidReturnType - 22:22 - The declared return type 'Monad' for Monad::chainFirst is incorrect, got 'Monad' ```
https://psalm.dev/r/6e491c9102 ```php ) $function * * @psalm-return Monad * @psalm-suppress InvalidReturnType */ public function chain(callable $function): Monad {} /** * @template B * * @psalm-param callable(A): Monad $f * * @psalm-return Monad */ public function chainFirst(callable $f): Monad { /** @psalm-trace $a */ $a = $this->chain($f); /** @psalm-trace $b */ $b = $a->chain(fn () => $this); return $b; } } ``` ``` Psalm output (using commit 1ee0f1b): INFO: Trace - 27:9 - $a: Monad INFO: Trace - 29:9 - $b: Monad ERROR: InvalidReturnStatement - 30:16 - The inferred type 'Monad' does not match the declared return type 'Monad' for Monad::chainFirst ERROR: InvalidReturnType - 22:22 - The declared return type 'Monad' for Monad::chainFirst is incorrect, got 'Monad' ```