Skip to content

Commit 547aff4

Browse files
Fix hasOffsetValueType with object
1 parent 6238750 commit 547aff4

File tree

9 files changed

+67
-5
lines changed

9 files changed

+67
-5
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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use PHPStan\Type\BooleanType;
2020
use PHPStan\Type\ErrorType;
2121
use PHPStan\Type\MixedType;
22-
use PHPStan\Type\StringType;
2322
use PHPStan\Type\Type;
2423
use PHPStan\Type\TypeCombinator;
2524

@@ -271,7 +270,7 @@ public function toArray(): Type
271270

272271
public function toArrayKey(): Type
273272
{
274-
return new StringType();
273+
return new ErrorType();
275274
}
276275

277276
public function toCoercedArgumentType(bool $strictTypes): Type

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1801,7 +1801,7 @@ public static function dataProperties(): array
18011801
'$this->resource',
18021802
],
18031803
[
1804-
'mixed',
1804+
'*ERROR*',
18051805
'$this->yetAnotherAnotherMixedParameter',
18061806
],
18071807
[

tests/PHPStan/Levels/data/stringOffsetAccess-3.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,19 @@
99
"line": 16,
1010
"ignorable": true
1111
},
12+
{
13+
"message": "Offset int|object does not exist on array{baz: 21}|array{foo: 17, bar: 19}.",
14+
"line": 55,
15+
"ignorable": true
16+
},
1217
{
1318
"message": "Invalid array key type stdClass.",
1419
"line": 59,
1520
"ignorable": true
21+
},
22+
{
23+
"message": "Offset stdClass does not exist on array{baz: 21}|array{foo: 17, bar: 19}.",
24+
"line": 59,
25+
"ignorable": true
1626
}
17-
]
27+
]

tests/PHPStan/Levels/data/stringOffsetAccess-7.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
"line": 31,
1010
"ignorable": true
1111
},
12+
{
13+
"message": "Offset int|object might not exist on array|string.",
14+
"line": 35,
15+
"ignorable": true
16+
},
1217
{
1318
"message": "Possibly invalid array key type int|object.",
1419
"line": 35,

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ public function testStrings(): void
193193
'Offset 12.34 might not exist on array|string.',
194194
28,
195195
],
196+
[
197+
'Offset int|object might not exist on array|string.',
198+
32,
199+
],
196200
]);
197201
}
198202

@@ -921,6 +925,20 @@ public function testBug12593(): void
921925
$this->analyse([__DIR__ . '/data/bug-12593.php'], []);
922926
}
923927

928+
public function testBugObject(): void
929+
{
930+
$this->analyse([__DIR__ . '/data/bug-object.php'], [
931+
[
932+
'Offset int|object does not exist on array{baz: 21}|array{foo: 17, bar: 19}.',
933+
12,
934+
],
935+
[
936+
'Offset object does not exist on array<string, int>.',
937+
21,
938+
],
939+
]);
940+
}
941+
924942
public function testBug3747(): void
925943
{
926944
$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)