@@ -5706,10 +5706,10 @@ private function processAssignVar(
57065706 $ offsetValueType = $ varType ;
57075707 $ offsetNativeValueType = $ varNativeType ;
57085708
5709- $ valueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetTypes , $ offsetValueType , $ valueToWrite , $ scope );
5709+ [ $ valueToWrite, $ additionalExpressions ] = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetTypes , $ offsetValueType , $ valueToWrite , $ scope );
57105710
57115711 if (!$ offsetValueType ->equals ($ offsetNativeValueType ) || !$ valueToWrite ->equals ($ nativeValueToWrite )) {
5712- $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite , $ scope );
5712+ [ $ nativeValueToWrite, $ additionalNativeExpressions ] = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite , $ scope );
57135713 } else {
57145714 $ rewritten = false ;
57155715 foreach ($ offsetTypes as $ i => $ offsetType ) {
@@ -5728,7 +5728,7 @@ private function processAssignVar(
57285728 continue ;
57295729 }
57305730
5731- $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite , $ scope );
5731+ [ $ nativeValueToWrite] = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite , $ scope );
57325732 $ rewritten = true ;
57335733 break ;
57345734 }
@@ -5781,6 +5781,16 @@ private function processAssignVar(
57815781 }
57825782 }
57835783
5784+ foreach ($ additionalExpressions as $ k => $ additionalExpression ) {
5785+ [$ expr , $ type ] = $ additionalExpression ;
5786+ $ nativeType = $ type ;
5787+ if (isset ($ additionalNativeExpressions [$ k ])) {
5788+ [, $ nativeType ] = $ additionalNativeExpressions [$ k ];
5789+ }
5790+
5791+ $ scope = $ scope ->assignExpression ($ expr , $ type , $ nativeType );
5792+ }
5793+
57845794 if (!$ varType ->isArray ()->yes () && !(new ObjectType (ArrayAccess::class))->isSuperTypeOf ($ varType )->no ()) {
57855795 $ throwPoints = array_merge ($ throwPoints , $ this ->processExprNode (
57865796 $ stmt ,
@@ -6134,9 +6144,13 @@ private function isImplicitArrayCreation(array $dimFetchStack, Scope $scope): Tr
61346144 /**
61356145 * @param list<ArrayDimFetch> $dimFetchStack
61366146 * @param list<Type|null> $offsetTypes
6147+ *
6148+ * @return array{Type, list<array{Expr, Type}>}
61376149 */
6138- private function produceArrayDimFetchAssignValueToWrite (array $ dimFetchStack , array $ offsetTypes , Type $ offsetValueType , Type $ valueToWrite , Scope $ scope ): Type
6150+ private function produceArrayDimFetchAssignValueToWrite (array $ dimFetchStack , array $ offsetTypes , Type $ offsetValueType , Type $ valueToWrite , Scope $ scope ): array
61396151 {
6152+ $ originalValueToWrite = $ valueToWrite ;
6153+
61406154 $ offsetValueTypeStack = [$ offsetValueType ];
61416155 foreach (array_slice ($ offsetTypes , 0 , -1 ) as $ offsetType ) {
61426156 if ($ offsetType === null ) {
@@ -6204,28 +6218,47 @@ private function produceArrayDimFetchAssignValueToWrite(array $dimFetchStack, ar
62046218 continue ;
62056219 }
62066220
6207- if ($ scope ->hasExpressionType ($ arrayDimFetch )->yes ()) { // keep list for $list[$index] assignments
6221+ if (!$ arrayDimFetch ->dim instanceof BinaryOp \Plus) {
6222+ continue ;
6223+ }
6224+
6225+ if ( // keep list for $list[$index + 1] assignments
6226+ $ arrayDimFetch ->dim ->right instanceof Variable
6227+ && $ arrayDimFetch ->dim ->left instanceof Node \Scalar \Int_
6228+ && $ arrayDimFetch ->dim ->left ->value === 1
6229+ && $ scope ->hasExpressionType (new ArrayDimFetch ($ arrayDimFetch ->var , $ arrayDimFetch ->dim ->right ))->yes ()
6230+ ) {
62086231 $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
6209- } elseif ($ arrayDimFetch ->dim instanceof BinaryOp \Plus) {
6210- if ( // keep list for $list[$index + 1] assignments
6211- $ arrayDimFetch ->dim ->right instanceof Variable
6212- && $ arrayDimFetch ->dim ->left instanceof Node \Scalar \Int_
6213- && $ arrayDimFetch ->dim ->left ->value === 1
6214- && $ scope ->hasExpressionType (new ArrayDimFetch ($ arrayDimFetch ->var , $ arrayDimFetch ->dim ->right ))->yes ()
6215- ) {
6216- $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
6217- } elseif ( // keep list for $list[1 + $index] assignments
6218- $ arrayDimFetch ->dim ->left instanceof Variable
6219- && $ arrayDimFetch ->dim ->right instanceof Node \Scalar \Int_
6220- && $ arrayDimFetch ->dim ->right ->value === 1
6221- && $ scope ->hasExpressionType (new ArrayDimFetch ($ arrayDimFetch ->var , $ arrayDimFetch ->dim ->left ))->yes ()
6222- ) {
6223- $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
6224- }
6232+ } elseif ( // keep list for $list[1 + $index] assignments
6233+ $ arrayDimFetch ->dim ->left instanceof Variable
6234+ && $ arrayDimFetch ->dim ->right instanceof Node \Scalar \Int_
6235+ && $ arrayDimFetch ->dim ->right ->value === 1
6236+ && $ scope ->hasExpressionType (new ArrayDimFetch ($ arrayDimFetch ->var , $ arrayDimFetch ->dim ->left ))->yes ()
6237+ ) {
6238+ $ valueToWrite = TypeCombinator::intersect ($ valueToWrite , new AccessoryArrayListType ());
6239+ }
6240+ }
6241+
6242+ $ additionalExpressions = [];
6243+ $ offsetValueType = $ valueToWrite ;
6244+ $ lastDimKey = array_key_last ($ dimFetchStack );
6245+ foreach ($ dimFetchStack as $ key => $ dimFetch ) {
6246+ if ($ dimFetch ->dim === null ) {
6247+ $ additionalExpressions = [];
6248+ break ;
62256249 }
6250+
6251+ if ($ key === $ lastDimKey ) {
6252+ $ offsetValueType = $ originalValueToWrite ;
6253+ } else {
6254+ $ offsetType = $ scope ->getType ($ dimFetch ->dim );
6255+ $ offsetValueType = $ offsetValueType ->getOffsetValueType ($ offsetType );
6256+ }
6257+
6258+ $ additionalExpressions [] = [$ dimFetch , $ offsetValueType ];
62266259 }
62276260
6228- return $ valueToWrite ;
6261+ return [ $ valueToWrite, $ additionalExpressions ] ;
62296262 }
62306263
62316264 private function unwrapAssign (Expr $ expr ): Expr
0 commit comments