@@ -1087,10 +1087,7 @@ private function specifyTypesForCountFuncCall(
10871087 if (
10881088 $ sizeType instanceof ConstantIntegerType
10891089 && $ sizeType ->getValue () < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1090- && (
1091- $ isList ->yes ()
1092- || $ isConstantArray ->yes () && $ arrayType ->getKeyType ()->isSuperTypeOf (IntegerRangeType::fromInterval (0 , $ sizeType ->getValue () - 1 ))->yes ()
1093- )
1090+ && $ arrayType ->getKeyType ()->isSuperTypeOf (IntegerRangeType::fromInterval (0 , $ sizeType ->getValue () - 1 ))->yes ()
10941091 ) {
10951092 // turn optional offsets non-optional
10961093 $ valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty ();
@@ -1105,21 +1102,23 @@ private function specifyTypesForCountFuncCall(
11051102 if (
11061103 $ sizeType instanceof IntegerRangeType
11071104 && $ sizeType ->getMin () !== null
1108- && (
1109- $ isList ->yes ()
1110- || $ isConstantArray ->yes () && $ arrayType ->getKeyType ()->isSuperTypeOf (IntegerRangeType::fromInterval (0 , $ sizeType ->getMin () - 1 ))->yes ()
1111- )
1105+ && $ sizeType ->getMin () < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT
1106+ && $ arrayType ->getKeyType ()->isSuperTypeOf (IntegerRangeType::fromInterval (0 , ($ sizeType ->getMax () ?? $ sizeType ->getMin ()) - 1 ))->yes ()
11121107 ) {
1108+ $ builderData = [];
11131109 // turn optional offsets non-optional
1114- $ valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty ();
11151110 for ($ i = 0 ; $ i < $ sizeType ->getMin (); $ i ++) {
11161111 $ offsetType = new ConstantIntegerType ($ i );
1117- $ valueTypesBuilder -> setOffsetValueType ( $ offsetType , $ arrayType ->getOffsetValueType ($ offsetType )) ;
1112+ $ builderData [] = [ $ offsetType , $ arrayType ->getOffsetValueType ($ offsetType ), false ] ;
11181113 }
11191114 if ($ sizeType ->getMax () !== null ) {
1115+ if ($ sizeType ->getMax () - $ sizeType ->getMin () > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT ) {
1116+ $ resultTypes [] = $ arrayType ;
1117+ continue ;
1118+ }
11201119 for ($ i = $ sizeType ->getMin (); $ i < $ sizeType ->getMax (); $ i ++) {
11211120 $ offsetType = new ConstantIntegerType ($ i );
1122- $ valueTypesBuilder -> setOffsetValueType ( $ offsetType , $ arrayType ->getOffsetValueType ($ offsetType ), true ) ;
1121+ $ builderData [] = [ $ offsetType , $ arrayType ->getOffsetValueType ($ offsetType ), true ] ;
11231122 }
11241123 } elseif ($ arrayType ->isConstantArray ()->yes ()) {
11251124 for ($ i = $ sizeType ->getMin ();; $ i ++) {
@@ -1128,14 +1127,24 @@ private function specifyTypesForCountFuncCall(
11281127 if ($ hasOffset ->no ()) {
11291128 break ;
11301129 }
1131- $ valueTypesBuilder -> setOffsetValueType ( $ offsetType , $ arrayType ->getOffsetValueType ($ offsetType ), !$ hasOffset ->yes ()) ;
1130+ $ builderData [] = [ $ offsetType , $ arrayType ->getOffsetValueType ($ offsetType ), !$ hasOffset ->yes ()] ;
11321131 }
11331132 } else {
11341133 $ resultTypes [] = TypeCombinator::intersect ($ arrayType , new NonEmptyArrayType ());
11351134 continue ;
11361135 }
11371136
1138- $ resultTypes [] = $ valueTypesBuilder ->getArray ();
1137+ if (count ($ builderData ) > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT ) {
1138+ $ resultTypes [] = $ arrayType ;
1139+ continue ;
1140+ }
1141+
1142+ $ builder = ConstantArrayTypeBuilder::createEmpty ();
1143+ foreach ($ builderData as [$ offsetType , $ valueType , $ optional ]) {
1144+ $ builder ->setOffsetValueType ($ offsetType , $ valueType , $ optional );
1145+ }
1146+
1147+ $ resultTypes [] = $ builder ->getArray ();
11391148 continue ;
11401149 }
11411150
0 commit comments