Fix phpstan/phpstan#14336: assign any-int in a loop should turn list into array#5267
Closed
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Closed
Fix phpstan/phpstan#14336: assign any-int in a loop should turn list into array#5267phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Conversation
…arbitrary int offset When assigning to a list-typed array variable with an arbitrary `int` offset (e.g., `$list[$int] = $value`), PHPStan incorrectly preserved the `list` type. Lists require sequential 0-based integer keys, so assigning with an arbitrary `int` (which may include negative values) should degrade the type to `array<int, T>`. Two changes fix the issue: 1. In AssignHandler::produceArrayDimFetchAssignValueToWrite, prevent setExistingOffsetValueType from being used for lists when the offset type is not guaranteed to be non-negative (int<0, max>). 2. In IntersectionType::setOffsetValueType, only re-add AccessoryArrayListType for list-of-arrays when the offset type is null (append) or non-negative.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes phpstan/phpstan#14336
When assigning to a list-typed array with an arbitrary
intoffset (e.g.,$list[$int] = $value), PHPStan incorrectly preserved thelisttype. Since lists require sequential 0-based integer keys and an arbitraryintcan include negative values, the type should be degraded toarray<int, T>.Root cause: Two mechanisms incorrectly preserved lists:
AssignHandler used
setExistingOffsetValueTypefor lists when the parent expression was tracked in scope (e.g., from a previous loop iteration), even when the offset type wasn't guaranteed to be a valid list index. Fix: add a check that only allowssetExistingOffsetValueTypefor lists when the offset is withinint<0, max>range.IntersectionType::setOffsetValueType unconditionally re-added
AccessoryArrayListTypewhen the list's value type was an array, overriding the correct degradation byAccessoryArrayListType::setOffsetValueType. Fix: only re-add the list marker when the offset is null (append) or non-negative.Test expectation updates for 3 existing tests that produced more correct results:
bug-10089:$matrix[$size-1][8] = 3where$size-1can be-1— list correctly degradedbug-13629: assignment with string key now correctly includesstringin key typebug-14245:array_key_existswith untyped$needle— list correctly degraded since$needletype includes fullintrange