Skip to content

Commit 8038a29

Browse files
schlndhondrejmirtes
authored andcommitted
add null to array_map(null, $a, $b)
1 parent f158d5b commit 8038a29

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

src/Type/Php/ArrayMapFunctionReturnTypeExtension.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public function isFunctionSupported(FunctionReflection $functionReflection): boo
3232

3333
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): ?Type
3434
{
35-
if (count($functionCall->getArgs()) < 2) {
35+
$numArgs = count($functionCall->getArgs());
36+
if ($numArgs < 2) {
3637
return null;
3738
}
3839

@@ -54,10 +55,41 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
5455
)->getReturnType();
5556
} elseif ($callableIsNull) {
5657
$arrayBuilder = ConstantArrayTypeBuilder::createEmpty();
58+
$argIterableValueTypes = [];
59+
$addNull = false;
60+
$expectedSize = null;
5761
foreach (array_slice($functionCall->getArgs(), 1) as $index => $arg) {
62+
$argType = $scope->getType($arg->value);
63+
$argIterableValueTypes[$index] = $argType->getIterableValueType();
64+
if ($addNull) {
65+
continue;
66+
}
67+
68+
$arraySizes = $argType->getArraySize()->getConstantScalarValues();
69+
if ($arraySizes === []) {
70+
$addNull = true;
71+
continue;
72+
}
73+
74+
foreach ($arraySizes as $size) {
75+
$expectedSize ??= $size;
76+
if ($expectedSize === $size) {
77+
continue;
78+
}
79+
80+
$addNull = true;
81+
break;
82+
}
83+
}
84+
85+
foreach ($argIterableValueTypes as $index => $offsetValueType) {
86+
if ($addNull) {
87+
$offsetValueType = TypeCombinator::addNull($offsetValueType);
88+
}
89+
5890
$arrayBuilder->setOffsetValueType(
5991
new ConstantIntegerType($index),
60-
$scope->getType($arg->value)->getIterableValueType(),
92+
$offsetValueType,
6193
);
6294
}
6395
$valueType = $arrayBuilder->getArray();

tests/PHPStan/Analyser/nsrt/array_map_multiple.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public function arrayMapNull(array $array, array $other): void
2929
assertType('non-empty-array<int, array{1|2|3, 4|5|6}>', array_map(null, [1, 2, 3], [4, 5, 6]));
3030

3131
assertType('non-empty-array<string, int>', array_map(null, $array));
32-
assertType('non-empty-array<int, array{int, int}>', array_map(null, $array, $array));
33-
assertType('non-empty-array<int, array{int, bool}>', array_map(null, $array, $other));
32+
assertType('non-empty-array<int, array{int|null, int|null}>', array_map(null, $array, $array));
33+
assertType('non-empty-array<int, array{int|null, bool|null}>', array_map(null, $array, $other));
3434
}
3535

3636
}

0 commit comments

Comments
 (0)