From 111c48affe38f2f583090f638b736f41f5d8f3ce Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 13 Aug 2026 11:10:00 +0200 Subject: [PATCH] Pin the iteratee's entry types in the by-ref foreach intertwined expression The SetExistingOffsetValueTypeExpr subject re-priced the raw iteratee through Scope::getType() on every ask of the intertwined node. The iteratee's phpdoc and native types at loop entry are already threaded into enterForeach(), and the sibling key expression already pins them the same way; the outer IntertwinedVariableByReferenceWithExpr keeps carrying the raw iteratee, so invalidation on reassignment is unchanged. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01DaBZjgksga4c5s6Q9FniY7 --- src/Analyser/MutatingScope.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index c08258e4f32..a1d20804cc2 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2650,7 +2650,7 @@ public function enterForeach(self $originalScope, Expr $iteratee, Type $iteratee if ($valueByRef && $iterateeType->isArray()->yes() && $iterateeType->isConstantArray()->no()) { $scope = $scope->assignExpression( new IntertwinedVariableByReferenceWithExpr($valueName, $iteratee, new SetExistingOffsetValueTypeExpr( - $iteratee, + new NativeTypeExpr($iterateeType, $nativeIterateeType), new NativeTypeExpr( $originalScope->getIterableKeyType($iterateeType), $originalScope->getIterableKeyType($nativeIterateeType),