diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 6698a8a800..5f637a4e75 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -291,6 +291,25 @@ public function specifyTypesInCondition( if ($specifiedTypes !== null) { $result = $result->unionWith($specifiedTypes); } + if ( + $context->true() + && $expr instanceof Node\Expr\BinaryOp\Smaller + && $argType->isList()->yes() + && IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($leftType)->yes() + ) { + $dimFetch = new ArrayDimFetch( + $expr->right->getArgs()[0]->value, + $expr->left, + ); + $result = $result->unionWith( + $this->create( + $dimFetch, + $argType->getIterableValueType(), + TypeSpecifierContext::createTrue(), + $scope, + ) + ); + } if ( $context->true() && (IntegerRangeType::createAllGreaterThanOrEqualTo(1 - $offset)->isSuperTypeOf($leftType)->yes()) diff --git a/tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php b/tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php index 879c86f791..1b4658fa50 100644 --- a/tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php +++ b/tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php @@ -700,6 +700,10 @@ public static function dataReportPossiblyNonexistentArrayOffset(): iterable "Offset 'foo' might not exist on array.", 9, ], + [ + 'Offset int might not exist on list.', + 77 + ], ]]; yield [true, true, [ [ @@ -710,6 +714,10 @@ public static function dataReportPossiblyNonexistentArrayOffset(): iterable 'Offset string might not exist on array{foo: 1}.', 20, ], + [ + 'Offset int might not exist on list.', + 77 + ], ]]; } diff --git a/tests/PHPStan/Rules/Arrays/data/report-possibly-nonexistent-array-offset.php b/tests/PHPStan/Rules/Arrays/data/report-possibly-nonexistent-array-offset.php index fc54d96f00..967d913cea 100644 --- a/tests/PHPStan/Rules/Arrays/data/report-possibly-nonexistent-array-offset.php +++ b/tests/PHPStan/Rules/Arrays/data/report-possibly-nonexistent-array-offset.php @@ -57,4 +57,25 @@ public function nonEmpty(array $a): void echo $a[0]; } + /** + * @param list $array + * @param positive-int $index + */ + public function guard(array $array, int $index) { + if ($index < count($array)) { + return $array[$index]; + } + return null; + } + + + /** + * @param list $array + */ + public function guardNotSafe(array $array, int $index) { + if ($index < count($array)) { + return $array[$index]; + } + return null; + } }