Skip to content

Commit c6b5dd5

Browse files
VincentLangletphpstan-bot
authored andcommitted
Fix phpstan/phpstan#13473: isset() false positive in property set hook
- In property set hooks, the hooked property might not be initialized yet (e.g., when the set hook is triggered from __construct()) - Removed PropertyInitializationExpr for the hooked property from the scope when entering a set hook in MutatingScope::enterPropertyHook() - Added regression test in tests/PHPStan/Rules/Variables/data/bug-13473.php
1 parent abe2dd8 commit c6b5dd5

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

src/Analyser/MutatingScope.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,7 @@ public function enterPropertyHook(
15741574

15751575
$realParameterTypes = $this->getRealParameterTypes($hook);
15761576

1577-
return $this->enterFunctionLike(
1577+
$scope = $this->enterFunctionLike(
15781578
new PhpMethodFromParserNodeReflection(
15791579
$this->getClassReflection(),
15801580
$hook,
@@ -1606,6 +1606,14 @@ public function enterPropertyHook(
16061606
),
16071607
true,
16081608
);
1609+
1610+
if ($hookName === 'set') {
1611+
$initExprKey = $this->getNodeKey(new PropertyInitializationExpr($propertyName));
1612+
unset($scope->expressionTypes[$initExprKey]);
1613+
unset($scope->nativeExpressionTypes[$initExprKey]);
1614+
}
1615+
1616+
return $scope;
16091617
}
16101618

16111619
private function transformStaticType(Type $type): Type

tests/PHPStan/Rules/Variables/IssetRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,12 @@ public function testBug14393(): void
562562
]);
563563
}
564564

565+
#[RequiresPhp('>= 8.4')]
566+
public function testBug13473(): void
567+
{
568+
$this->treatPhpDocTypesAsCertain = true;
569+
570+
$this->analyse([__DIR__ . '/data/bug-13473.php'], []);
571+
}
572+
565573
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php // lint >= 8.4
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug13473;
6+
7+
class Foo {
8+
private(set) int $bar {
9+
get => $this->bar;
10+
set(int $bar) {
11+
if (isset($this->bar)) {
12+
throw new \Exception('bar is set');
13+
}
14+
$this->bar = $bar;
15+
}
16+
}
17+
18+
public function __construct(int $bar)
19+
{
20+
$this->bar = $bar;
21+
}
22+
}

0 commit comments

Comments
 (0)