@@ -249,6 +249,10 @@ class NodeScopeResolver
249249 /** @var array<string, MutatingScope|null> */
250250 private array $ calledMethodResults = [];
251251
252+ private ?Type $ nonIntKeyOffsetValueType = null ;
253+
254+ private ?Type $ intKeyOffsetValueType = null ;
255+
252256 /**
253257 * @param string[][] $earlyTerminatingMethodCalls className(string) => methods(string[])
254258 * @param array<int, string> $earlyTerminatingFunctionCalls
@@ -6606,15 +6610,22 @@ private function produceArrayDimFetchAssignValueToWrite(array $dimFetchStack, ar
66066610 !$ offsetValueType instanceof MixedType
66076611 && !$ offsetValueType ->isArray ()->yes ()
66086612 ) {
6609- $ types = [
6613+ $ this -> nonIntKeyOffsetValueType ??= TypeCombinator:: union (
66106614 new ArrayType (new MixedType (), new MixedType ()),
66116615 new ObjectType (ArrayAccess::class),
66126616 new NullType (),
6613- ];
6617+ );
6618+
66146619 if ($ offsetType !== null && $ offsetType ->isInteger ()->yes ()) {
6615- $ types [] = new StringType ();
6620+ $ this ->intKeyOffsetValueType ??= TypeCombinator::union (
6621+ $ this ->nonIntKeyOffsetValueType ,
6622+ new StringType (),
6623+ );
6624+
6625+ $ offsetValueType = TypeCombinator::intersect ($ offsetValueType , $ this ->intKeyOffsetValueType );
6626+ } else {
6627+ $ offsetValueType = TypeCombinator::intersect ($ offsetValueType , $ this ->nonIntKeyOffsetValueType );
66166628 }
6617- $ offsetValueType = TypeCombinator::intersect ($ offsetValueType , TypeCombinator::union (...$ types ));
66186629 }
66196630
66206631 $ arrayDimFetch = $ dimFetchStack [$ i ] ?? null ;
0 commit comments