Skip to content

Commit 534b11b

Browse files
committed
fix determination of final scope
1 parent 0fbc568 commit 534b11b

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/Analyser/NodeScopeResolver.php

+29-1
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,35 @@ private function processStmtNode(
795795
), $methodScope);
796796

797797
if ($isConstructor && $this->narrowMethodScopeFromConstructor) {
798-
$scope = $statementResult->getScope()->rememberConstructorScope();
798+
$finalScope = null;
799+
800+
foreach ($executionEnds as $executionEnd) {
801+
if ($executionEnd->getStatementResult()->isAlwaysTerminating()) {
802+
continue;
803+
}
804+
805+
$endScope = $executionEnd->getStatementResult()->getScope();
806+
if ($finalScope === null) {
807+
$finalScope = $endScope;
808+
continue;
809+
}
810+
811+
$finalScope = $finalScope->mergeWith($endScope);
812+
}
813+
814+
foreach ($gatheredReturnStatements as $statement) {
815+
if ($finalScope === null) {
816+
$finalScope = $statement->getScope();
817+
continue;
818+
}
819+
820+
$finalScope = $finalScope->mergeWith($statement->getScope());
821+
}
822+
823+
if ($finalScope !== null) {
824+
$scope = $finalScope->rememberConstructorScope();
825+
}
826+
799827
}
800828
}
801829
} elseif ($stmt instanceof Echo_) {

tests/PHPStan/Analyser/nsrt/remember-readonly-constructor-narrowed.php

+24
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,27 @@ public function doFoo() {
8383
assertType('int', $this->i);
8484
}
8585
}
86+
87+
class HelloWorldReadonlyPropertySometimesThrowing {
88+
private readonly int $i;
89+
90+
public function __construct()
91+
{
92+
if (rand(0,1)) {
93+
$this->i = 4;
94+
95+
return;
96+
} elseif (rand(10,100)) {
97+
$this->i = 10;
98+
return;
99+
} else {
100+
$this->i = 20;
101+
}
102+
103+
throw new \LogicException();
104+
}
105+
106+
public function doFoo() {
107+
assertType('4|10', $this->i);
108+
}
109+
}

0 commit comments

Comments
 (0)