File tree Expand file tree Collapse file tree 3 files changed +71
-0
lines changed
tests/PHPStan/Rules/Arrays Expand file tree Collapse file tree 3 files changed +71
-0
lines changed Original file line number Diff line number Diff line change 2828use PHPStan \Type \Accessory \AccessoryNumericStringType ;
2929use PHPStan \Type \Accessory \AccessoryType ;
3030use PHPStan \Type \Accessory \AccessoryUppercaseStringType ;
31+ use PHPStan \Type \Accessory \HasOffsetType ;
32+ use PHPStan \Type \Accessory \HasOffsetValueType ;
3133use PHPStan \Type \Accessory \NonEmptyArrayType ;
3234use PHPStan \Type \Constant \ConstantArrayType ;
3335use PHPStan \Type \Constant \ConstantIntegerType ;
4547use function count ;
4648use function implode ;
4749use function in_array ;
50+ use function is_int ;
4851use function ksort ;
4952use function md5 ;
5053use function sprintf ;
@@ -738,6 +741,21 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
738741 if ((new ConstantIntegerType (0 ))->isSuperTypeOf ($ arrayKeyOffsetType )->yes ()) {
739742 return TrinaryLogic::createYes ();
740743 }
744+
745+ foreach ($ this ->types as $ type ) {
746+ if (!$ type instanceof HasOffsetValueType && !$ type instanceof HasOffsetType) {
747+ continue ;
748+ }
749+
750+ foreach ($ type ->getOffsetType ()->getConstantScalarValues () as $ constantScalarValue ) {
751+ if (!is_int ($ constantScalarValue )) {
752+ continue ;
753+ }
754+ if (IntegerRangeType::fromInterval (0 , $ constantScalarValue )->isSuperTypeOf ($ arrayKeyOffsetType )->yes ()) {
755+ return TrinaryLogic::createYes ();
756+ }
757+ }
758+ }
741759 }
742760
743761 return $ this ->intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->hasOffsetValueType ($ offsetType ));
Original file line number Diff line number Diff line change @@ -900,6 +900,22 @@ public function testNarrowSuperglobals(): void
900900 $ this ->analyse ([__DIR__ . '/data/narrow-superglobal.php ' ], []);
901901 }
902902
903+ public function testBug12605 (): void
904+ {
905+ $ this ->reportPossiblyNonexistentGeneralArrayOffset = true ;
906+
907+ $ this ->analyse ([__DIR__ . '/data/bug-12605.php ' ], [
908+ [
909+ 'Offset 1 might not exist on list<int>. ' ,
910+ 19 ,
911+ ],
912+ [
913+ 'Offset 10 might not exist on non-empty-list<int>. ' ,
914+ 26 ,
915+ ],
916+ ]);
917+ }
918+
903919 public function testBug11602 (): void
904920 {
905921 $ this ->reportPossiblyNonexistentGeneralArrayOffset = true ;
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace Bug12605 ;
4+
5+ /**
6+ * @return list<int>
7+ */
8+ function test (): array
9+ {
10+ return [];
11+ }
12+
13+ function doFoo (): void {
14+ $ test = test ();
15+
16+ if (isset ($ test [3 ])) {
17+ echo $ test [1 ];
18+ }
19+ echo $ test [1 ];
20+ }
21+
22+ function doFooBar (): void {
23+ $ test = test ();
24+
25+ if (isset ($ test [4 ])) {
26+ echo $ test [10 ];
27+ }
28+ }
29+
30+ function doBaz (): void {
31+ $ test = test ();
32+
33+ if (array_key_exists (5 , $ test ) && is_int ($ test [5 ])) {
34+ echo $ test [3 ];
35+ }
36+ }
37+
You can’t perform that action at this time.
0 commit comments