diff --git a/src/Type/Constant/ConstantArrayType.php b/src/Type/Constant/ConstantArrayType.php index ac9294134c..5023310ef9 100644 --- a/src/Type/Constant/ConstantArrayType.php +++ b/src/Type/Constant/ConstantArrayType.php @@ -234,6 +234,9 @@ public function isSuperTypeOf(Type $type): TrinaryLogic if ($type instanceof self) { if (count($this->keyTypes) === 0) { if (count($type->keyTypes) > 0) { + if (count($type->optionalKeys) > 0) { + return TrinaryLogic::createMaybe(); + } return TrinaryLogic::createNo(); } @@ -244,7 +247,12 @@ public function isSuperTypeOf(Type $type): TrinaryLogic foreach ($this->keyTypes as $i => $keyType) { $hasOffset = $type->hasOffsetValueType($keyType); if ($hasOffset->no()) { - return TrinaryLogic::createNo(); + if (!$this->isOptionalKey($i)) { + return TrinaryLogic::createNo(); + } + + $results[] = TrinaryLogic::createMaybe(); + continue; } $results[] = $this->valueTypes[$i]->isSuperTypeOf($type->getOffsetValueType($keyType)); } diff --git a/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php b/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php index bd4199a988..09a5bc0b14 100644 --- a/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php +++ b/tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php @@ -449,6 +449,54 @@ public function dataIsSuperTypeOf(): iterable ]), TrinaryLogic::createNo(), ]; + + yield [ + new ConstantArrayType([ + new ConstantStringType('foo'), + new ConstantStringType('bar'), + ], [ + new IntegerType(), + new IntegerType(), + ], 2), + new ConstantArrayType([], []), + TrinaryLogic::createNo(), + ]; + + yield [ + new ConstantArrayType([ + new ConstantStringType('foo'), + new ConstantStringType('bar'), + ], [ + new IntegerType(), + new IntegerType(), + ], 2, [0]), + new ConstantArrayType([], []), + TrinaryLogic::createNo(), + ]; + + yield [ + new ConstantArrayType([ + new ConstantStringType('foo'), + new ConstantStringType('bar'), + ], [ + new IntegerType(), + new IntegerType(), + ], 2, [0, 1]), + new ConstantArrayType([], []), + TrinaryLogic::createMaybe(), + ]; + + yield [ + new ConstantArrayType([], []), + new ConstantArrayType([ + new ConstantStringType('foo'), + new ConstantStringType('bar'), + ], [ + new IntegerType(), + new IntegerType(), + ], 2, [0, 1]), + TrinaryLogic::createMaybe(), + ]; } /**