119119use PHPStan \Node \VarTagChangedExpressionTypeNode ;
120120use PHPStan \Parser \ArrowFunctionArgVisitor ;
121121use PHPStan \Parser \ClosureArgVisitor ;
122+ use PHPStan \Parser \ImmediatelyInvokedClosureVisitor ;
122123use PHPStan \Parser \Parser ;
123124use PHPStan \Php \PhpVersion ;
124125use PHPStan \PhpDoc \PhpDocInheritanceResolver ;
@@ -4232,7 +4233,7 @@ private function processClosureNode(
42324233 }
42334234
42344235 $ closureScope = $ scope ->enterAnonymousFunction ($ expr , $ callableParameters );
4235- $ closureScope = $ closureScope ->processClosureScope ($ expr , $ scope , null , $ byRefUses );
4236+ $ closureScope = $ closureScope ->processClosureScope ($ scope , null , $ byRefUses );
42364237 $ closureType = $ closureScope ->getAnonymousFunctionReflection ();
42374238 if (!$ closureType instanceof ClosureType) {
42384239 throw new ShouldNotHappenException ();
@@ -4277,6 +4278,7 @@ private function processClosureNode(
42774278
42784279 $ gatheredReturnStatements [] = new ReturnStatement ($ scope , $ node );
42794280 };
4281+
42804282 if (count ($ byRefUses ) === 0 ) {
42814283 $ statementResult = $ this ->processStmtNodes ($ expr , $ expr ->stmts , $ closureScope , $ closureStmtsCallback , StatementContext::createTopLevel ());
42824284 $ nodeCallback (new ClosureReturnStatementsNode (
@@ -4292,6 +4294,7 @@ private function processClosureNode(
42924294 }
42934295
42944296 $ count = 0 ;
4297+ $ closureResultScope = null ;
42954298 do {
42964299 $ prevScope = $ closureScope ;
42974300
@@ -4301,8 +4304,15 @@ private function processClosureNode(
43014304 foreach ($ intermediaryClosureScopeResult ->getExitPoints () as $ exitPoint ) {
43024305 $ intermediaryClosureScope = $ intermediaryClosureScope ->mergeWith ($ exitPoint ->getScope ());
43034306 }
4307+
4308+ if ($ expr ->getAttribute (ImmediatelyInvokedClosureVisitor::ATTRIBUTE_NAME ) === true ) {
4309+ $ closureResultScope = $ intermediaryClosureScope ;
4310+ break ;
4311+ }
4312+
43044313 $ closureScope = $ scope ->enterAnonymousFunction ($ expr , $ callableParameters );
4305- $ closureScope = $ closureScope ->processClosureScope ($ expr , $ intermediaryClosureScope , $ prevScope , $ byRefUses );
4314+ $ closureScope = $ closureScope ->processClosureScope ($ intermediaryClosureScope , $ prevScope , $ byRefUses );
4315+
43064316 if ($ closureScope ->equals ($ prevScope )) {
43074317 break ;
43084318 }
@@ -4312,6 +4322,10 @@ private function processClosureNode(
43124322 $ count ++;
43134323 } while ($ count < self ::LOOP_SCOPE_ITERATIONS );
43144324
4325+ if ($ closureResultScope === null ) {
4326+ $ closureResultScope = $ closureScope ;
4327+ }
4328+
43154329 $ statementResult = $ this ->processStmtNodes ($ expr , $ expr ->stmts , $ closureScope , $ closureStmtsCallback , StatementContext::createTopLevel ());
43164330 $ nodeCallback (new ClosureReturnStatementsNode (
43174331 $ expr ,
@@ -4322,7 +4336,7 @@ private function processClosureNode(
43224336 array_merge ($ statementResult ->getImpurePoints (), $ closureImpurePoints ),
43234337 ), $ closureScope );
43244338
4325- return new ProcessClosureResult ($ scope ->processClosureScope ($ expr , $ closureScope , null , $ byRefUses ), $ statementResult ->getThrowPoints (), $ statementResult ->getImpurePoints (), $ invalidateExpressions );
4339+ return new ProcessClosureResult ($ scope ->processClosureScope ($ closureResultScope , null , $ byRefUses ), $ statementResult ->getThrowPoints (), $ statementResult ->getImpurePoints (), $ invalidateExpressions );
43264340 }
43274341
43284342 /**
0 commit comments