@@ -780,8 +780,10 @@ private static function optimizeConstantArrays(array $types): array
780
780
}
781
781
782
782
$ results = [];
783
+ $ eachIsOversized = true ;
783
784
foreach ($ types as $ type ) {
784
- $ results [] = TypeTraverser::map ($ type , static function (Type $ type , callable $ traverse ): Type {
785
+ $ isOversized = false ;
786
+ $ result = TypeTraverser::map ($ type , static function (Type $ type , callable $ traverse ) use (&$ isOversized ): Type {
785
787
if (!$ type instanceof ConstantArrayType) {
786
788
return $ traverse ($ type );
787
789
}
@@ -790,6 +792,8 @@ private static function optimizeConstantArrays(array $types): array
790
792
return $ type ;
791
793
}
792
794
795
+ $ isOversized = true ;
796
+
793
797
$ isList = true ;
794
798
$ valueTypes = [];
795
799
$ keyTypes = [];
@@ -808,8 +812,8 @@ private static function optimizeConstantArrays(array $types): array
808
812
$ keyTypes [$ generalizedKeyType ->describe (VerbosityLevel::precise ())] = $ generalizedKeyType ;
809
813
810
814
$ innerValueType = $ type ->getValueTypes ()[$ i ];
811
- $ generalizedValueType = TypeTraverser::map ($ innerValueType , static function (Type $ type, callable $ innerTraverse ) use ($ traverse ): Type {
812
- if ($ type instanceof ArrayType) {
815
+ $ generalizedValueType = TypeTraverser::map ($ innerValueType , static function (Type $ type ) use ($ traverse ): Type {
816
+ if ($ type instanceof ArrayType || $ type instanceof ConstantArrayType ) {
813
817
return TypeCombinator::intersect ($ type , new OversizedArrayType ());
814
818
}
815
819
@@ -828,6 +832,36 @@ private static function optimizeConstantArrays(array $types): array
828
832
829
833
return TypeCombinator::intersect ($ arrayType , new NonEmptyArrayType (), new OversizedArrayType ());
830
834
});
835
+
836
+ if (!$ isOversized ) {
837
+ $ eachIsOversized = false ;
838
+ }
839
+
840
+ $ results [] = $ result ;
841
+ }
842
+
843
+ if ($ eachIsOversized ) {
844
+ $ eachIsList = true ;
845
+ $ keyTypes = [];
846
+ $ valueTypes = [];
847
+ foreach ($ results as $ result ) {
848
+ $ keyTypes [] = $ result ->getIterableKeyType ();
849
+ $ valueTypes [] = $ result ->getLastIterableValueType ();
850
+ if ($ result ->isList ()->yes ()) {
851
+ continue ;
852
+ }
853
+ $ eachIsList = false ;
854
+ }
855
+
856
+ $ keyType = self ::union (...array_values ($ keyTypes ));
857
+ $ valueType = self ::union (...array_values ($ valueTypes ));
858
+
859
+ $ arrayType = new ArrayType ($ keyType , $ valueType );
860
+ if ($ eachIsList ) {
861
+ $ arrayType = self ::intersect ($ arrayType , new AccessoryArrayListType ());
862
+ }
863
+
864
+ return [self ::intersect ($ arrayType , new NonEmptyArrayType (), new OversizedArrayType ())];
831
865
}
832
866
833
867
return $ results ;
0 commit comments