Skip to content

Commit 0db5fec

Browse files
committed
Understand array properties being overwritten in foreach too
1 parent fea60a0 commit 0db5fec

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ private function processStmtNode(
12841284
&& $stmt->keyVar !== null
12851285
&& $exprType->isArray()->yes()
12861286
&& $exprType->isConstantArray()->no()
1287-
&& !$hasExpr->no()
1287+
&& (!$hasExpr->no() || !$stmt->expr instanceof Variable)
12881288
) {
12891289
$arrayExprDimFetch = new ArrayDimFetch($stmt->expr, $stmt->keyVar);
12901290
$arrayDimFetchLoopTypes = [];
@@ -1332,6 +1332,12 @@ private function processStmtNode(
13321332
$newExprNativeType,
13331333
$hasExpr,
13341334
);
1335+
} else {
1336+
$finalScope = $finalScope->assignExpression(
1337+
$stmt->expr,
1338+
$newExprType,
1339+
$newExprNativeType,
1340+
);
13351341
}
13361342
}
13371343
}

tests/PHPStan/Analyser/nsrt/overwritten-arrays.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,27 @@
33
namespace OverwrittenArrays;
44

55
use function PHPStan\Testing\assertType;
6-
use function rad2deg;
76

87
class Foo
98
{
109

10+
/** @var array<string> */
11+
private array $a;
12+
13+
public function doFooProp1(): void
14+
{
15+
foreach ($this->a as $k => $v) {
16+
if (rand(0, 1)) {
17+
$this->a[$k] = 2;
18+
continue;
19+
}
20+
21+
$this->a[$k] = 1;
22+
}
23+
24+
assertType('array<1|2>', $this->a);
25+
}
26+
1127
/**
1228
* @param array<int, string> $a
1329
*/

0 commit comments

Comments
 (0)