-
Notifications
You must be signed in to change notification settings - Fork 554
Fix #14129: Support integer range keys in constant arrays #4951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
+317
−1
Closed
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
038222b
Support integer range keys in constant arrays
staabm efbc5fd
Add regression test for #9907
phpstan-bot a243073
Add regression test for #7978
phpstan-bot 5dc4e18
Add regression test for #2294
phpstan-bot a68b970
Add regression test for #13000
phpstan-bot aa336f6
Add regression test for #13759
phpstan-bot 3e19a98
Address review comments
phpstan-bot 56c981c
Add regression test for #14129
phpstan-bot a4d6589
Fix CI failures [claude-ci-fix]
phpstan-bot 4277198
Address review comments
phpstan-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace Bug13000; | ||
|
|
||
| use function PHPStan\Testing\assertType; | ||
|
|
||
| function (): void { | ||
| $r = []; | ||
| foreach (['a' => '1', 'b' => '2'] as $key => $val) { | ||
| $r[$key] = $val; | ||
| } | ||
| assertType("array{a?: '1'|'2', b?: '1'|'2'}", $r); | ||
| }; |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?php declare(strict_types = 1); // lint >= 8.0 | ||
|
|
||
| namespace Bug13759; | ||
|
|
||
| use function PHPStan\Testing\assertType; | ||
|
|
||
| class Test | ||
| { | ||
| public function scenario(): void | ||
| { | ||
| $ints = []; | ||
| foreach (['a', 'b'] as $key) { | ||
| $ints[$key] = 1; | ||
| } | ||
| $ints['c'] = 1; | ||
|
|
||
| assertType("array{a?: 1, b?: 1, c: 1}", $ints); | ||
|
|
||
| foreach (['a'] as $key) { | ||
| $ints[$key] = $this->intToSomething($ints[$key]); | ||
| } | ||
|
|
||
| assertType("array{a: float|string, b?: 1, c: 1}", $ints); | ||
| } | ||
|
|
||
| /** | ||
| * @return string|float | ||
| */ | ||
| protected function intToSomething(int $int): string|float { | ||
| return mt_rand(1, 2) ? (string)$int : (float)$int; | ||
| } | ||
| } |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace Bug2294; | ||
|
|
||
| use function PHPStan\Testing\assertType; | ||
|
|
||
| function (): void { | ||
| $entries = ['A' => null, 'B' => null]; | ||
|
|
||
| $entries2 = []; | ||
| foreach($entries as $key => $value) { | ||
| $entries2[$key] = ['a' => 1, 'b' => 2]; | ||
| } | ||
| assertType("array{A?: array{a: 1, b: 2}, B?: array{a: 1, b: 2}}", $entries2); | ||
| }; |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace Bug9907; | ||
|
|
||
| use function PHPStan\Testing\assertType; | ||
|
|
||
| class HelloWorld | ||
| { | ||
| /** | ||
| * @param 'foo'|'bar' $key | ||
| */ | ||
| public function sayHello(string $key): void | ||
| { | ||
| $a = []; | ||
| $a['id'] = null; | ||
| $a[$key] = 'string'; | ||
|
|
||
| assertType("array{id: null, bar: 'string'}|array{id: null, foo: 'string'}", $a); | ||
| } | ||
| } |
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
70 changes: 70 additions & 0 deletions
70
tests/PHPStan/Analyser/nsrt/set-constant-union-offset-on-constant-array.php
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| <?php | ||
|
|
||
| namespace SetConstantUnionOffsetOnConstantArray; | ||
|
|
||
| use function PHPStan\Testing\assertType; | ||
|
|
||
| class Foo | ||
| { | ||
|
|
||
| /** | ||
| * @param array{foo: int} $a | ||
| */ | ||
| public function doFoo(array $a): void | ||
| { | ||
| $k = rand(0, 1) ? 'a' : 'b'; | ||
| $a[$k] = 256; | ||
| assertType('array{foo: int, a: 256}|array{foo: int, b: 256}', $a); | ||
| } | ||
|
|
||
| /** | ||
| * @param array{foo: int} $a | ||
| * @param int<1,5> $intRange | ||
| */ | ||
| public function doBar(array $a, $intRange): void | ||
| { | ||
| $a[$intRange] = 256; | ||
| assertType('array{foo: int, 1: 256}|array{foo: int, 2: 256}|array{foo: int, 3: 256}|array{foo: int, 4: 256}|array{foo: int, 5: 256}', $a); | ||
| } | ||
|
|
||
| /** | ||
| * @param array{foo: int} $a | ||
| * @param int<0, max> $intRange | ||
| */ | ||
| public function doInfiniteRange(array $a, $intRange): void | ||
| { | ||
| $a[$intRange] = 256; | ||
| assertType('non-empty-array<\'foo\'|int<0, max>, int>', $a); | ||
| } | ||
staabm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * @param array{foo: int} $a | ||
| * @param int<0, 5>|int<10, 15> $intRange | ||
| */ | ||
| public function doUnionOfRanges(array $a, $intRange): void | ||
| { | ||
| $a[$intRange] = 256; | ||
| assertType('non-empty-array<\'foo\'|int<0, 5>|int<10, 15>, int>', $a); | ||
| } | ||
|
|
||
| /** | ||
| * @param array{foo: int} $a | ||
| * @param int<0, 3>|int<2, 4> $intRange | ||
| */ | ||
| public function doOverlappingRanges(array $a, $intRange): void | ||
| { | ||
| $a[$intRange] = 256; | ||
| assertType('array{foo: int, 0: 256}|array{foo: int, 1: 256}|array{foo: int, 2: 256}|array{foo: int, 3: 256}|array{foo: int, 4: 256}', $a); | ||
| } | ||
|
|
||
| /** | ||
| * @param array{0: 'a', 1: 'b'} $a | ||
| * @param int<0,1> $intRange | ||
| */ | ||
| public function doExistingKeys(array $a, $intRange): void | ||
| { | ||
| $a[$intRange] = 'c'; | ||
| assertType("array{'a'|'c', 'b'|'c'}", $a); | ||
| } | ||
|
|
||
| } | ||
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <?php declare(strict_types = 1); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this bug should be covered via |
||
|
|
||
| namespace Bug7978; | ||
|
|
||
| class Test { | ||
|
|
||
| const FIELD_SETS = [ | ||
| 'basic' => ['username', 'password'], | ||
| 'headers' => ['app_id', 'app_key'], | ||
| ]; | ||
|
|
||
| /** | ||
| * @param array<string, string> $credentials | ||
| */ | ||
| public function acceptCredentials(array $credentials): void | ||
| { | ||
| } | ||
|
|
||
| public function doSomething(): void | ||
| { | ||
| foreach (self::FIELD_SETS as $type => $fields) { | ||
| $credentials = []; | ||
| foreach ($fields as $field) { | ||
| $credentials[$field] = 'fake'; | ||
| } | ||
| $this->acceptCredentials($credentials); | ||
| } | ||
| } | ||
| } | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <?php declare(strict_types = 1); | ||
|
|
||
| namespace Bug9907Rule; | ||
|
|
||
| class Demo | ||
| { | ||
| /** | ||
| * @phpstan-param array{street: string, city: string} $address1 | ||
| * @phpstan-param array{street: string, city: string} $address2 | ||
| * | ||
| * @phpstan-return array{ | ||
| * street?: array{change_to: string}, | ||
| * city?: array{change_to: string}, | ||
| * variation_count?: int<1, max> | ||
| * } | ||
| */ | ||
| public function diffAddresses(array $address1, array $address2): array | ||
| { | ||
| $addressDifference = array_diff_assoc($address1, $address2); | ||
| $differenceDetails = []; | ||
|
|
||
| foreach ($addressDifference as $name => $differenceValue) { | ||
| $differenceDetails[$name] = [ | ||
| 'change_to' => $differenceValue, | ||
| ]; | ||
| } | ||
|
|
||
| if (!empty(count($differenceDetails))) { | ||
| $differenceDetails['variation_count'] = count($differenceDetails); | ||
| } | ||
|
|
||
| return $differenceDetails; | ||
| } | ||
| } |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.