Skip to content

Commit 6895e54

Browse files
authored
Fix phpstan/phpstan#14352: "Cannot re-assign $this." false-positive (#5281)
1 parent 85c4052 commit 6895e54

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ lint:
134134
--exclude tests/PHPStan/Rules/EnumCases/data/bug-14252.php \
135135
--exclude tests/PHPStan/Rules/Functions/data/bug-14241.php \
136136
--exclude tests/PHPStan/Rules/Variables/data/bug-14349.php \
137+
--exclude tests/PHPStan/Rules/Variables/data/bug-14352.php \
137138
src tests
138139

139140
install-paratest:

src/Rules/Variables/InvalidVariableAssignRule.php

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

33
namespace PHPStan\Rules\Variables;
44

5+
use ArrayAccess;
56
use PhpParser\Node;
67
use PHPStan\Analyser\Scope;
78
use PHPStan\DependencyInjection\RegisteredRule;
@@ -30,6 +31,14 @@ public function processNode(Node $node, Scope $scope): array
3031
}
3132

3233
if ($variable->name === 'this') {
34+
if ($scope->isInClass()) {
35+
$classReflection = $scope->getClassReflection();
36+
37+
if ($classReflection->implementsInterface(ArrayAccess::class)) {
38+
return [];
39+
}
40+
}
41+
3342
return [
3443
RuleErrorBuilder::message('Cannot re-assign $this.')
3544
->identifier('assign.this')

tests/PHPStan/Rules/Variables/InvalidVariableAssignRuleTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
7+
use PHPUnit\Framework\Attributes\RequiresPhp;
78

89
/**
910
* @extends RuleTestCase<InvalidVariableAssignRule>
@@ -50,6 +51,43 @@ public function testBug3585(): void
5051
]);
5152
}
5253

54+
#[RequiresPhp('>= 8.0')]
55+
public function testBug14352(): void
56+
{
57+
$this->analyse([__DIR__ . '/data/bug-14352.php'], [
58+
/*
59+
[
60+
'Cannot re-assign $this.',
61+
13,
62+
],
63+
*/
64+
[
65+
'Cannot re-assign $this.',
66+
37,
67+
],
68+
[
69+
'Cannot re-assign $this.',
70+
39,
71+
],
72+
[
73+
'Cannot re-assign $this.',
74+
47,
75+
],
76+
[
77+
'Cannot re-assign $this.',
78+
49,
79+
],
80+
[
81+
'Cannot re-assign $this.',
82+
57,
83+
],
84+
[
85+
'Cannot re-assign $this.',
86+
63,
87+
],
88+
]);
89+
}
90+
5391
public function testBug14349(): void
5492
{
5593
$this->analyse([__DIR__ . '/data/bug-14349.php'], [
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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; // fine because ArrayAccess
12+
13+
$this = $value; // should still fail
14+
}
15+
16+
public function offsetExists(mixed $offset): bool
17+
{
18+
}
19+
20+
public function offsetGet(mixed $offset): mixed
21+
{
22+
}
23+
24+
public function offsetSet(mixed $offset, mixed $value): void
25+
{
26+
}
27+
28+
public function offsetUnset(mixed $offset): void
29+
{
30+
}
31+
}
32+
33+
final class FinalTestPlain
34+
{
35+
public function doFoo(string $key, string $value): void
36+
{
37+
$this[$key] = $value;
38+
39+
$this = $value;
40+
}
41+
}
42+
43+
class TestPlain
44+
{
45+
public function doFoo(string $key, string $value): void
46+
{
47+
$this[$key] = $value;
48+
49+
$this = $value;
50+
}
51+
}
52+
53+
class TestStatic
54+
{
55+
static public function doFoo(string $value): void
56+
{
57+
$this = $value;
58+
}
59+
}
60+
61+
function doFoo(string $value): void
62+
{
63+
$this = $value;
64+
}

0 commit comments

Comments
 (0)