@@ -1202,6 +1202,7 @@ private function processStmtNode(
12021202 $ condResult = $ this ->processExprNode ($ stmt , $ stmt ->expr , $ scope , $ nodeCallback , ExpressionContext::createDeep (), $ context );
12031203 $ throwPoints = $ overridingThrowPoints ?? $ condResult ->getThrowPoints ();
12041204 $ impurePoints = $ condResult ->getImpurePoints ();
1205+ $ exprType = $ scope ->getType ($ stmt ->expr );
12051206 $ scope = $ condResult ->getScope ();
12061207 $ arrayComparisonExpr = new BinaryOp \NotIdentical (
12071208 $ stmt ->expr ,
@@ -1214,6 +1215,18 @@ private function processStmtNode(
12141215 $ originalScope = $ scope ;
12151216 $ bodyScope = $ scope ;
12161217
1218+ $ isIterableAtLeastOnce = $ exprType ->isIterableAtLeastOnce ();
1219+ if (!$ context ->isTopLevel () && $ isIterableAtLeastOnce ->no ()) {
1220+ return new StatementResult (
1221+ $ scope ,
1222+ $ condResult ->hasYield (),
1223+ $ condResult ->isAlwaysTerminating (),
1224+ [],
1225+ $ throwPoints ,
1226+ $ impurePoints ,
1227+ );
1228+ }
1229+
12171230 if ($ context ->isTopLevel ()) {
12181231 $ originalScope = $ this ->polluteScopeWithAlwaysIterableForeach ? $ scope ->filterByTruthyValue ($ arrayComparisonExpr ) : $ scope ;
12191232 $ bodyScope = $ this ->enterForeach ($ originalScope , $ originalScope , $ stmt );
@@ -1250,8 +1263,6 @@ private function processStmtNode(
12501263 $ finalScope = $ breakExitPoint ->getScope ()->mergeWith ($ finalScope );
12511264 }
12521265
1253- $ exprType = $ scope ->getType ($ stmt ->expr );
1254- $ isIterableAtLeastOnce = $ exprType ->isIterableAtLeastOnce ();
12551266 if ($ exprType ->isIterable ()->no () || $ isIterableAtLeastOnce ->maybe ()) {
12561267 $ finalScope = $ finalScope ->mergeWith ($ scope ->filterByTruthyValue (new BooleanOr (
12571268 new BinaryOp \Identical (
0 commit comments