Skip to content

Commit 26e6270

Browse files
committed
Cover the sealed key-set shortcut against shapes of unknown sealedness
The shortcut in ConstantArrayType::isSuperTypeOf() only applies when both shapes are sealed: a shape of unknown sealedness accepts extra keys, so a required key it lacks decides nothing. isKeyIndexMiss() no longer asks isConstantScalarValue() first - a non-compound type has a single int or string constant scalar value only when it is that constant. Amp-Thread-ID: https://ampcode.com/threads/T-01a1b24f-ec49-7194-bbd2-0f4a43ab9b8f
1 parent 0401e57 commit 26e6270

3 files changed

Lines changed: 25 additions & 4 deletions

File tree

‎src/Type/Constant/ConstantArrayType.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3318,7 +3318,7 @@ private function findVerifiedKeyIndex(Type $offsetType): ?int
33183318
*/
33193319
private function isKeyIndexMiss(Type $offsetType): bool
33203320
{
3321-
if ($offsetType instanceof CompoundType || !$offsetType->isConstantScalarValue()->yes()) {
3321+
if ($offsetType instanceof CompoundType) {
33223322
return false;
33233323
}
33243324

‎tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,30 @@ public static function dataIsSuperTypeOfWithoutBleedingEdge(): array
934934
]),
935935
TrinaryLogic::createYes(),
936936
],
937+
// the same with the other shape sealed: its extra required key does not decide anything
938+
[
939+
new ConstantArrayType([new ConstantStringType('a')], [new StringType()]),
940+
new ConstantArrayType([
941+
new ConstantStringType('a'),
942+
new ConstantStringType('b'),
943+
], [
944+
new StringType(),
945+
new IntegerType(),
946+
], unsealed: [new NeverType(true), new NeverType(true)]),
947+
TrinaryLogic::createYes(),
948+
],
949+
// a sealed shape against one with unknown sealedness and an extra required key
950+
[
951+
new ConstantArrayType([new ConstantStringType('a')], [new StringType()], unsealed: [new NeverType(true), new NeverType(true)]),
952+
new ConstantArrayType([
953+
new ConstantStringType('a'),
954+
new ConstantStringType('b'),
955+
], [
956+
new StringType(),
957+
new IntegerType(),
958+
]),
959+
TrinaryLogic::createYes(),
960+
],
937961
]);
938962
}
939963

‎turbo-ext/src/ConstantArrayType.cpp‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,9 +5216,6 @@ class ConstantArrayType
52165216
bool compound;
52175217
if (UNEXPECTED(!isInstance(offsetType, PT_CLASS_COMPOUND_TYPE, compound))) return false;
52185218
if (compound) return true;
5219-
zend_long isConstantScalar = pt_type_op_trinary(Z_OBJ_P(offsetType), PT_OP_IS_CONSTANT_SCALAR_VALUE, 0, NULL);
5220-
if (UNEXPECTED(isConstantScalar < 0)) return false;
5221-
if (isConstantScalar != PT_TRI_YES) return true;
52225219

52235220
zv::Val values = pt_type_call_array(Z_OBJ_P(offsetType), PT_LC("getconstantscalarvalues"), 0, NULL);
52245221
if (UNEXPECTED(values.isUndef())) return false;

0 commit comments

Comments
 (0)