diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php index 35319816cea..2f85c7aa034 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php @@ -38,7 +38,6 @@ use function array_shift; use function array_slice; use function array_values; -use function assert; use function count; use function explode; use function in_array; @@ -79,6 +78,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev array_shift($call_args); $array_arg_types = []; + $orig_types = []; foreach ($call_args as $call_arg) { $call_arg_type = $statements_source->node_data->getType($call_arg->value); @@ -89,11 +89,23 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev && $call_arg_atomic->fallback_params === null ) { $array_arg_types []= array_values($call_arg_atomic->properties); + $orig_types []= $call_arg_type; + } elseif ($call_arg_type + && $call_arg_type->isSingle() + && ($call_arg_atomic = $call_arg_type->getSingleAtomic()) instanceof TArray + && $call_arg_atomic->isEmptyArray() + ) { + $array_arg_types []= []; + $orig_types []= $call_arg_type; } else { return Type::getArray(); } } + if (count($orig_types) === 1) { + return $orig_types[0]; + } + $null = Type::getNull(); $array_arg_types = array_map(null, ...$array_arg_types); $array_arg_types = array_map( @@ -107,7 +119,10 @@ function (array $sub) use ($null) { }, $array_arg_types ); - assert(count($array_arg_types)); + + if (!$array_arg_types) { + return Type::getEmptyArray(); + } return new Union([new TKeyedArray($array_arg_types, null, null, true)]); } diff --git a/tests/ArrayFunctionCallTest.php b/tests/ArrayFunctionCallTest.php index c42bf717b6f..93711745b56 100644 --- a/tests/ArrayFunctionCallTest.php +++ b/tests/ArrayFunctionCallTest.php @@ -2063,6 +2063,22 @@ function takesString(string $string): void {} 'ignored_issues' => [], 'php_version' => '7.4', ], + 'arrayMapMoreZip' => [ + 'code' => ' 1]); + $d = array_map(null, [], []); + ', + 'assertions' => [ + '$a===' => 'array', + '$b===' => 'list{1}', + '$c===' => 'array{test: 1}', + '$d===' => 'array', + ], + 'ignored_issues' => [], + 'php_version' => '7.4', + ], 'arrayMapExplicitZip' => [ 'code' => '