@@ -725,7 +725,41 @@ public function specifyTypesInCondition(
725725
726726 if ($ context ->null ()) {
727727 $ specifiedTypes = $ this ->specifyTypesInCondition ($ scope ->exitFirstLevelStatements (), $ expr ->expr , $ context )->setRootExpr ($ expr );
728+ } else {
729+ $ specifiedTypes = $ this ->specifyTypesInCondition ($ scope ->exitFirstLevelStatements (), $ expr ->var , $ context )->setRootExpr ($ expr );
730+ }
731+
732+ // infer $arr[$key] after $key = array_key_first/last($arr)
733+ if (
734+ $ expr ->expr instanceof FuncCall
735+ && $ expr ->expr ->name instanceof Name
736+ && in_array ($ expr ->expr ->name ->toLowerString (), ['array_key_first ' , 'array_key_last ' ], true )
737+ && count ($ expr ->expr ->getArgs ()) >= 1
738+ ) {
739+ $ arrayArg = $ expr ->expr ->getArgs ()[0 ]->value ;
740+ $ arrayType = $ scope ->getType ($ arrayArg );
728741
742+ if ($ arrayType ->isArray ()->yes ()) {
743+ if ($ context ->true ()) {
744+ $ specifiedTypes = $ specifiedTypes ->unionWith (
745+ $ this ->create ($ arrayArg , new NonEmptyArrayType (), TypeSpecifierContext::createTrue (), $ scope ),
746+ );
747+ $ isNonEmpty = true ;
748+ } else {
749+ $ isNonEmpty = $ arrayType ->isIterableAtLeastOnce ()->yes ();
750+ }
751+
752+ if ($ isNonEmpty ) {
753+ $ dimFetch = new ArrayDimFetch ($ arrayArg , $ expr ->var );
754+
755+ $ specifiedTypes = $ specifiedTypes ->unionWith (
756+ $ this ->create ($ dimFetch , $ arrayType ->getIterableValueType (), TypeSpecifierContext::createTrue (), $ scope ),
757+ );
758+ }
759+ }
760+ }
761+
762+ if ($ context ->null ()) {
729763 // infer $arr[$key] after $key = array_rand($arr)
730764 if (
731765 $ expr ->expr instanceof FuncCall
@@ -755,30 +789,6 @@ public function specifyTypesInCondition(
755789 }
756790 }
757791
758- // infer $arr[$key] after $key = array_key_first/last($arr)
759- if (
760- $ expr ->expr instanceof FuncCall
761- && $ expr ->expr ->name instanceof Name
762- && in_array ($ expr ->expr ->name ->toLowerString (), ['array_key_first ' , 'array_key_last ' ], true )
763- && count ($ expr ->expr ->getArgs ()) >= 1
764- ) {
765- $ arrayArg = $ expr ->expr ->getArgs ()[0 ]->value ;
766- $ arrayType = $ scope ->getType ($ arrayArg );
767- if (
768- $ arrayType ->isArray ()->yes ()
769- && $ arrayType ->isIterableAtLeastOnce ()->yes ()
770- ) {
771- $ dimFetch = new ArrayDimFetch ($ arrayArg , $ expr ->var );
772- $ iterableValueType = $ expr ->expr ->name ->toLowerString () === 'array_key_first '
773- ? $ arrayType ->getIterableValueType ()
774- : $ arrayType ->getIterableValueType ();
775-
776- return $ specifiedTypes ->unionWith (
777- $ this ->create ($ dimFetch , $ iterableValueType , TypeSpecifierContext::createTrue (), $ scope ),
778- );
779- }
780- }
781-
782792 // infer $list[$count] after $count = count($list) - 1
783793 if (
784794 $ expr ->expr instanceof Expr \BinaryOp \Minus
@@ -806,8 +816,6 @@ public function specifyTypesInCondition(
806816 return $ specifiedTypes ;
807817 }
808818
809- $ specifiedTypes = $ this ->specifyTypesInCondition ($ scope ->exitFirstLevelStatements (), $ expr ->var , $ context )->setRootExpr ($ expr );
810-
811819 if ($ context ->true ()) {
812820 // infer $arr[$key] after $key = array_search($needle, $arr)
813821 if (
0 commit comments