@@ -1325,12 +1325,17 @@ private function resolveType(Expr $node): Type
13251325 } else {
13261326 $ closureScope = $ this ->enterAnonymousFunctionWithoutReflection ($ node );
13271327 $ closureReturnStatements = [];
1328- $ this ->nodeScopeResolver ->processStmtNodes ($ node , $ node ->stmts , $ closureScope , static function (Node $ node , Scope $ scope ) use (&$ closureReturnStatements ): void {
1329- if (!$ node instanceof Node \Stmt \Return_) {
1328+ $ closureYieldStatements = [];
1329+ $ this ->nodeScopeResolver ->processStmtNodes ($ node , $ node ->stmts , $ closureScope , static function (Node $ node , Scope $ scope ) use (&$ closureReturnStatements , &$ closureYieldStatements ): void {
1330+ if ($ node instanceof Node \Stmt \Return_) {
1331+ $ closureReturnStatements [] = [$ node , $ scope ];
1332+ }
1333+
1334+ if (!$ node instanceof Expr \Yield_ && !$ node instanceof Expr \YieldFrom) {
13301335 return ;
13311336 }
13321337
1333- $ closureReturnStatements [] = [$ node , $ scope ];
1338+ $ closureYieldStatements [] = [$ node , $ scope ];
13341339 });
13351340
13361341 $ returnTypes = [];
@@ -1353,7 +1358,40 @@ private function resolveType(Expr $node): Type
13531358 $ returnType = TypeCombinator::union (...$ returnTypes );
13541359 }
13551360
1356- $ returnType = TypehintHelper::decideType ($ this ->getFunctionType ($ node ->returnType , false , false ), $ returnType );
1361+ if (count ($ closureYieldStatements ) > 0 ) {
1362+ $ keyTypes = [];
1363+ $ valueTypes = [];
1364+ foreach ($ closureYieldStatements as [$ yieldNode , $ yieldScope ]) {
1365+ if ($ yieldNode instanceof Expr \Yield_) {
1366+ if ($ yieldNode ->key === null ) {
1367+ $ keyTypes [] = new IntegerType ();
1368+ } else {
1369+ $ keyTypes [] = $ yieldScope ->getType ($ yieldNode ->key );
1370+ }
1371+
1372+ if ($ yieldNode ->value === null ) {
1373+ $ valueTypes [] = new NullType ();
1374+ } else {
1375+ $ valueTypes [] = $ yieldScope ->getType ($ yieldNode ->value );
1376+ }
1377+
1378+ continue ;
1379+ }
1380+
1381+ $ yieldFromType = $ yieldScope ->getType ($ yieldNode ->expr );
1382+ $ keyTypes [] = $ yieldFromType ->getIterableKeyType ();
1383+ $ valueTypes [] = $ yieldFromType ->getIterableValueType ();
1384+ }
1385+
1386+ $ returnType = new GenericObjectType (\Generator::class, [
1387+ TypeCombinator::union (...$ keyTypes ),
1388+ TypeCombinator::union (...$ valueTypes ),
1389+ new MixedType (),
1390+ $ returnType ,
1391+ ]);
1392+ } else {
1393+ $ returnType = TypehintHelper::decideType ($ this ->getFunctionType ($ node ->returnType , false , false ), $ returnType );
1394+ }
13571395 }
13581396
13591397 return new ClosureType (
0 commit comments