@@ -5706,10 +5706,10 @@ private function processAssignVar(
5706
5706
$ offsetValueType = $ varType ;
5707
5707
$ offsetNativeValueType = $ varNativeType ;
5708
5708
5709
- $ valueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetTypes , $ offsetValueType , $ valueToWrite , $ scope );
5709
+ [ $ valueToWrite, $ additionalExpressions ] = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetTypes , $ offsetValueType , $ valueToWrite , $ scope );
5710
5710
5711
5711
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 );
5713
5713
} else {
5714
5714
$ rewritten = false ;
5715
5715
foreach ($ offsetTypes as $ i => $ offsetType ) {
@@ -5728,7 +5728,7 @@ private function processAssignVar(
5728
5728
continue ;
5729
5729
}
5730
5730
5731
- $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite , $ scope );
5731
+ [ $ nativeValueToWrite] = $ this ->produceArrayDimFetchAssignValueToWrite ($ dimFetchStack , $ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite , $ scope );
5732
5732
$ rewritten = true ;
5733
5733
break ;
5734
5734
}
@@ -5781,6 +5781,16 @@ private function processAssignVar(
5781
5781
}
5782
5782
}
5783
5783
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
+
5784
5794
if (!$ varType ->isArray ()->yes () && !(new ObjectType (ArrayAccess::class))->isSuperTypeOf ($ varType )->no ()) {
5785
5795
$ throwPoints = array_merge ($ throwPoints , $ this ->processExprNode (
5786
5796
$ stmt ,
@@ -6134,9 +6144,13 @@ private function isImplicitArrayCreation(array $dimFetchStack, Scope $scope): Tr
6134
6144
/**
6135
6145
* @param list<ArrayDimFetch> $dimFetchStack
6136
6146
* @param list<Type|null> $offsetTypes
6147
+ *
6148
+ * @return array{Type, list<array{Expr, Type}>}
6137
6149
*/
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
6139
6151
{
6152
+ $ originalValueToWrite = $ valueToWrite ;
6153
+
6140
6154
$ offsetValueTypeStack = [$ offsetValueType ];
6141
6155
foreach (array_slice ($ offsetTypes , 0 , -1 ) as $ offsetType ) {
6142
6156
if ($ offsetType === null ) {
@@ -6204,28 +6218,47 @@ private function produceArrayDimFetchAssignValueToWrite(array $dimFetchStack, ar
6204
6218
continue ;
6205
6219
}
6206
6220
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
+ ) {
6208
6231
$ 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 ;
6225
6249
}
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 ];
6226
6259
}
6227
6260
6228
- return $ valueToWrite ;
6261
+ return [ $ valueToWrite, $ additionalExpressions ] ;
6229
6262
}
6230
6263
6231
6264
private function unwrapAssign (Expr $ expr ): Expr
0 commit comments