mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix #663 - infer array return types for closures
This commit is contained in:
parent
9bdf9eefd3
commit
fe033f1b6c
@ -481,31 +481,35 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
$storage->return_type_location
|
||||
);
|
||||
|
||||
if ($this->function->inferredType
|
||||
&& (!$storage->return_type
|
||||
$closure_yield_types = [];
|
||||
|
||||
$closure_return_types = EffectsAnalyser::getReturnTypes(
|
||||
$this->function->stmts,
|
||||
$closure_yield_types,
|
||||
$ignore_nullable_issues,
|
||||
$ignore_falsable_issues,
|
||||
true
|
||||
);
|
||||
|
||||
if ($closure_return_types) {
|
||||
$closure_return_type = new Type\Union($closure_return_types);
|
||||
|
||||
if (!$storage->return_type
|
||||
|| $storage->return_type->isMixed()
|
||||
|| TypeChecker::isContainedBy(
|
||||
$project_checker->codebase,
|
||||
$this->function->inferredType,
|
||||
$closure_return_type,
|
||||
$storage->return_type
|
||||
)
|
||||
)
|
||||
) {
|
||||
$closure_yield_types = [];
|
||||
$closure_return_types = EffectsAnalyser::getReturnTypes(
|
||||
$this->function->stmts,
|
||||
$closure_yield_types,
|
||||
$ignore_nullable_issues,
|
||||
$ignore_falsable_issues,
|
||||
true
|
||||
);
|
||||
|
||||
if ($closure_return_types && $this->function->inferredType) {
|
||||
/** @var Type\Atomic\Fn */
|
||||
$closure_atomic = $this->function->inferredType->getTypes()['Closure'];
|
||||
$closure_atomic->return_type = new Type\Union($closure_return_types);
|
||||
) {
|
||||
if ($this->function->inferredType) {
|
||||
/** @var Type\Atomic\Fn */
|
||||
$closure_atomic = $this->function->inferredType->getTypes()['Closure'];
|
||||
$closure_atomic->return_type = $closure_return_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($context->collect_references
|
||||
|
@ -431,6 +431,42 @@ class CallableTest extends TestCase
|
||||
],
|
||||
'error_levels' => ['MissingClosureReturnType'],
|
||||
],
|
||||
'inferArrayMapReturnTypeWithoutTypehints' => [
|
||||
'<?php
|
||||
/**
|
||||
* @param array{0:string,1:string}[] $ret
|
||||
* @return array{0:string,1:int}[]
|
||||
*/
|
||||
function f(array $ret) : array
|
||||
{
|
||||
return array_map(
|
||||
function (array $row) {
|
||||
return [
|
||||
strval($row[0]),
|
||||
intval($row[1]),
|
||||
];
|
||||
}, $ret);
|
||||
}',
|
||||
'assertions' => [],
|
||||
'error_levels' => ['MissingClosureReturnType'],
|
||||
],
|
||||
'inferArrayMapReturnTypeWithTypehints' => [
|
||||
'<?php
|
||||
/**
|
||||
* @param array{0:string,1:string}[] $ret
|
||||
* @return array{0:string,1:int}[]
|
||||
*/
|
||||
function f(array $ret): array
|
||||
{
|
||||
return array_map(
|
||||
function (array $row): array {
|
||||
return [
|
||||
strval($row[0]),
|
||||
intval($row[1]),
|
||||
];
|
||||
}, $ret);
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user