Skip to content

Commit 6a15618

Browse files
Fix accessing offset with object
1 parent 5a50985 commit 6a15618

File tree

6 files changed

+46
-2
lines changed

6 files changed

+46
-2
lines changed

src/Type/ArrayType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
268268
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
269269
{
270270
$offsetType = $offsetType->toArrayKey();
271+
if ($offsetType instanceof ErrorType) {
272+
return TrinaryLogic::createNo();
273+
}
271274

272275
if ($this->getKeyType()->isSuperTypeOf($offsetType)->no()
273276
&& ($offsetType->isString()->no() || !$offsetType->isConstantScalarValue()->no())

src/Type/Constant/ConstantArrayType.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,10 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
588588

589589
private function recursiveHasOffsetValueType(Type $offsetType): TrinaryLogic
590590
{
591+
if ($offsetType instanceof ErrorType) {
592+
return TrinaryLogic::createNo();
593+
}
594+
591595
if ($offsetType instanceof UnionType) {
592596
$results = [];
593597
foreach ($offsetType->getTypes() as $innerType) {

src/Type/ObjectType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ public function toArray(): Type
702702

703703
public function toArrayKey(): Type
704704
{
705-
return $this->toString();
705+
return new ErrorType();
706706
}
707707

708708
public function toCoercedArgumentType(bool $strictTypes): Type

src/Type/Traits/ObjectTypeTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public function toArray(): Type
271271

272272
public function toArrayKey(): Type
273273
{
274-
return new StringType();
274+
return new ErrorType();
275275
}
276276

277277
public function toCoercedArgumentType(bool $strictTypes): Type

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,20 @@ public function testBug12593(): void
921921
$this->analyse([__DIR__ . '/data/bug-12593.php'], []);
922922
}
923923

924+
public function testBugObject(): void
925+
{
926+
$this->analyse([__DIR__ . '/data/bug-object.php'], [
927+
[
928+
'Offset int|object does not exist on array{baz: 21}|array{foo: 17, bar: 19}.',
929+
12,
930+
],
931+
[
932+
'Offset object does not exist on array<string, int>.',
933+
21,
934+
]
935+
]);
936+
}
937+
924938
public function testBug3747(): void
925939
{
926940
$this->analyse([__DIR__ . '/data/bug-3747.php'], []);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace BugObject;
4+
5+
class B {
6+
/**
7+
* @param array{baz: 21}|array{foo: 17, bar: 19} $array
8+
* @param int|object $key
9+
*/
10+
public function foo($array, $key)
11+
{
12+
$array[$key];
13+
}
14+
15+
/**
16+
* @param array<string, int> $array
17+
* @param object $key
18+
*/
19+
public function foo2($array, $key)
20+
{
21+
$array[$key];
22+
}
23+
}

0 commit comments

Comments
 (0)