Open azjezz opened 3 years ago
I found these snippets:
I found these snippets:
Psalm has some special behaviour for array_map
because it knows the type of the first array is unpacked into the argument for the second.
Imagine that the params are flipped: https://psalm.dev/r/5db81b6045
Now Psalm must know to scan the second argument first to get the param type so it can then use the correct types on the first. This is infeasible (and Hack does not do this either AFAIK).
I found these snippets:
This case should be handled at least for when the generic argument is provided before the closure.
currently a lot of projects i maintain contain these redundant parameters, and in most cases, the generic argument appears before the closure
Hack does not do this either AFAIK
it does!
Hack also handles this when the arguments are flipped:
Psalm has some special behaviour for
array_map
can this special behavior be replicated for other functions using a plugin? i would like to do so in php-standard-library/psalm-plugin
I stand very corrected!
can this special behavior be replicated for other functions using a plugin
No, but once I figure out how Hack is doing it this will work in Psalm.
Given this code:
function maptwice<T1, T2, T3>((function(T2):T3) $c2, (function(T1):T2) $c1, vec<T1> $a): vec<T3> {
$res = vec[];
foreach($a as $v) { $res[] = $c2($c1($v)); }
return $res;
}
function foo(vec<shape('a' => string, 'b' => int)> $input): vec<int> {
return maptwice(
($in) ==> $in + 3,
($in) ==> $in['b'],
$input
);
}
The process could go like this:
[T2 => T3, T1 => T2]
implies a chain of length two, so argument list will have to be scanned three timesEquivalent PHP: https://psalm.dev/r/2767b16320
I found these snippets:
@azjezz I believe this has been fixed, probably by a recent PR by @klimick . Can you confirm your use case is covered?
No, the example provided by @muglug is still failing ( https://psalm.dev/r/90597ecafa ), so i think this problem still persists
I found these snippets:
@klimick is this expected? Will #7471 be able to solve that?
@klimick is this expected? Will #7471 be able to solve that?
Expected. Inference of this kind is hard to implement for me. And functions with reverse arg ordering in PHP is rare. It is not worth implementing it in Psalm. In my opinion.
However, these rare cases can be covered with hook from #7471
Great! Thanks for the diagnosis!
It is not worth implementing it in Psalm. In my opinion.
I disagree, this problem currently results in the need of writing useless docblocks from the end user perspective to explain things to psalm.
As shown above, this is already supported by other type checkers such as hh ( hack ).
The following example shows the issue: https://psalm.dev/r/3e6b2451c3
Your first example has no issues now. Psalm can infer callable args at now. But only in left to right order.
can this special behavior be replicated for other functions using a plugin?
Currently I work at new plugin hook here #7471.
writing useless docblocks
With new hook we will able to write plugin for function with weird params ordering. We'll can implement behavior like array_map
has.
Look at test:
https://github.com/klimick/psalm/blob/f7da5a8d55d5a0e8b15a6f28a914042750dd0aa7/tests/Config/PluginTest.php#L1053-L1074
custom_array_map
similar to maptwice
I found these snippets:
Still doesn't work when the closure parameter is first.
Broken example: https://psalm.dev/r/16e9d5fb4f "Fixed" example: https://psalm.dev/r/28cded7a0d
Swapping the arguments is not always possible (e.g. varargs) or desirable.
PHPStan is fine with it as-is: https://phpstan.org/r/f7924a67-a216-4621-af5e-64ed76663816
I found these snippets:
The following example shows the issue: https://psalm.dev/r/3e6b2451c3
both map and array_map act the same way, however, psalm complains about missing
@param
type declaration for the closure with user land implementations, but not builtin array_map.This results in useless type declaration being added ( see https://psalm.dev/r/15e391e947 ) to satisfy psalm.