@@ -780,8 +780,10 @@ private static function optimizeConstantArrays(array $types): array
780780 }
781781
782782 $ results = [];
783+ $ eachIsOversized = true ;
783784 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 {
785787 if (!$ type instanceof ConstantArrayType) {
786788 return $ traverse ($ type );
787789 }
@@ -790,6 +792,8 @@ private static function optimizeConstantArrays(array $types): array
790792 return $ type ;
791793 }
792794
795+ $ isOversized = true ;
796+
793797 $ isList = true ;
794798 $ valueTypes = [];
795799 $ keyTypes = [];
@@ -808,8 +812,8 @@ private static function optimizeConstantArrays(array $types): array
808812 $ keyTypes [$ generalizedKeyType ->describe (VerbosityLevel::precise ())] = $ generalizedKeyType ;
809813
810814 $ 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 ) {
813817 return TypeCombinator::intersect ($ type , new OversizedArrayType ());
814818 }
815819
@@ -828,6 +832,36 @@ private static function optimizeConstantArrays(array $types): array
828832
829833 return TypeCombinator::intersect ($ arrayType , new NonEmptyArrayType (), new OversizedArrayType ());
830834 });
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 ())];
831865 }
832866
833867 return $ results ;
0 commit comments