New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Contextual inference for Closure param types #7209
Comments
I found these snippets: https://psalm.dev/r/310e6ed76e<?php
/**
* @template A
* @template B
* @param list<A> $collection
* @param callable(A): B $ab
* @return list<B>
*/
function map(array $collection, callable $ab): array
{
$b = [];
foreach ($collection as $a) {
$b[] = $ab($a);
}
return $b;
}
/** @var list<int> */
$numbers = [];
$mapped = map($numbers, fn($num) => $num + 1);
/** @psalm-trace $mapped */;
https://psalm.dev/r/b60a08d22a<?php
/**
* @template A
* @template B
* @param list<A> $collection
* @param callable(A): B $ab
* @return list<B>
*/
function map(array $collection, callable $ab): array
{
$b = [];
foreach ($collection as $a) {
$b[] = $ab($a);
}
return $b;
}
/** @template T */
final class Foo {}
/** @var list<Foo<int>> */
$fooList = [];
// Actual: list<array{Foo}>
// Expected: list<array{Foo<int>}>
$mapped = map($fooList, fn(Foo $num) => [$num]);
/** @psalm-trace $mapped */;
https://psalm.dev/r/7c9621b9d3<?php
/**
* @template A
* @template B
* @param list<A> $collection
* @param callable(A): B $ab
* @return list<B>
*/
function map(array $collection, callable $ab): array
{
$b = [];
foreach ($collection as $a) {
$b[] = $ab($a);
}
return $b;
}
/** @template T */
final class Foo {}
/** @var list<Foo<int>> */
$fooList = [];
// Actual: list<array{Foo<int>}>
// Expected: list<array{Foo<int>}>
$mapped = map(
$fooList,
/** @param Foo<int> $num*/
fn($num) => [$num],
);
/** @psalm-trace $mapped */;
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's very painful that psalm can't infer closure parameters from context:
https://psalm.dev/r/310e6ed76e
Of course we can specify type hint. But if type have templates it will be lost:
https://psalm.dev/r/b60a08d22a
Doc blocks preserves templates, but code looks bad:
https://psalm.dev/r/7c9621b9d3
We could write code like this:
From what I've learned, it is relatively easy to implement left-to-right args type resolving for furter closure params inference.
I don't think Psalm needs a right-to-left analysis that was be mentioned in #5820. From my point of view its rare and difficult case.
The text was updated successfully, but these errors were encountered: