@@ -1688,18 +1688,11 @@ public static function intersect(Type ...$types): Type
16881688 && get_class ($ types [$ i ]) === ArrayType::class
16891689 && $ types [$ j ] instanceof CallableType
16901690 ) {
1691- $ existingValueType = $ types [$ i ]->getItemType ();
1692- $ offset0ValueType = self ::intersect ($ existingValueType , new UnionType ([new ClassStringType (), new ObjectWithoutClassType ()]));
1693- $ offset1ValueType = self ::intersect ($ existingValueType , new StringType ());
1694- if ($ offset0ValueType instanceof NeverType || $ offset1ValueType instanceof NeverType) {
1691+ $ narrowed = self ::narrowArrayTypeWithCallable ($ types [$ i ]);
1692+ if ($ narrowed instanceof NeverType) {
16951693 return new NeverType ();
16961694 }
1697- $ types [$ i ] = new ConstantArrayType (
1698- [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
1699- [$ offset0ValueType , $ offset1ValueType ],
1700- [2 ],
1701- isList: TrinaryLogic::createYes (),
1702- );
1695+ $ types [$ i ] = $ narrowed ;
17031696 continue ;
17041697 }
17051698
@@ -1708,18 +1701,11 @@ public static function intersect(Type ...$types): Type
17081701 && get_class ($ types [$ j ]) === ArrayType::class
17091702 && $ types [$ i ] instanceof CallableType
17101703 ) {
1711- $ existingValueType = $ types [$ j ]->getItemType ();
1712- $ offset0ValueType = self ::intersect ($ existingValueType , new UnionType ([new ClassStringType (), new ObjectWithoutClassType ()]));
1713- $ offset1ValueType = self ::intersect ($ existingValueType , new StringType ());
1714- if ($ offset0ValueType instanceof NeverType || $ offset1ValueType instanceof NeverType) {
1704+ $ narrowed = self ::narrowArrayTypeWithCallable ($ types [$ j ]);
1705+ if ($ narrowed instanceof NeverType) {
17151706 return new NeverType ();
17161707 }
1717- $ types [$ j ] = new ConstantArrayType (
1718- [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
1719- [$ offset0ValueType , $ offset1ValueType ],
1720- [2 ],
1721- isList: TrinaryLogic::createYes (),
1722- );
1708+ $ types [$ j ] = $ narrowed ;
17231709 continue ;
17241710 }
17251711
@@ -1841,6 +1827,27 @@ public static function removeTruthy(Type $type): Type
18411827 return self ::remove ($ type , StaticTypeFactory::truthy ());
18421828 }
18431829
1830+ private static function narrowArrayTypeWithCallable (ArrayType $ arrayType ): Type
1831+ {
1832+ if ($ arrayType ->getKeyType ()->isSuperTypeOf (new IntegerType ())->no ()) {
1833+ return new NeverType ();
1834+ }
1835+
1836+ $ existingValueType = $ arrayType ->getItemType ();
1837+ $ offset0ValueType = self ::intersect ($ existingValueType , new UnionType ([new ClassStringType (), new ObjectWithoutClassType ()]));
1838+ $ offset1ValueType = self ::intersect ($ existingValueType , new StringType ());
1839+ if ($ offset0ValueType instanceof NeverType || $ offset1ValueType instanceof NeverType) {
1840+ return new NeverType ();
1841+ }
1842+
1843+ return new ConstantArrayType (
1844+ [new ConstantIntegerType (0 ), new ConstantIntegerType (1 )],
1845+ [$ offset0ValueType , $ offset1ValueType ],
1846+ [2 ],
1847+ isList: TrinaryLogic::createYes (),
1848+ );
1849+ }
1850+
18441851 private static function narrowConstantArrayWithCallable (ConstantArrayType $ constantArray ): Type
18451852 {
18461853 $ keyTypes = $ constantArray ->getKeyTypes ();
0 commit comments