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

Prevent ShouldNotHappenException in filter_* extensions #2951

Open
wants to merge 14 commits into
base: 1.10.x
Choose a base branch
from

Conversation

staabm
Copy link
Contributor

@staabm staabm commented Mar 1, 2024

@@ -240,7 +242,7 @@ private function getConstant(string $constantName): int
$constant = $this->reflectionProvider->getConstant(new Node\Name($constantName), null);
$valueType = $constant->getValueType();
if (!$valueType instanceof ConstantIntegerType) {
throw new ShouldNotHappenException(sprintf('Constant %s does not have integer type.', $constantName));
return self::UNKNOWN_CONSTANT;
Copy link
Contributor Author

@staabm staabm Mar 1, 2024

Choose a reason for hiding this comment

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

I thought about returning null, or catching this exception (or a new exception) at the call-sites, but this seemed too much for this case. instead I decided to return a negative constant value, which does not overlap with other existing FILTER_* constants

@staabm staabm marked this pull request as ready for review March 1, 2024 14:12
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

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

What's the effect of this on the type inference? Please include the failing test here in this PR too. So we can build on it and verify the actual returned type by this extension.

@staabm staabm marked this pull request as draft March 5, 2024 14:15
@staabm
Copy link
Contributor Author

staabm commented Mar 5, 2024

(I need to verify on a different computer with PHP 7.2 installed whether the test is working as intended)

@staabm staabm marked this pull request as ready for review March 5, 2024 18:36
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@@ -202,6 +202,8 @@ jobs:

strategy:
matrix:
php-version: ["8.1"]
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't do what you think it does. See: https://github.com/phpstan/phpstan-src/actions/runs/8159444153/job/22303754862 - you basically disabled all of the tests.

Normal run: https://github.com/phpstan/phpstan-src/actions/runs/8170798487

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch. fixed it.

thank you

<?php

function doFoo(mixed $filter): void {
\PHPStan\Testing\assertType('non-falsy-string|false', filter_var("no", FILTER_VALIDATE_REGEXP));
Copy link
Member

Choose a reason for hiding this comment

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

Alright so I found out that the usual result on PHP versions where this constant exists is the same as here. Which makes me a bit suspicious. Can you explain that? We surely must be losing information when we return the unknown constant somewhere, right?

@ondrejmirtes
Copy link
Member

Alright, and now add the same test to the usual NodeScopeResolverTest, so that the difference is obvious 😊 You'll most likely need different files for different PHP versions?

@staabm
Copy link
Contributor Author

staabm commented Mar 6, 2024

reverted the previous test commit.

I thnk there is no type inference difference to observe, because phpstan internally works with the same "wrong" constant value as the code beeing analyzed (because the constant is defined in a bootstrap.php script, therefore mangels the global scope of the whole process).

the only thing we need to prevent is the crash

@staabm
Copy link
Contributor Author

staabm commented Mar 6, 2024

I got one idea for which I am not sure whether its worth testing. the type inference might be different when we define the constant in bootstrap with a integer value of another existing FILTER_ constant. that way we would trigger an overlap of 2 constants.

but thats not something the initial case we try to fix triggers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants