diff --git a/src/Type/Php/ArrayFlipFunctionReturnTypeExtension.php b/src/Type/Php/ArrayFlipFunctionReturnTypeExtension.php index 71f1140218..29d53b6432 100644 --- a/src/Type/Php/ArrayFlipFunctionReturnTypeExtension.php +++ b/src/Type/Php/ArrayFlipFunctionReturnTypeExtension.php @@ -8,9 +8,11 @@ use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Type\Accessory\NonEmptyArrayType; use PHPStan\Type\ArrayType; +use PHPStan\Type\Constant\ConstantArrayTypeBuilder; use PHPStan\Type\DynamicFunctionReturnTypeExtension; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; +use PHPStan\Type\TypeUtils; use function count; class ArrayFlipFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension @@ -30,6 +32,25 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, $array = $functionCall->getArgs()[0]->value; $argType = $scope->getType($array); + $constantArrays = TypeUtils::getOldConstantArrays($argType); + if (count($constantArrays) > 0) { + $flipped = []; + foreach ($constantArrays as $constantArray) { + $builder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($constantArray->getKeyTypes() as $i => $keyType) { + $valueType = $constantArray->getValueTypes()[$i]; + $builder->setOffsetValueType( + ArrayType::castToArrayKeyType($valueType), + $keyType, + $constantArray->isOptionalKey($i), + ); + } + $flipped[] = $builder->getArray(); + } + + return TypeCombinator::union(...$flipped); + } + if ($argType->isArray()->yes()) { $keyType = $argType->getIterableKeyType(); $itemType = $argType->getIterableValueType(); diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index 53944695a7..4b4b9f6b85 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -995,6 +995,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7563.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7764.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5845.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/array-flip-constant.php'); } /** diff --git a/tests/PHPStan/Analyser/data/array-flip-constant.php b/tests/PHPStan/Analyser/data/array-flip-constant.php new file mode 100644 index 0000000000..1081520823 --- /dev/null +++ b/tests/PHPStan/Analyser/data/array-flip-constant.php @@ -0,0 +1,26 @@ +