@@ -5055,7 +5055,7 @@ private function processAssignVar(
50555055 $ valueToWrite = $ scope ->getType ($ assignedExpr );
50565056 $ nativeValueToWrite = $ scope ->getNativeType ($ assignedExpr );
50575057 $ originalValueToWrite = $ valueToWrite ;
5058- $ originalNativeValueToWrite = $ valueToWrite ;
5058+ $ originalNativeValueToWrite = $ nativeValueToWrite ;
50595059
50605060 // 3. eval assigned expr
50615061 $ result = $ processExprCallback ($ scope );
@@ -5076,67 +5076,9 @@ private function processAssignVar(
50765076 }
50775077 $ offsetValueType = $ varType ;
50785078 $ offsetNativeValueType = $ varNativeType ;
5079- $ offsetValueTypeStack = [$ offsetValueType ];
5080- $ offsetValueNativeTypeStack = [$ offsetNativeValueType ];
5081- foreach (array_slice ($ offsetTypes , 0 , -1 ) as $ offsetType ) {
5082- if ($ offsetType === null ) {
5083- $ offsetValueType = new ConstantArrayType ([], []);
5084-
5085- } else {
5086- $ offsetValueType = $ offsetValueType ->getOffsetValueType ($ offsetType );
5087- if ($ offsetValueType instanceof ErrorType) {
5088- $ offsetValueType = new ConstantArrayType ([], []);
5089- }
5090- }
50915079
5092- $ offsetValueTypeStack [] = $ offsetValueType ;
5093- }
5094- foreach (array_slice ($ offsetNativeTypes , 0 , -1 ) as $ offsetNativeType ) {
5095- if ($ offsetNativeType === null ) {
5096- $ offsetNativeValueType = new ConstantArrayType ([], []);
5097-
5098- } else {
5099- $ offsetNativeValueType = $ offsetNativeValueType ->getOffsetValueType ($ offsetNativeType );
5100- if ($ offsetNativeValueType instanceof ErrorType) {
5101- $ offsetNativeValueType = new ConstantArrayType ([], []);
5102- }
5103- }
5104-
5105- $ offsetValueNativeTypeStack [] = $ offsetNativeValueType ;
5106- }
5107-
5108- foreach (array_reverse ($ offsetTypes ) as $ i => $ offsetType ) {
5109- /** @var Type $offsetValueType */
5110- $ offsetValueType = array_pop ($ offsetValueTypeStack );
5111- if (!$ offsetValueType instanceof MixedType) {
5112- $ types = [
5113- new ArrayType (new MixedType (), new MixedType ()),
5114- new ObjectType (ArrayAccess::class),
5115- new NullType (),
5116- ];
5117- if ($ offsetType !== null && $ offsetType ->isInteger ()->yes ()) {
5118- $ types [] = new StringType ();
5119- }
5120- $ offsetValueType = TypeCombinator::intersect ($ offsetValueType , TypeCombinator::union (...$ types ));
5121- }
5122- $ valueToWrite = $ offsetValueType ->setOffsetValueType ($ offsetType , $ valueToWrite , $ i === 0 );
5123- }
5124- foreach (array_reverse ($ offsetNativeTypes ) as $ i => $ offsetNativeType ) {
5125- /** @var Type $offsetNativeValueType */
5126- $ offsetNativeValueType = array_pop ($ offsetValueNativeTypeStack );
5127- if (!$ offsetNativeValueType instanceof MixedType) {
5128- $ types = [
5129- new ArrayType (new MixedType (), new MixedType ()),
5130- new ObjectType (ArrayAccess::class),
5131- new NullType (),
5132- ];
5133- if ($ offsetNativeType !== null && $ offsetNativeType ->isInteger ()->yes ()) {
5134- $ types [] = new StringType ();
5135- }
5136- $ offsetNativeValueType = TypeCombinator::intersect ($ offsetNativeValueType , TypeCombinator::union (...$ types ));
5137- }
5138- $ nativeValueToWrite = $ offsetNativeValueType ->setOffsetValueType ($ offsetNativeType , $ nativeValueToWrite , $ i === 0 );
5139- }
5080+ $ valueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ offsetTypes , $ offsetValueType , $ valueToWrite );
5081+ $ nativeValueToWrite = $ this ->produceArrayDimFetchAssignValueToWrite ($ offsetNativeTypes , $ offsetNativeValueType , $ nativeValueToWrite );
51405082
51415083 if ($ varType ->isArray ()->yes () || !(new ObjectType (ArrayAccess::class))->isSuperTypeOf ($ varType )->yes ()) {
51425084 if ($ var instanceof Variable && is_string ($ var ->name )) {
@@ -5409,6 +5351,46 @@ static function (): void {
54095351 return new ExpressionResult ($ scope , $ hasYield , $ throwPoints , $ impurePoints );
54105352 }
54115353
5354+ /**
5355+ * @param list<Type|null> $offsetTypes
5356+ */
5357+ private function produceArrayDimFetchAssignValueToWrite (array $ offsetTypes , Type $ offsetValueType , Type $ valueToWrite ): Type
5358+ {
5359+ $ offsetValueTypeStack = [$ offsetValueType ];
5360+ foreach (array_slice ($ offsetTypes , 0 , -1 ) as $ offsetType ) {
5361+ if ($ offsetType === null ) {
5362+ $ offsetValueType = new ConstantArrayType ([], []);
5363+
5364+ } else {
5365+ $ offsetValueType = $ offsetValueType ->getOffsetValueType ($ offsetType );
5366+ if ($ offsetValueType instanceof ErrorType) {
5367+ $ offsetValueType = new ConstantArrayType ([], []);
5368+ }
5369+ }
5370+
5371+ $ offsetValueTypeStack [] = $ offsetValueType ;
5372+ }
5373+
5374+ foreach (array_reverse ($ offsetTypes ) as $ i => $ offsetType ) {
5375+ /** @var Type $offsetValueType */
5376+ $ offsetValueType = array_pop ($ offsetValueTypeStack );
5377+ if (!$ offsetValueType instanceof MixedType) {
5378+ $ types = [
5379+ new ArrayType (new MixedType (), new MixedType ()),
5380+ new ObjectType (ArrayAccess::class),
5381+ new NullType (),
5382+ ];
5383+ if ($ offsetType !== null && $ offsetType ->isInteger ()->yes ()) {
5384+ $ types [] = new StringType ();
5385+ }
5386+ $ offsetValueType = TypeCombinator::intersect ($ offsetValueType , TypeCombinator::union (...$ types ));
5387+ }
5388+ $ valueToWrite = $ offsetValueType ->setOffsetValueType ($ offsetType , $ valueToWrite , $ i === 0 );
5389+ }
5390+
5391+ return $ valueToWrite ;
5392+ }
5393+
54125394 private function unwrapAssign (Expr $ expr ): Expr
54135395 {
54145396 if ($ expr instanceof Assign) {
0 commit comments