From f4d1d481472b45c56ba2cd49ae98065092217f36 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 24 Apr 2024 09:19:44 +0200 Subject: [PATCH] non-empty-list always has offset 0 --- src/Type/IntersectionType.php | 8 ++++++++ .../data/report-possibly-nonexistent-array-offset.php | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Type/IntersectionType.php b/src/Type/IntersectionType.php index fbec19866d..cc2a3f957c 100644 --- a/src/Type/IntersectionType.php +++ b/src/Type/IntersectionType.php @@ -26,6 +26,7 @@ use PHPStan\Type\Accessory\AccessoryNumericStringType; use PHPStan\Type\Accessory\AccessoryType; use PHPStan\Type\Accessory\NonEmptyArrayType; +use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\Generic\TemplateTypeMap; use PHPStan\Type\Generic\TemplateTypeVariance; @@ -673,6 +674,13 @@ public function isOffsetAccessible(): TrinaryLogic public function hasOffsetValueType(Type $offsetType): TrinaryLogic { + if ($this->isList()->yes() && $this->isIterableAtLeastOnce()->yes()) { + $arrayKeyOffsetType = $offsetType->toArrayKey(); + if ((new ConstantIntegerType(0))->isSuperTypeOf($arrayKeyOffsetType)->yes()) { + return TrinaryLogic::createYes(); + } + } + return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->hasOffsetValueType($offsetType)); } 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 00571bdc1b..fc54d96f00 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 @@ -49,4 +49,12 @@ public function testDimUnion(array $a, string $dim): void echo $a[$dim]; } + /** + * @param non-empty-list $a + */ + public function nonEmpty(array $a): void + { + echo $a[0]; + } + }