-
Notifications
You must be signed in to change notification settings - Fork 536
!array_key_exists()
should imply array
for PHP8+
#4417
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
Open
staabm
wants to merge
8
commits into
phpstan:2.1.x
Choose a base branch
from
staabm:arr-key
base: 2.1.x
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+166
−2
Open
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
bc0bf26
`!array_key_exists()` should imply `array` for PHP8+
staabm 109b572
Update bug-13301-php8.php
staabm d8ba4ad
Update bug-13270b-php8.php
staabm 5215e5e
test different context variants
staabm 889ce48
get rid of instanceof Mixed
staabm 3e2d776
fix php7 build
staabm b9d27dc
fix wrong comment
staabm 349110a
fix
staabm 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,30 @@ | ||
<?php // lint >= 8.0 | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Bug13270bPhp8; | ||
|
||
use function PHPStan\Testing\assertType; | ||
|
||
class Test | ||
{ | ||
/** | ||
* @param mixed[] $data | ||
* @return mixed[] | ||
*/ | ||
public function parseData(array $data): array | ||
{ | ||
if (isset($data['price'])) { | ||
assertType('mixed~null', $data['price']); | ||
if (!array_key_exists('priceWithVat', $data['price'])) { | ||
$data['price']['priceWithVat'] = null; | ||
} | ||
assertType("non-empty-array&hasOffsetValue('priceWithVat', mixed)", $data['price']); | ||
if (!array_key_exists('priceWithoutVat', $data['price'])) { | ||
$data['price']['priceWithoutVat'] = null; | ||
} | ||
assertType("non-empty-array&hasOffsetValue('priceWithoutVat', mixed)&hasOffsetValue('priceWithVat', mixed)", $data['price']); | ||
} | ||
return $data; | ||
} | ||
} |
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 |
---|---|---|
@@ -1,4 +1,6 @@ | ||
<?php declare(strict_types=1); | ||
<?php // lint < 8.0 | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Bug13270b; | ||
|
||
|
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,52 @@ | ||
<?php // lint >= 8.0 | ||
|
||
namespace Bug13301Php8; | ||
|
||
use function PHPStan\Testing\assertType; | ||
|
||
function doFoo($mixed) { | ||
if (array_key_exists('a', $mixed)) { | ||
assertType("non-empty-array&hasOffset('a')", $mixed); | ||
echo "has-a"; | ||
} else { | ||
assertType('array', $mixed); // could be array~hasOffset('a') after arrays got subtractable | ||
echo "NO-a"; | ||
} | ||
assertType('array', $mixed); | ||
} | ||
|
||
function doFooTrue($mixed) { | ||
if (array_key_exists('a', $mixed) === true) { | ||
assertType("non-empty-array&hasOffset('a')", $mixed); | ||
} else { | ||
assertType('array', $mixed); // could be array~hasOffset('a') after arrays got subtractable | ||
} | ||
assertType('array', $mixed); | ||
} | ||
|
||
function doFooTruethy($mixed) { | ||
if (array_key_exists('a', $mixed) == true) { | ||
assertType("non-empty-array&hasOffset('a')", $mixed); | ||
} else { | ||
assertType('array', $mixed); // could be array~hasOffset('a') after arrays got subtractable | ||
} | ||
assertType('array', $mixed); | ||
} | ||
|
||
function doFooFalsey($mixed) { | ||
if (array_key_exists('a', $mixed) == 0) { | ||
assertType("array", $mixed); | ||
} else { | ||
assertType("non-empty-array&hasOffset('a')", $mixed); | ||
} | ||
assertType('array', $mixed); | ||
} | ||
|
||
function doArray(array $arr) { | ||
if (array_key_exists('a', $arr)) { | ||
assertType("non-empty-array&hasOffset('a')", $arr); | ||
} else { | ||
assertType('array', $arr); | ||
} | ||
assertType('array', $arr); | ||
} |
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 // lint < 8.0 | ||
|
||
namespace Bug13301Php7; | ||
|
||
use function PHPStan\Testing\assertType; | ||
|
||
function doFoo($mixed) { | ||
if (array_key_exists('a', $mixed)) { | ||
assertType("non-empty-array&hasOffset('a')", $mixed); | ||
echo "has-a"; | ||
} else { | ||
assertType("mixed~hasOffset('a')", $mixed); | ||
echo "NO-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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php // lint >= 8.0 | ||
|
||
namespace Bug2001Php8; | ||
|
||
use function PHPStan\Testing\assertType; | ||
|
||
class HelloWorld | ||
{ | ||
public function parseUrl(string $url): string | ||
{ | ||
$parsedUrl = parse_url(urldecode($url)); | ||
assertType('array{scheme?: string, host?: string, port?: int<0, 65535>, user?: string, pass?: string, path?: string, query?: string, fragment?: string}|false', $parsedUrl); | ||
|
||
if (array_key_exists('host', $parsedUrl)) { | ||
assertType('array{scheme?: string, host: string, port?: int<0, 65535>, user?: string, pass?: string, path?: string, query?: string, fragment?: string}', $parsedUrl); | ||
throw new \RuntimeException('Absolute URLs are prohibited for the redirectTo parameter.'); | ||
} | ||
|
||
assertType('array{scheme?: string, host?: string, port?: int<0, 65535>, user?: string, pass?: string, path?: string, query?: string, fragment?: string}', $parsedUrl); | ||
|
||
$redirectUrl = $parsedUrl['path']; | ||
|
||
if (array_key_exists('query', $parsedUrl)) { | ||
assertType('array{scheme?: string, host?: string, port?: int<0, 65535>, user?: string, pass?: string, path?: string, query: string, fragment?: string}', $parsedUrl); | ||
$redirectUrl .= '?' . $parsedUrl['query']; | ||
} | ||
|
||
if (array_key_exists('fragment', $parsedUrl)) { | ||
assertType('array{scheme?: string, host?: string, port?: int<0, 65535>, user?: string, pass?: string, path?: string, query?: string, fragment: string}', $parsedUrl); | ||
$redirectUrl .= '#' . $parsedUrl['query']; | ||
} | ||
|
||
assertType('array{scheme?: string, host?: string, port?: int<0, 65535>, user?: string, pass?: string, path?: string, query?: string, fragment?: string}', $parsedUrl); | ||
|
||
return $redirectUrl; | ||
} | ||
|
||
public function doFoo(int $i) | ||
{ | ||
$a = ['a' => $i]; | ||
if (rand(0, 1)) { | ||
$a['b'] = $i; | ||
} | ||
|
||
if (rand(0,1)) { | ||
$a = ['d' => $i]; | ||
} | ||
|
||
assertType('array{a: int, b?: int}|array{d: int}', $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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
<?php | ||
<?php // lint < 8.0 | ||
|
||
namespace Bug2001; | ||
|
||
|
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.
Uh oh!
There was an error while loading. Please reload this page.
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.
in this case we got more preicse, because we no longer have a union
array{...}|false
but just the plain array-shape.but on the other hand we no longer know that the
'host'
offset cannot exist at this point.I tried several variants, but wasn't successfull in combining the specified types in a way which turns the mixed into array while also removing the offset.