@@ -5450,14 +5450,15 @@ private function processAssignVar(
54505450 $ offsetValueType = $ varType ;
54515451 $ offsetNativeValueType = $ varNativeType ;
54525452
5453- $ valueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ offsetTypes , $ offsetValueType , $ valueToWrite );
5453+ $ valueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetTypes , $ offsetValueType , $ valueToWrite, $ scope );
54545454
54555455 if (!$ offsetValueType ->equals ($ offsetNativeValueType ) || !$ valueToWrite ->equals ($ nativeValueToWrite )) {
5456- $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite );
5456+ $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite, $ scope );
54575457 } else {
54585458 $ rewritten = false ;
54595459 foreach ($ offsetTypes as $ i => $ offsetType ) {
54605460 $ offsetNativeType = $ offsetNativeTypes [$ i ];
5461+
54615462 if ($ offsetType === null ) {
54625463 if ($ offsetNativeType !== null ) {
54635464 throw new ShouldNotHappenException ();
@@ -5471,7 +5472,7 @@ private function processAssignVar(
54715472 continue ;
54725473 }
54735474
5474- $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite );
5475+ $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite, $ scope );
54755476 $ rewritten = true ;
54765477 break ;
54775478 }
@@ -5482,28 +5483,6 @@ private function processAssignVar(
54825483 }
54835484
54845485 if ($ varType ->isArray ()->yes () || !(new ObjectType (ArrayAccess::class))->isSuperTypeOf ($ varType )->yes ()) {
5485- if ($ varType ->isList ()->yes ()) {
5486- if ($ scope ->hasExpressionType ($ originalVar )->yes ()) { // keep list for $list[$index] assignments
5487- $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
5488- } elseif ($ originalVar ->dim instanceof BinaryOp \Plus) {
5489- if ( // keep list for $list[$index + 1] assignments
5490- $ originalVar ->dim ->right instanceof Variable
5491- && $ originalVar ->dim ->left instanceof Node \Scalar \Int_
5492- && $ originalVar ->dim ->left ->value === 1
5493- && $ scope ->hasExpressionType (new ArrayDimFetch ($ originalVar ->var , $ originalVar ->dim ->right ))->yes ()
5494- ) {
5495- $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
5496- } elseif ( // keep list for $list[1 + $index] assignments
5497- $ originalVar ->dim ->left instanceof Variable
5498- && $ originalVar ->dim ->right instanceof Node \Scalar \Int_
5499- && $ originalVar ->dim ->right ->value === 1
5500- && $ scope ->hasExpressionType (new ArrayDimFetch ($ originalVar ->var , $ originalVar ->dim ->left ))->yes ()
5501- ) {
5502- $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
5503- }
5504- }
5505- }
5506-
55075486 if ($ var instanceof Variable && is_string ($ var ->name )) {
55085487 $ nodeCallback (new VariableAssignNode ($ var , $ assignedPropertyExpr , $ isAssignOp ), $ scope );
55095488 $ scope = $ scope ->assignVariable ($ var ->name , $ valueToWrite , $ nativeValueToWrite , TrinaryLogic::createYes ());
@@ -5806,9 +5785,10 @@ static function (): void {
58065785 }
58075786
58085787 /**
5788+ * @param list<ArrayDimFetch> $dimFetchStack
58095789 * @param list<Type|null> $offsetTypes
58105790 */
5811- private function produceArrayDimFetchAssignValueToWrite (array $ offsetTypes , Type $ offsetValueType , Type $ valueToWrite ): Type
5791+ private function produceArrayDimFetchAssignValueToWrite (array $ dimFetchStack , array $ offsetTypes , Type $ offsetValueType , Type $ valueToWrite, Scope $ scope ): Type
58125792 {
58135793 $ offsetValueTypeStack = [$ offsetValueType ];
58145794 foreach (array_slice ($ offsetTypes , 0 , -1 ) as $ offsetType ) {
@@ -5843,6 +5823,31 @@ private function produceArrayDimFetchAssignValueToWrite(array $offsetTypes, Type
58435823 $ offsetValueType = TypeCombinator::intersect ($ offsetValueType , TypeCombinator::union (...$ types ));
58445824 }
58455825 $ valueToWrite = $ offsetValueType ->setOffsetValueType ($ offsetType , $ valueToWrite , $ i === 0 );
5826+
5827+ $ arrayDimFetch = $ dimFetchStack [$ i ] ?? null ;
5828+ if ($ arrayDimFetch === null || !$ offsetValueType ->isList ()->yes ()) {
5829+ continue ;
5830+ }
5831+
5832+ if ($ scope ->hasExpressionType ($ arrayDimFetch )->yes ()) { // keep list for $list[$index] assignments
5833+ $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
5834+ } elseif ($ arrayDimFetch ->dim instanceof BinaryOp \Plus) {
5835+ if ( // keep list for $list[$index + 1] assignments
5836+ $ arrayDimFetch ->dim ->right instanceof Variable
5837+ && $ arrayDimFetch ->dim ->left instanceof Node \Scalar \Int_
5838+ && $ arrayDimFetch ->dim ->left ->value === 1
5839+ && $ scope ->hasExpressionType (new ArrayDimFetch ($ arrayDimFetch ->var , $ arrayDimFetch ->dim ->right ))->yes ()
5840+ ) {
5841+ $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
5842+ } elseif ( // keep list for $list[1 + $index] assignments
5843+ $ arrayDimFetch ->dim ->left instanceof Variable
5844+ && $ arrayDimFetch ->dim ->right instanceof Node \Scalar \Int_
5845+ && $ arrayDimFetch ->dim ->right ->value === 1
5846+ && $ scope ->hasExpressionType (new ArrayDimFetch ($ arrayDimFetch ->var , $ arrayDimFetch ->dim ->left ))->yes ()
5847+ ) {
5848+ $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
5849+ }
5850+ }
58465851 }
58475852
58485853 return $ valueToWrite ;
0 commit comments