Skip to content

Commit 327ac3e

Browse files
authored
Fix false positives on existing-offsets after assign
1 parent 12a0b4e commit 327ac3e

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

src/Analyser/NodeScopeResolver.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -5496,7 +5496,12 @@ private function processAssignVar(
54965496
}
54975497

54985498
if ($originalVar->dim instanceof Variable || $originalVar->dim instanceof Node\Scalar) {
5499-
if (!$scope->hasExpressionType($originalVar)->yes()) {
5499+
$currentVarType = $scope->getType($originalVar);
5500+
$currentVarNativeType = $scope->getNativeType($originalVar);
5501+
if (
5502+
!$originalValueToWrite->isSuperTypeOf($currentVarType)->yes()
5503+
|| !$originalNativeValueToWrite->isSuperTypeOf($currentVarNativeType)->yes()
5504+
) {
55005505
$scope = $scope->assignExpression(
55015506
$originalVar,
55025507
$originalValueToWrite,

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

+16
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,22 @@ public function testBug12406(): void
856856
$this->analyse([__DIR__ . '/data/bug-12406.php'], []);
857857
}
858858

859+
public function testBug12406b(): void
860+
{
861+
$this->reportPossiblyNonexistentGeneralArrayOffset = true;
862+
863+
$this->analyse([__DIR__ . '/data/bug-12406b.php'], [
864+
[
865+
'Offset int<0, max> might not exist on non-empty-list<array{0: string, 1: non-empty-string, 2: non-falsy-string, 3: numeric-string, 4?: numeric-string, 5?: numeric-string}>.',
866+
22,
867+
],
868+
[
869+
'Offset int<0, max> might not exist on non-empty-list<array{0: string, 1: non-empty-string, 2: non-falsy-string, 3: numeric-string, 4?: numeric-string, 5?: numeric-string}>.',
870+
23,
871+
],
872+
]);
873+
}
874+
859875
public function testBug11679(): void
860876
{
861877
$this->reportPossiblyNonexistentGeneralArrayOffset = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Bug12406_2;
4+
5+
final class Foo
6+
{
7+
8+
public function sayHello(string $s): void
9+
{
10+
$stats = [];
11+
preg_match_all('~
12+
commit[ ][a-z0-9]{40}\\n
13+
Author:\s+(.+)\s+<[^>]+>\\n
14+
AuthorDate:[^\\n]+\\n
15+
Commit:[^\\n]+\\n
16+
CommitDate:[^\\n]+\\n\\n
17+
(\s+(?:[^\n]+\n)+)\n
18+
[ ](\\d+)[ ]files?[ ]changed,(?:[ ](\\d+)[ ]insertions?\\(\\+\\),?)?(?:[ ](\\d+)[ ]deletions?\\(-\\))?
19+
~mx', $s, $matches, PREG_SET_ORDER);
20+
21+
for ($i = 0; $i < count($matches); $i++) {
22+
$author = $matches[$i][1];
23+
$files = (int) $matches[$i][3];
24+
$insertions = (int) ($matches[$i][4] ?? 0);
25+
$deletions = (int) ($matches[$i][5] ?? 0);
26+
27+
$stats[$author]['commits'] = ($stats[$author]['commits'] ?? 0) + 1;
28+
$stats[$author]['files'] = ($stats[$author]['files'] ?? 0) + $files;
29+
$stats[$author]['insertions'] = ($stats[$author]['insertions'] ?? 0) + $insertions;
30+
$stats[$author]['deletions'] = ($stats[$author]['deletions'] ?? 0) + $deletions;
31+
$stats[$author]['diff'] = ($stats[$author]['diff'] ?? 0) + $insertions - $deletions;
32+
}
33+
}
34+
35+
}

0 commit comments

Comments
 (0)