Skip to content

Commit 0f64ca7

Browse files
committed
Remember assigned offset value on general arrays
1 parent 9e62026 commit 0f64ca7

5 files changed

Lines changed: 44 additions & 3 deletions

File tree

src/Analyser/NodeScopeResolver.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,6 +2651,7 @@ private function processAssignVar(
26512651
}
26522652
} elseif ($var instanceof ArrayDimFetch) {
26532653
$dimExprStack = [];
2654+
$originalVar = $var;
26542655
while ($var instanceof ArrayDimFetch) {
26552656
$dimExprStack[] = $var->dim;
26562657
$var = $var->var;
@@ -2690,6 +2691,7 @@ private function processAssignVar(
26902691
}
26912692

26922693
$valueToWrite = $scope->getType($assignedExpr);
2694+
$originalValueToWrite = $valueToWrite;
26932695

26942696
// 3. eval assigned expr
26952697
$result = $processExprCallback($scope);
@@ -2734,6 +2736,16 @@ private function processAssignVar(
27342736
$valueToWrite
27352737
);
27362738
}
2739+
2740+
if ($originalVar->dim instanceof Variable) {
2741+
$currentVarType = $scope->getType($originalVar);
2742+
if (!$originalValueToWrite->isSuperTypeOf($currentVarType)->yes()) {
2743+
$scope = $scope->assignExpression(
2744+
$originalVar,
2745+
$originalValueToWrite
2746+
);
2747+
}
2748+
}
27372749
}
27382750
} elseif ($var instanceof PropertyFetch) {
27392751
$this->processExprNode($var->var, $scope, $nodeCallback, $context);

src/Type/FileTypeMapper.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ public function getResolvedPhpDoc(
111111
$this->inProcess[$fileName][$phpDocKey] = $resolveCallback();
112112
}
113113

114-
assert($this->inProcess[$fileName][$phpDocKey] instanceof NameScopedPhpDocString);
115114
return $this->createResolvedPhpDocBlock($phpDocKey, $this->inProcess[$fileName][$phpDocKey], $fileName);
116115
}
117116

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10872,6 +10872,11 @@ public function dataInferArrayKey(): array
1087210872
return $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/infer-array-key.php');
1087310873
}
1087410874

10875+
public function dataOffsetValueTypeAfterAssign(): array
10876+
{
10877+
return $this->gatherAssertTypes(__DIR__ . '/data/offset-value-after-assign.php');
10878+
}
10879+
1087510880
/**
1087610881
* @param string $file
1087710882
* @return array<string, mixed[]>
@@ -11108,6 +11113,7 @@ private function gatherAssertTypes(string $file): array
1110811113
* @dataProvider dataBug3024
1110911114
* @dataProvider dataBug3134
1111011115
* @dataProvider dataInferArrayKey
11116+
* @dataProvider dataOffsetValueTypeAfterAssign
1111111117
* @param string $assertType
1111211118
* @param string $file
1111311119
* @param mixed ...$args
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace OffsetValueAfterAssign;
4+
5+
use function PHPStan\Analyser\assertType;
6+
7+
class Foo
8+
{
9+
10+
/**
11+
* @param array<string> $a
12+
*/
13+
public function doFoo(array $a, int $i): void
14+
{
15+
assertType('string', $a[$i]);
16+
17+
$a[$i] = 'foo';
18+
assertType('\'foo\'', $a[$i]);
19+
20+
$i = 1;
21+
assertType('string', $a[$i]);
22+
}
23+
24+
}

tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,10 @@ public function testBug3997(): void
399399
public function testBug1903(): void
400400
{
401401
$this->analyse([__DIR__ . '/data/bug-1903.php'], [
402-
/*[
402+
[
403403
'Method Bug1903\Test::doFoo() should return array but returns int.',
404404
19,
405-
],*/
405+
],
406406
]);
407407
}
408408

0 commit comments

Comments
 (0)