diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index 8b785274d5..6376d00a93 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -455,11 +455,10 @@ public function getArrayType(Expr\Array_ $expr, callable $getTypeCallback): Type } else { $arrayBuilder->degradeToGeneralArray(); - if (! (new StringType())->isSuperTypeOf($valueType->getIterableKeyType())->no() && $this->phpVersion->supportsArrayUnpackingWithStringKeys()) { - $arrayBuilder->setOffsetValueType($valueType->getIterableKeyType(), $valueType->getIterableValueType()); - } else { - $arrayBuilder->setOffsetValueType(new IntegerType(), $valueType->getIterableValueType(), !$valueType->isIterableAtLeastOnce()->yes() && !$valueType->getIterableValueType()->isIterableAtLeastOnce()->yes()); - } + $offsetType = $this->phpVersion->supportsArrayUnpackingWithStringKeys() && !(new StringType())->isSuperTypeOf($valueType->getIterableKeyType())->no() + ? $valueType->getIterableKeyType() + : new IntegerType(); + $arrayBuilder->setOffsetValueType($offsetType, $valueType->getIterableValueType(), !$valueType->isIterableAtLeastOnce()->yes()); } } else { $arrayBuilder->setOffsetValueType( diff --git a/tests/PHPStan/Analyser/data/array-unpacking-string-keys.php b/tests/PHPStan/Analyser/data/array-unpacking-string-keys.php index be5371f8b1..ccb2e6da0b 100644 --- a/tests/PHPStan/Analyser/data/array-unpacking-string-keys.php +++ b/tests/PHPStan/Analyser/data/array-unpacking-string-keys.php @@ -20,7 +20,7 @@ function foo(array $a, array $b) { $c = [...$a, ...$b]; - assertType('non-empty-array', $c); + assertType('array', $c); } /** @@ -31,7 +31,7 @@ function bar(array $a, array $b) { $c = [...$a, ...$b]; - assertType('non-empty-array', $c); + assertType('array', $c); } /** @@ -42,5 +42,27 @@ function baz(array $a, array $b) { $c = [...$a, ...$b]; - assertType('non-empty-array', $c); + assertType('array', $c); +} + +/** + * @param non-empty-array $a + * @param array $b + */ +function nonEmptyArray1(array $a, array $b) +{ + $c = [...$a, ...$b]; + + assertType('non-empty-array', $c); +} + +/** + * @param array $a + * @param non-empty-array $b + */ +function nonEmptyArray2(array $a, array $b) +{ + $c = [...$a, ...$b]; + + assertType('non-empty-array', $c); } diff --git a/tests/PHPStan/Analyser/data/bug-5287-php81.php b/tests/PHPStan/Analyser/data/bug-5287-php81.php index 21920ff3da..7884bbd6c6 100644 --- a/tests/PHPStan/Analyser/data/bug-5287-php81.php +++ b/tests/PHPStan/Analyser/data/bug-5287-php81.php @@ -19,7 +19,7 @@ function foo(array $arr): void function foo2(array $arr): void { $arrSpread = [...$arr]; - assertType('non-empty-array', $arrSpread); + assertType('array', $arrSpread); } /** diff --git a/tests/PHPStan/Analyser/data/bug-5287.php b/tests/PHPStan/Analyser/data/bug-5287.php index 3bcb5eb4fb..dab904a7f1 100644 --- a/tests/PHPStan/Analyser/data/bug-5287.php +++ b/tests/PHPStan/Analyser/data/bug-5287.php @@ -19,7 +19,7 @@ function foo(array $arr): void function foo2(array $arr): void { $arrSpread = [...$arr]; - assertType('non-empty-array', $arrSpread); + assertType('array', $arrSpread); } /** diff --git a/tests/PHPStan/Rules/Variables/EmptyRuleTest.php b/tests/PHPStan/Rules/Variables/EmptyRuleTest.php index e0e6237594..d38d53bdd3 100644 --- a/tests/PHPStan/Rules/Variables/EmptyRuleTest.php +++ b/tests/PHPStan/Rules/Variables/EmptyRuleTest.php @@ -177,4 +177,12 @@ public function testBug7424(): void $this->analyse([__DIR__ . '/data/bug-7424.php'], []); } + public function testBug7724(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->strictUnnecessaryNullsafePropertyFetch = false; + + $this->analyse([__DIR__ . '/data/bug-7724.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Variables/data/bug-7724.php b/tests/PHPStan/Rules/Variables/data/bug-7724.php new file mode 100644 index 0000000000..317988f1df --- /dev/null +++ b/tests/PHPStan/Rules/Variables/data/bug-7724.php @@ -0,0 +1,22 @@ += 7.4 + +declare(strict_types = 1); + +namespace Bug7724; + +$array = []; + +/** + * @return int[] + */ +function getElements(): array { + $empty = rand(0, 1); + + return $empty ? [] : [1]; +} + +$array = [...$array, ...getElements()]; + +if (false === empty($array)) { + +}