diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 8369ac2430..c04b167b70 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -166,6 +166,7 @@ use function usort; use const PHP_INT_MAX; use const PHP_INT_MIN; +use const PHP_VERSION_ID; final class MutatingScope implements Scope { @@ -5138,7 +5139,10 @@ private static function generalizeType(Type $a, Type $b, int $depth): Type } else { $constantArraysA = TypeCombinator::union(...$constantArrays['a']); $constantArraysB = TypeCombinator::union(...$constantArrays['b']); - if ($constantArraysA->getIterableKeyType()->equals($constantArraysB->getIterableKeyType())) { + if ( + $constantArraysA->getIterableKeyType()->equals($constantArraysB->getIterableKeyType()) + && $constantArraysA->getArraySize()->equals($constantArraysB->getArraySize()) + ) { $resultArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach (TypeUtils::flattenTypes($constantArraysA->getIterableKeyType()) as $keyType) { $resultArrayBuilder->setOffsetValueType( @@ -5158,7 +5162,11 @@ private static function generalizeType(Type $a, Type $b, int $depth): Type TypeCombinator::union(self::generalizeType($constantArraysA->getIterableKeyType(), $constantArraysB->getIterableKeyType(), $depth + 1)), TypeCombinator::union(self::generalizeType($constantArraysA->getIterableValueType(), $constantArraysB->getIterableValueType(), $depth + 1)), ); - if ($constantArraysA->isIterableAtLeastOnce()->yes() && $constantArraysB->isIterableAtLeastOnce()->yes()) { + if ( + $constantArraysA->isIterableAtLeastOnce()->yes() + && $constantArraysB->isIterableAtLeastOnce()->yes() + && $constantArraysA->getArraySize()->getGreaterOrEqualType(new PhpVersion(PHP_VERSION_ID))->isSuperTypeOf($constantArraysB->getArraySize())->yes() + ) { $resultType = TypeCombinator::intersect($resultType, new NonEmptyArrayType()); } if ($constantArraysA->isList()->yes() && $constantArraysB->isList()->yes()) { diff --git a/tests/PHPStan/Analyser/nsrt/bug-1021.php b/tests/PHPStan/Analyser/nsrt/bug-1021.php index b085b9a781..37e2f7244f 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-1021.php +++ b/tests/PHPStan/Analyser/nsrt/bug-1021.php @@ -13,7 +13,7 @@ function foobar() { } } - assertType('array{0?: int<1, max>, 1?: 2|3, 2?: 3}', $x); + assertType('list<1|2|3>', $x); if ($x) { } diff --git a/tests/PHPStan/Analyser/nsrt/bug7856.php b/tests/PHPStan/Analyser/nsrt/bug7856.php index fcdca30b44..8da8b7343e 100644 --- a/tests/PHPStan/Analyser/nsrt/bug7856.php +++ b/tests/PHPStan/Analyser/nsrt/bug7856.php @@ -10,7 +10,7 @@ function doFoo() { $endDate = new DateTimeImmutable('+1year'); do { - assertType("array{'+1week', '+1months', '+6months', '+17months'}|array{0: literal-string&lowercase-string&non-falsy-string, 1?: literal-string&lowercase-string&non-falsy-string, 2?: '+17months'}", $intervals); + assertType("list", $intervals); $periodEnd = $periodEnd->modify(array_shift($intervals)); } while (count($intervals) > 0 && $periodEnd->format('U') < $endDate); }