Skip to content

Commit 4f11780

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

3 files changed

Lines changed: 64 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+
35,
59+
],
60+
]);
61+
}
62+
5363
public function testBug14349(): void
5464
{
5565
$this->analyse([__DIR__ . '/data/bug-14349.php'], [
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
}
17+
18+
public function offsetGet(mixed $offset): mixed
19+
{
20+
}
21+
22+
public function offsetSet(mixed $offset, mixed $value): void
23+
{
24+
}
25+
26+
public function offsetUnset(mixed $offset): void
27+
{
28+
}
29+
}
30+
31+
final class FinalTestPlain
32+
{
33+
public function doFoo(string $key, string $value): void
34+
{
35+
$this[$key] = $value;
36+
}
37+
}
38+
39+
class TestPlain
40+
{
41+
public function doFoo(string $key, string $value): void
42+
{
43+
$this[$key] = $value;
44+
}
45+
}

0 commit comments

Comments
 (0)