Skip to content
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

array_keys() does not always infer the key type from the given array #2857

Closed
BenMorel opened this issue Jan 17, 2020 · 3 comments
Closed

array_keys() does not always infer the key type from the given array #2857

BenMorel opened this issue Jan 17, 2020 · 3 comments

Comments

@BenMorel
Copy link

Bug report

This is similar to #1847, but we're still getting the error with phpstan 0.11.19 and 0.12.5.

Even though the array key type is known, in some situations it is not used to infer the type of array_keys().

Code snippet that reproduces the problem

    /**
     * @param array<string, true> $knownAliases
     */
    function getSQLForJoins(string $fromAlias, array &$knownAliases) : string
    {
        ...
            throw NonUniqueAlias::new($join['joinAlias'], array_keys($knownAliases));

Here the type of array_keys($knownAliases) is inferred as array<int, int|string> instead of array<int, string>.

Sandbox: https://phpstan.org/r/98b7db20-f773-49d9-86d7-014f5d209483
Travis: https://travis-ci.org/doctrine/dbal/jobs/638201455

If you remove lines 45-48 (after the culprit), it suddenly works:

https://phpstan.org/r/586a6826-b4f7-4ea0-8c62-f3fa8a643a1a

Expected output

[OK] No errors

Actual output

 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------- 
  Line   lib/Doctrine/DBAL/Query/QueryBuilder.php                                                                                                                   
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------- 
  1319   Parameter #2 $registeredAliases of static method Doctrine\DBAL\Query\Exception\NonUniqueAlias::new() expects array<string>, array<int, int|string> given.  
 ------ ----------------------------------------------------------------------------------------------------------------------------------------------------------- 
@morozov
Copy link
Contributor

morozov commented Jan 17, 2020

Looks like this is because of $knownAliases[$join['joinAlias']] = true. Although we specify the type of $knownAliases as array<string, true>, given that the type of $join['joinAlias'] is unknown to PHPStan, setting this key on the array makes it array<int|string, true>.

Unless there's a way to specify the type of joinAlias on $join (like array{joinAlias: string} in Psalm), we could use an assertion.

@ondrejmirtes
Copy link
Member

PHPStan doesn't know what $join['joinAlias'] alias is, it's mixed for the analysis. So array_keys($knownAliases) are an array of int|string.

You can fix this by introducing some local variables and using inline @var PHPDocs.

@lock
Copy link

lock bot commented Feb 21, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Feb 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants