@@ -1403,6 +1403,45 @@ private function specifyTypesForCountFuncCall(
14031403 $ resultTypes [] = TypeCombinator::intersect ($ arrayType , new NonEmptyArrayType ());
14041404 }
14051405
1406+ if ($ context ->truthy () && $ isConstantArray ->yes () && $ isList ->yes ()) {
1407+ $ hasOptionalKeys = false ;
1408+ foreach ($ type ->getConstantArrays () as $ arrayType ) {
1409+ if ($ arrayType ->getOptionalKeys () !== []) {
1410+ $ hasOptionalKeys = true ;
1411+ break ;
1412+ }
1413+ }
1414+
1415+ if (!$ hasOptionalKeys ) {
1416+ $ argExpr = $ countFuncCall ->getArgs ()[0 ]->value ;
1417+ $ argExprString = $ this ->exprPrinter ->printExpr ($ argExpr );
1418+
1419+ $ sizeMin = null ;
1420+ $ sizeMax = null ;
1421+ if ($ sizeType instanceof ConstantIntegerType) {
1422+ $ sizeMin = $ sizeType ->getValue ();
1423+ $ sizeMax = $ sizeType ->getValue ();
1424+ } elseif ($ sizeType instanceof IntegerRangeType) {
1425+ $ sizeMin = $ sizeType ->getMin ();
1426+ $ sizeMax = $ sizeType ->getMax ();
1427+ }
1428+
1429+ $ sureTypes = [];
1430+ $ sureNotTypes = [];
1431+
1432+ if ($ sizeMin !== null && $ sizeMin >= 1 ) {
1433+ $ sureTypes [$ argExprString ] = [$ argExpr , new HasOffsetValueType (new ConstantIntegerType ($ sizeMin - 1 ), new MixedType ())];
1434+ }
1435+ if ($ sizeMax !== null ) {
1436+ $ sureNotTypes [$ argExprString ] = [$ argExpr , new HasOffsetValueType (new ConstantIntegerType ($ sizeMax ), new MixedType ())];
1437+ }
1438+
1439+ if ($ sureTypes !== [] || $ sureNotTypes !== []) {
1440+ return (new SpecifiedTypes ($ sureTypes , $ sureNotTypes ))->setRootExpr ($ rootExpr );
1441+ }
1442+ }
1443+ }
1444+
14061445 return $ this ->create ($ countFuncCall ->getArgs ()[0 ]->value , TypeCombinator::union (...$ resultTypes ), $ context , $ scope )->setRootExpr ($ rootExpr );
14071446 }
14081447
0 commit comments