Skip to content

Commit 60f6325

Browse files
Fix ArrayType::hasOffsetValueType
1 parent c87456e commit 60f6325

File tree

5 files changed

+68
-0
lines changed

5 files changed

+68
-0
lines changed

src/Type/ArrayType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
272272
if ($offsetArrayKeyType instanceof ErrorType) {
273273
$allowedArrayKeys = AllowedArrayKeysTypes::getType();
274274
$offsetArrayKeyType = TypeCombinator::intersect($allowedArrayKeys, $offsetType)->toArrayKey();
275+
if ($offsetArrayKeyType instanceof NeverType) {
276+
return TrinaryLogic::createNo();
277+
}
275278
}
276279
$offsetType = $offsetArrayKeyType;
277280

src/Type/Constant/ConstantArrayType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
586586
if ($offsetArrayKeyType instanceof ErrorType) {
587587
$allowedArrayKeys = AllowedArrayKeysTypes::getType();
588588
$offsetArrayKeyType = TypeCombinator::intersect($allowedArrayKeys, $offsetType)->toArrayKey();
589+
if ($offsetArrayKeyType instanceof NeverType) {
590+
return TrinaryLogic::createNo();
591+
}
589592
}
590593

591594
return $this->recursiveHasOffsetValueType($offsetArrayKeyType);

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,10 @@ public function testBugObject(): void
949949
'Offset int|object does not exist on array{baz: 21}|array{foo: 17, bar: 19}.',
950950
12,
951951
],
952+
[
953+
'Offset object does not exist on array<string, int>.',
954+
21,
955+
],
952956
]);
953957
}
954958

tests/PHPStan/Type/ArrayTypeTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,36 @@ public function testResolveTemplateTypes(Type $received, Type $template, array $
269269
);
270270
}
271271

272+
public static function dataHasOffsetValueType(): array
273+
{
274+
return [
275+
[
276+
new ArrayType(new BenevolentUnionType([
277+
new IntegerType(),
278+
new StringType(),
279+
]), new IntegerType()),
280+
new ArrayType(new BenevolentUnionType([
281+
new IntegerType(),
282+
new StringType(),
283+
]), new IntegerType()),
284+
TrinaryLogic::createNo(),
285+
],
286+
];
287+
}
288+
289+
#[DataProvider('dataHasOffsetValueType')]
290+
public function testHasOffsetValueType(
291+
ArrayType $type,
292+
Type $offsetType,
293+
TrinaryLogic $expectedResult,
294+
): void
295+
{
296+
$actualResult = $type->hasOffsetValueType($offsetType);
297+
$this->assertSame(
298+
$expectedResult->describe(),
299+
$actualResult->describe(),
300+
sprintf('%s -> hasOffsetValueType(%s)', $type->describe(VerbosityLevel::precise()), $offsetType->describe(VerbosityLevel::precise())),
301+
);
302+
}
303+
272304
}

tests/PHPStan/Type/Constant/ConstantArrayTypeTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,4 +1044,30 @@ public function testValuesArray(ConstantArrayType $type, ConstantArrayType $expe
10441044
$this->assertSame($expectedType->getNextAutoIndexes(), $actualType->getNextAutoIndexes());
10451045
}
10461046

1047+
public static function dataHasOffsetValueType(): array
1048+
{
1049+
return [
1050+
[
1051+
new ConstantArrayType([new ConstantIntegerType(0)], [new ConstantStringType('a')]),
1052+
new ConstantArrayType([new ConstantIntegerType(0)], [new ConstantStringType('a')]),
1053+
TrinaryLogic::createNo(),
1054+
],
1055+
];
1056+
}
1057+
1058+
#[DataProvider('dataHasOffsetValueType')]
1059+
public function testHasOffsetValueType(
1060+
ConstantArrayType $type,
1061+
Type $offsetType,
1062+
TrinaryLogic $expectedResult,
1063+
): void
1064+
{
1065+
$actualResult = $type->hasOffsetValueType($offsetType);
1066+
$this->assertSame(
1067+
$expectedResult->describe(),
1068+
$actualResult->describe(),
1069+
sprintf('%s -> hasOffsetValueType(%s)', $type->describe(VerbosityLevel::precise()), $offsetType->describe(VerbosityLevel::precise())),
1070+
);
1071+
}
1072+
10471073
}

0 commit comments

Comments
 (0)