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 ();
@@ -4291,6 +4292,24 @@ private function processClosureNode(
42914292 return new ProcessClosureResult ($ scope , $ statementResult ->getThrowPoints (), $ statementResult ->getImpurePoints (), $ invalidateExpressions );
42924293 }
42934294
4295+ if ($ expr ->getAttribute (ImmediatelyInvokedClosureVisitor::ATTRIBUTE_NAME ) === true ) {
4296+ $ intermediaryClosureScopeResult = $ this ->processStmtNodes ($ expr , $ expr ->stmts , $ closureScope , static function (): void {
4297+ }, StatementContext::createTopLevel ());
4298+ $ intermediaryClosureScope = $ intermediaryClosureScopeResult ->getScope ();
4299+
4300+ $ statementResult = $ this ->processStmtNodes ($ expr , $ expr ->stmts , $ closureScope , $ closureStmtsCallback , StatementContext::createTopLevel ());
4301+ $ nodeCallback (new ClosureReturnStatementsNode (
4302+ $ expr ,
4303+ $ gatheredReturnStatements ,
4304+ $ gatheredYieldStatements ,
4305+ $ statementResult ,
4306+ $ executionEnds ,
4307+ array_merge ($ statementResult ->getImpurePoints (), $ closureImpurePoints ),
4308+ ), $ closureScope );
4309+
4310+ return new ProcessClosureResult ($ scope ->processClosureScope ($ intermediaryClosureScope , null , $ byRefUses ), $ statementResult ->getThrowPoints (), $ statementResult ->getImpurePoints (), $ invalidateExpressions );
4311+ }
4312+
42944313 $ count = 0 ;
42954314 do {
42964315 $ prevScope = $ closureScope ;
@@ -4302,7 +4321,7 @@ private function processClosureNode(
43024321 $ intermediaryClosureScope = $ intermediaryClosureScope ->mergeWith ($ exitPoint ->getScope ());
43034322 }
43044323 $ closureScope = $ scope ->enterAnonymousFunction ($ expr , $ callableParameters );
4305- $ closureScope = $ closureScope ->processClosureScope ($ expr , $ intermediaryClosureScope , $ prevScope , $ byRefUses );
4324+ $ closureScope = $ closureScope ->processClosureScope ($ intermediaryClosureScope , $ prevScope , $ byRefUses );
43064325 if ($ closureScope ->equals ($ prevScope )) {
43074326 break ;
43084327 }
@@ -4322,7 +4341,7 @@ private function processClosureNode(
43224341 array_merge ($ statementResult ->getImpurePoints (), $ closureImpurePoints ),
43234342 ), $ closureScope );
43244343
4325- return new ProcessClosureResult ($ scope ->processClosureScope ($ expr , $ closureScope , null , $ byRefUses ), $ statementResult ->getThrowPoints (), $ statementResult ->getImpurePoints (), $ invalidateExpressions );
4344+ return new ProcessClosureResult ($ scope ->processClosureScope ($ closureScope , null , $ byRefUses ), $ statementResult ->getThrowPoints (), $ statementResult ->getImpurePoints (), $ invalidateExpressions );
43264345 }
43274346
43284347 /**
0 commit comments