Skip to content

Commit fc1c685

Browse files
authored
Allow destructuring of objects implementing ArrayAccess
1 parent e61ad95 commit fc1c685

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/Rules/Arrays/ArrayDestructuringRule.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPStan\Type\Constant\ConstantIntegerType;
1515
use PHPStan\Type\Constant\ConstantStringType;
1616
use PHPStan\Type\ErrorType;
17+
use PHPStan\Type\ObjectType;
1718
use PHPStan\Type\Type;
1819
use PHPStan\Type\VerbosityLevel;
1920

@@ -65,14 +66,14 @@ private function getErrors(Scope $scope, Expr $var, Expr $expr): array
6566
$expr,
6667
'',
6768
static function (Type $varType): bool {
68-
return $varType->isArray()->yes();
69+
return $varType->isArray()->yes() || (new ObjectType(\ArrayAccess::class))->isSuperTypeOf($varType)->yes();
6970
}
7071
);
7172
$exprType = $exprTypeResult->getType();
7273
if ($exprType instanceof ErrorType) {
7374
return [];
7475
}
75-
if (!$exprType->isArray()->yes()) {
76+
if (!$exprType->isArray()->yes() && !(new ObjectType(\ArrayAccess::class))->isSuperTypeOf($exprType)->yes()) {
7677
return [
7778
RuleErrorBuilder::message(sprintf('Cannot use array destructuring on %s.', $exprType->describe(VerbosityLevel::typeOnly())))->build(),
7879
];

tests/PHPStan/Rules/Arrays/data/array-destructuring.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,33 @@ public function doBar(): void
2222
['a' => $a] = ['b' => 1];
2323
}
2424

25+
public function doBaz(): void
26+
{
27+
$arrayObject = new FooArrayObject();
28+
['a' => $a] = $arrayObject;
29+
}
30+
31+
}
32+
33+
class FooArrayObject implements \ArrayAccess
34+
{
35+
36+
public function offsetGet($key)
37+
{
38+
return true;
39+
}
40+
41+
public function offsetSet($key, $value): void
42+
{
43+
}
44+
45+
public function offsetUnset($key): void
46+
{
47+
}
48+
49+
public function offsetExists($key): bool
50+
{
51+
return false;
52+
}
53+
2554
}

0 commit comments

Comments
 (0)