diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 5507652bdf..5b8670d3dd 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -1825,7 +1825,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression /** * @param Arg[] $callArgs - * @param callable(?Type, Type, bool=): void $setOffsetValueType + * @param callable(?Type, Type, bool): void $setOffsetValueType */ $setOffsetValueTypes = static function (Scope $scope, array $callArgs, callable $setOffsetValueType, ?bool &$nonConstantArrayWasUnpacked = null): void { foreach ($callArgs as $callArg) { @@ -1850,7 +1850,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression } continue; } - $setOffsetValueType(null, $callArgType); + $setOffsetValueType(null, $callArgType, false); } }; @@ -1861,7 +1861,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression $setOffsetValueTypes( $scope, $callArgs, - static function (?Type $offsetType, Type $valueType, bool $optional = false) use (&$arrayTypeBuilder): void { + static function (?Type $offsetType, Type $valueType, bool $optional) use (&$arrayTypeBuilder): void { $arrayTypeBuilder->setOffsetValueType($offsetType, $valueType, $optional); }, $nonConstantArrayWasUnpacked, @@ -1890,8 +1890,14 @@ static function (?Type $offsetType, Type $valueType, bool $optional = false) use $setOffsetValueTypes( $scope, $callArgs, - static function (?Type $offsetType, Type $valueType) use (&$arrayType): void { + static function (?Type $offsetType, Type $valueType, bool $optional) use (&$arrayType): void { + $isIterableAtLeastOnce = $arrayType->isIterableAtLeastOnce()->yes() || !$optional; $arrayType = $arrayType->setOffsetValueType($offsetType, $valueType); + if ($isIterableAtLeastOnce) { + return; + } + + $arrayType = TypeCombinator::union(...TypeUtils::getArrays($arrayType)); }, ); } diff --git a/tests/PHPStan/Analyser/data/array-push.php b/tests/PHPStan/Analyser/data/array-push.php index e4a42922c5..8aaaf3326d 100644 --- a/tests/PHPStan/Analyser/data/array-push.php +++ b/tests/PHPStan/Analyser/data/array-push.php @@ -13,10 +13,14 @@ * @param non-empty-array $c * @param array $d */ -function arrayPush(array $a, array $b, array $c, array $d): void +function arrayPush(array $a, array $b, array $c, array $d, array $arr): void { array_push($a, ...$b); - assertType('non-empty-array', $a); + assertType('array', $a); + + /** @var non-empty-array $arr */ + array_push($arr, ...$b); + assertType('non-empty-array', $arr); array_push($b, ...[]); assertType('array', $b); @@ -27,7 +31,7 @@ function arrayPush(array $a, array $b, array $c, array $d): void /** @var array $d1 */ $d1 = []; array_push($d, ...$d1); - assertType('non-empty-array', $d); + assertType('array', $d); } function arrayPushConstantArray(): void diff --git a/tests/PHPStan/Analyser/data/array-unshift.php b/tests/PHPStan/Analyser/data/array-unshift.php index 3b8d648455..59d7819819 100644 --- a/tests/PHPStan/Analyser/data/array-unshift.php +++ b/tests/PHPStan/Analyser/data/array-unshift.php @@ -13,10 +13,14 @@ * @param non-empty-array $c * @param array $d */ -function arrayUnshift(array $a, array $b, array $c, array $d): void +function arrayUnshift(array $a, array $b, array $c, array $d, array $arr): void { array_unshift($a, ...$b); - assertType('non-empty-array', $a); + assertType('array', $a); + + /** @var non-empty-array $arr */ + array_unshift($arr, ...$b); + assertType('non-empty-array', $arr); array_unshift($b, ...[]); assertType('array', $b); @@ -27,7 +31,7 @@ function arrayUnshift(array $a, array $b, array $c, array $d): void /** @var array $d1 */ $d1 = []; array_unshift($d, ...$d1); - assertType('non-empty-array', $d); + assertType('array', $d); } function arrayUnshiftConstantArray(): void diff --git a/tests/PHPStan/Rules/Variables/EmptyRuleTest.php b/tests/PHPStan/Rules/Variables/EmptyRuleTest.php index 1d457ba1c3..e0e6237594 100644 --- a/tests/PHPStan/Rules/Variables/EmptyRuleTest.php +++ b/tests/PHPStan/Rules/Variables/EmptyRuleTest.php @@ -169,4 +169,12 @@ public function testBug7318(): void $this->analyse([__DIR__ . '/../Properties/data/bug-7318.php'], []); } + public function testBug7424(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->strictUnnecessaryNullsafePropertyFetch = false; + + $this->analyse([__DIR__ . '/data/bug-7424.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Variables/data/bug-7424.php b/tests/PHPStan/Rules/Variables/data/bug-7424.php new file mode 100644 index 0000000000..ac685e0b19 --- /dev/null +++ b/tests/PHPStan/Rules/Variables/data/bug-7424.php @@ -0,0 +1,35 @@ +getInitData(); + + array_push($data, ...$this->getExtra()); + + if (empty($data)) { + return; + } + + echo 'Proceeding to process data'; + } + + /** + * @return string[] + */ + protected function getInitData(): array + { + return []; + } + + /** + * @return string[] + */ + protected function getExtra(): array + { + return []; + } +}