Skip to content

Commit b73b7a3

Browse files
committed
Fix non-existent offset when guarding
1 parent 8f9490e commit b73b7a3

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,25 @@ public function specifyTypesInCondition(
291291
if ($specifiedTypes !== null) {
292292
$result = $result->unionWith($specifiedTypes);
293293
}
294+
if (
295+
$context->true()
296+
&& $expr instanceof Node\Expr\BinaryOp\Smaller
297+
&& $argType->isList()->yes()
298+
&& IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($leftType)->yes()
299+
) {
300+
$dimFetch = new ArrayDimFetch(
301+
$expr->right->getArgs()[0]->value,
302+
$expr->left,
303+
);
304+
$result = $result->unionWith(
305+
$this->create(
306+
$dimFetch,
307+
$argType->getIterableValueType(),
308+
TypeSpecifierContext::createTrue(),
309+
$scope,
310+
)->setRootExpr($expr)
311+
);
312+
}
294313

295314
if (
296315
$context->true() && (IntegerRangeType::createAllGreaterThanOrEqualTo(1 - $offset)->isSuperTypeOf($leftType)->yes())

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,10 @@ public static function dataReportPossiblyNonexistentArrayOffset(): iterable
700700
"Offset 'foo' might not exist on array.",
701701
9,
702702
],
703+
[
704+
'Offset int might not exist on list<int>.',
705+
77
706+
],
703707
]];
704708
yield [true, true, [
705709
[
@@ -710,6 +714,10 @@ public static function dataReportPossiblyNonexistentArrayOffset(): iterable
710714
'Offset string might not exist on array{foo: 1}.',
711715
20,
712716
],
717+
[
718+
'Offset int might not exist on list<int>.',
719+
77
720+
],
713721
]];
714722
}
715723

tests/PHPStan/Rules/Arrays/data/report-possibly-nonexistent-array-offset.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,25 @@ public function nonEmpty(array $a): void
5757
echo $a[0];
5858
}
5959

60+
/**
61+
* @param list<int> $array
62+
* @param positive-int $index
63+
*/
64+
public function guard(array $array, int $index) {
65+
if ($index < count($array)) {
66+
return $array[$index];
67+
}
68+
return null;
69+
}
70+
71+
72+
/**
73+
* @param list<int> $array
74+
*/
75+
public function guardNotSafe(array $array, int $index) {
76+
if ($index < count($array)) {
77+
return $array[$index];
78+
}
79+
return null;
80+
}
6081
}

0 commit comments

Comments
 (0)