1919use PHPStan \Type \TypeCombinator ;
2020use PHPStan \Type \TypeUtils ;
2121use function array_map ;
22+ use function array_reduce ;
2223use function array_slice ;
2324use function count ;
2425
@@ -55,19 +56,18 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
5556 )->getReturnType ();
5657 } elseif ($ callableIsNull ) {
5758 $ arrayBuilder = ConstantArrayTypeBuilder::createEmpty ();
58- $ argIterableValueTypes = [];
59- $ addNull = false ;
59+ $ argTypes = [];
60+ $ areAllSameSize = true ;
6061 $ expectedSize = null ;
6162 foreach (array_slice ($ functionCall ->getArgs (), 1 ) as $ index => $ arg ) {
62- $ argType = $ scope ->getType ($ arg ->value );
63- $ argIterableValueTypes [$ index ] = $ argType ->getIterableValueType ();
64- if ($ addNull ) {
63+ $ argTypes [$ index ] = $ argType = $ scope ->getType ($ arg ->value );
64+ if (!$ areAllSameSize || $ numArgs === 2 ) {
6565 continue ;
6666 }
6767
6868 $ arraySizes = $ argType ->getArraySize ()->getConstantScalarValues ();
6969 if ($ arraySizes === []) {
70- $ addNull = true ;
70+ $ areAllSameSize = false ;
7171 continue ;
7272 }
7373
@@ -77,12 +77,30 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
7777 continue ;
7878 }
7979
80- $ addNull = true ;
81- break ;
80+ $ areAllSameSize = false ;
81+ continue 2 ;
8282 }
8383 }
8484
85- foreach ($ argIterableValueTypes as $ index => $ offsetValueType ) {
85+ if (!$ areAllSameSize ) {
86+ $ firstArr = $ functionCall ->getArgs ()[1 ]->value ;
87+ $ identities = [];
88+ foreach (array_slice ($ functionCall ->getArgs (), 2 ) as $ arg ) {
89+ $ identities [] = new Node \Expr \BinaryOp \Identical ($ firstArr , $ arg ->value );
90+ }
91+
92+ $ and = array_reduce (
93+ $ identities ,
94+ static fn (Node \Expr $ a , Node \Expr $ b ) => new Node \Expr \BinaryOp \BooleanAnd ($ a , $ b ),
95+ new Node \Expr \ConstFetch (new Node \Name ('true ' )),
96+ );
97+ $ areAllSameSize = $ scope ->getType ($ and )->isTrue ()->yes ();
98+ }
99+
100+ $ addNull = !$ areAllSameSize ;
101+
102+ foreach ($ argTypes as $ index => $ argType ) {
103+ $ offsetValueType = $ argType ->getIterableValueType ();
86104 if ($ addNull ) {
87105 $ offsetValueType = TypeCombinator::addNull ($ offsetValueType );
88106 }
0 commit comments