diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 6e785c8d45..fddb980225 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -50,6 +50,7 @@ use PHPStan\TrinaryLogic; use PHPStan\Type\Accessory\AccessoryLiteralStringType; use PHPStan\Type\Accessory\AccessoryNonEmptyStringType; +use PHPStan\Type\Accessory\NonEmptyArrayType; use PHPStan\Type\ArrayType; use PHPStan\Type\BenevolentUnionType; use PHPStan\Type\BooleanType; @@ -1290,6 +1291,7 @@ private function resolveType(Expr $node): Type return TypeCombinator::union(...$resultTypes); } + $arrayType = new ArrayType(new MixedType(), new MixedType()); if ($arrayType->isSuperTypeOf($leftType)->yes() && $arrayType->isSuperTypeOf($rightType)->yes()) { @@ -1306,10 +1308,16 @@ private function resolveType(Expr $node): Type } $keyType = TypeCombinator::union(...$keyTypes); } - return new ArrayType( + + $arrayType = new ArrayType( $keyType, TypeCombinator::union($leftType->getIterableValueType(), $rightType->getIterableValueType()) ); + + if ($leftType->isIterableAtLeastOnce()->yes() || $rightType->isIterableAtLeastOnce()->yes()) { + return TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); + } + return $arrayType; } if ($leftType instanceof MixedType && $rightType instanceof MixedType) { diff --git a/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php b/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php index 6cdf52184c..d224a419e5 100644 --- a/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php @@ -2830,7 +2830,7 @@ public function dataBinaryOperations(): array '[1, 2, 3] + [4, 5, 6]', ], [ - 'array', + 'non-empty-array', '$arrayOfUnknownIntegers + [1, 2, 3]', ], [ diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index e09cc3a426..ffca869fb5 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -272,6 +272,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/array-map.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/array-map-closure.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/array-sum.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/array-plus.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4573.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4577.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4579.php'); diff --git a/tests/PHPStan/Analyser/data/array-plus.php b/tests/PHPStan/Analyser/data/array-plus.php new file mode 100644 index 0000000000..b6d8b99e2d --- /dev/null +++ b/tests/PHPStan/Analyser/data/array-plus.php @@ -0,0 +1,20 @@ +