Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix bug #10862 #3065

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
greew wants to merge 8 commits into phpstan:1.11.x
base: 1.11.x
Choose a base branch
Loading
from greew:bug-10862
Open

Fix bug #10862 #3065

greew wants to merge 8 commits into phpstan:1.11.x from greew:bug-10862

Conversation

@greew
Copy link
Contributor

@greew greew commented May 12, 2024

This fix ensures that we use correct array indicies in >= PHP8.3.

(See https://www.php.net/manual/en/migration83.incompatible.php#migration83.incompatible.core.negative-index-to-empty-array).

We ensure, that if

  • PHP version is 8.3+
  • AND the current element to add is the first element
  • AND the key is less than 0 (it's negative)

then we set the newAutoIndexes to the negative value + 1.

Added tests to show correctness for both < PHP8.3 and >= PHP8.3

This should fix bug phpstan/phpstan#10862


I'm not sure that I quite understood the $optional part - also, if you prefer having tests created in another way than each in their separate file (or something else), please let me know! :)

Copy link
Contributor

@staabm staabm May 12, 2024
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually php feature detects are implemented in PhpVersion class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!! It's exactly these kinds of comments, I need!

I'll try and figure out how that's working! 😊

Copy link
Contributor Author

greew commented May 12, 2024

I'm not sure this is the right solution, but since ConstantArrayTypeBuilder is not created by DI, I don't know how else to insert the PhpVersion class into the class.

Copy link
Contributor

herndlm commented May 12, 2024
edited
Loading

I'm not sure this is the right solution, but since ConstantArrayTypeBuilder is not created by DI, I don't know how else to insert the PhpVersion class into the class.

$phpVersion = PhpVersionStaticAccessor::getInstance();

just directly where you need it apparently. It's already used somewhere in ConstantArrayType

greew reacted with thumbs up emoji

Copy link
Contributor Author

greew commented May 12, 2024

I'm not sure this is the right solution, but since ConstantArrayTypeBuilder is not created by DI, I don't know how else to insert the PhpVersion class into the class.

$phpVersion = PhpVersionStaticAccessor::getInstance();

just directly where you need it apparently. It's already used somewhere in ConstantArrayType

Greeeeat - thank you very much!! 😃

Copy link
Member

I feel like this fix should be done differently.

Because PHPStan has a wrong assumption even on previous PHP versions: https://phpstan.org/r/492b583a-dc4b-4be2-a4c9-2232e039c19c (2nd key in $a should be -3 on all PHP versions, not just PHP 8.3).

Only on PHP 8.3 $b should be array{-4: 1, -3: 2}, otherwise array{-4: 1, 0: 2}.

My suggestion: Fix the behaviour in ConstantArrayTypeBuilder regardless of PHP version. And then in InitializerExprTypeResolver::getArrayType() (DI is available there, hooray!) do the condition for PHP < 8.3 (so that the 2nd key is 0, not -3).

Copy link
Contributor Author

greew commented Jun 2, 2024

I feel like this fix should be done differently.

Because PHPStan has a wrong assumption even on previous PHP versions: https://phpstan.org/r/492b583a-dc4b-4be2-a4c9-2232e039c19c (2nd key in $a should be -3 on all PHP versions, not just PHP 8.3).

Only on PHP 8.3 $b should be array{-4: 1, -3: 2}, otherwise array{-4: 1, 0: 2}.

My suggestion: Fix the behaviour in ConstantArrayTypeBuilder regardless of PHP version. And then in InitializerExprTypeResolver::getArrayType() (DI is available there, hooray!) do the condition for PHP < 8.3 (so that the 2nd key is 0, not -3).

Great - thanks! And nice caught with the direct initialization difference in the old PHP versions!

Anyhow - I can't seem to figure out how to implement the change in the InitializerExprTypeResolver::getArrayType() method. It is still the ConstantArrayTypeBuilder that handles the calculation of which nextAutoIndexes to use, and I can't change this data from within InitializerExprTypeResolver.

If I'm not to change the visibility of the methods of ConstantArrayTypeBuilder, can someone give me a hint of how to do this?

Copy link
Member

In InitializerExprTypeResolver::getArrayType() you can call a new method on ConstantArrayTypeBuilder after creation that changes how it computes next indexes...

Copy link
Contributor Author

greew commented Jun 9, 2024

OK, I've added tests for both pre-8.0, 8.0+ and 8.3+ as requested in phpstan/phpstan#10862 (comment).

As requested earlier on, I've also moved the PHP version check to the InitializerExprTypeResolver class, but also had to add a PHP version check in ConstantArrayType to take care of the PHP >=8.0 < 8.3 findings.

Copy link
Contributor Author

greew commented Jun 9, 2024

Seems like the 7.3 and 7.4 errors test errors were introduced in #3128 ??

Copy link
Contributor

staabm commented Jun 10, 2024

Seems like the 7.3 and 7.4 errors test errors were introduced in #3128 ??

fixed the build error with #3137

greew added 8 commits June 10, 2024 10:00
This fix ensures that we use correct array indicies in >= PHP8.3. (See
https://www.php.net/manual/en/migration83.incompatible.php#migration83.incompatible.core.negative-index-to-empty-array).
We ensure, that if
- PHP version is 8.3+
- AND the current element to add is the first element
- AND the key is less than 0 (it's negative)
then we set the newAutoIndexes to the negative value + 1.
Added tests to show correctness for both < PHP8.3 and >= PHP8.3
Fixing negative array indexes
if (PHP_VERSION_ID < 80000) {
$path = 'bug-10862';
}
yield from self::gatherAssertTypes(__DIR__ . '/data/' . $path . '.php');
Copy link
Member

@ondrejmirtes ondrejmirtes Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if the conditions contained the whole yield from call instead of concatenating the path dynamically like this. It will make the path clickable in IDE.

$this->nextAutoIndexes[] = $newAutoIndex;
}
}
if (count($this->keyTypes) === 1 && $offsetType->getValue() < 0) {
Copy link
Member

@ondrejmirtes ondrejmirtes Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes to the builder certainly need new tests in ConstantArrayTypeBuilderTest.

return $this->isList->yes();
}

public function resetNextAutoIndexToZeroIfNegative(): void
Copy link
Member

@ondrejmirtes ondrejmirtes Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought about this method that it should be set once after creation and not before every setOffsetValueType call. It should change the behaviour for all the calls, not just for the next one. Instead of this logic, this method should switch a bool property so that the computation of nextAutoIndexes changes based on that.

Copy link
Contributor

Hi @greew, are you still interested in finishing in PR (and doing it on 2.1.x now) ?

Copy link
Contributor Author

greew commented Oct 24, 2025

@VincentLanglet Uhmm... I'll see if I can get the time within the next weeks :)

I had pretty much forgotten about this PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ondrejmirtes ondrejmirtes ondrejmirtes requested changes

+1 more reviewer

@staabm staabm staabm left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /