Skip to content

Commit ad07aca

Browse files
committed
"Cannot re-assign $this." false-positive
1 parent bebb16f commit ad07aca

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

src/Rules/Variables/InvalidVariableAssignRule.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
namespace PHPStan\Rules\Variables;
44

5+
use ArrayAccess;
56
use PhpParser\Node;
67
use PHPStan\Analyser\Scope;
78
use PHPStan\DependencyInjection\RegisteredRule;
89
use PHPStan\Node\VariableAssignNode;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Rules\RuleErrorBuilder;
12+
use PHPStan\Type\ObjectType;
1113
use function is_string;
1214

1315
/**
@@ -30,6 +32,13 @@ public function processNode(Node $node, Scope $scope): array
3032
}
3133

3234
if ($variable->name === 'this') {
35+
$expr = $node->getAssignedExpr();
36+
$type = $scope->getType($expr);
37+
38+
if ((new ObjectType(ArrayAccess::class))->isSuperTypeOf($type)->yes()) {
39+
return [];
40+
}
41+
3342
return [
3443
RuleErrorBuilder::message('Cannot re-assign $this.')
3544
->identifier('assign.this')

tests/PHPStan/Rules/Variables/InvalidVariableAssignRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ public function testBug3585(): void
5050
]);
5151
}
5252

53+
public function testBug14352(): void
54+
{
55+
$this->analyse([__DIR__ . '/data/bug-14352.php'], [
56+
[
57+
'Cannot re-assign $this.',
58+
39,
59+
],
60+
]);
61+
}
62+
5363
public function testBug14349(): void
5464
{
5565
$this->analyse([__DIR__ . '/data/bug-14349.php'], [
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug14352;
4+
5+
use ArrayAccess;
6+
7+
class TestArrayAccess implements ArrayAccess
8+
{
9+
public function doFoo(string $key, string $value): void
10+
{
11+
$this[$key] = $value;
12+
}
13+
14+
public function offsetExists(mixed $offset): bool
15+
{
16+
// TODO: Implement offsetExists() method.
17+
}
18+
19+
public function offsetGet(mixed $offset): mixed
20+
{
21+
// TODO: Implement offsetGet() method.
22+
}
23+
24+
public function offsetSet(mixed $offset, mixed $value): void
25+
{
26+
// TODO: Implement offsetSet() method.
27+
}
28+
29+
public function offsetUnset(mixed $offset): void
30+
{
31+
// TODO: Implement offsetUnset() method.
32+
}
33+
}
34+
35+
final class TestPlain
36+
{
37+
public function doFoo(string $key, string $value): void
38+
{
39+
$this[$key] = $value;
40+
}
41+
}

0 commit comments

Comments
 (0)