Skip to content

Conversation

staabm
Copy link
Contributor

@staabm staabm commented Mar 18, 2022

@staabm
Copy link
Contributor Author

staabm commented Mar 18, 2022

this part of the initial issue

Additionally PHPStan does not error on types that have this as array key: array<value-of, bool>, which means that it silently accepts incorrect code in this case (key-of has the same issue in this case, I guess that should just not be allowed though).
Playground example: phpstan.org/r/50d372e7-f7bf-49a2-8456-2eb89d97b7bc

sounds like a missing rule-check somewhere... I think this can be fixed in a separate PR (which I can work on after this)?

@staabm
Copy link
Contributor Author

staabm commented Mar 18, 2022

(sorry for trial and error.. have no php 8.1 setup yet locally)

build error is unrelated

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.

Please also add a case to NodeScopeResolverTest that tests what value-of resolves to inside a method body.

@ondrejmirtes
Copy link
Member

About this:

Additionally PHPStan does not error on types that have this as array key: array<value-of, bool>, which means that it silently accepts incorrect code in this case

Yeah, let's discuss this separately in another PR. The issue here is that value-of<something wrong> produces an ErrorType in TypeNodeResolver, and array<*ERROR*, X> gets cast to array<int|string, X> in TypeNodeResolver but it needs to stay array<*ERROR*, X> on this line:

$arrayType = new ArrayType(!$keyType instanceof NeverType ? ArrayType::castToArrayKeyType($keyType) : $keyType, $genericTypes[1]);

@staabm staabm force-pushed the value-of-enum branch 2 times, most recently from 1ca0150 to 90851b1 Compare March 18, 2022 17:09
@ondrejmirtes ondrejmirtes force-pushed the 1.5.x branch 3 times, most recently from ddd20b4 to 95d480b Compare March 18, 2022 19:53
@ondrejmirtes
Copy link
Member

Please add NodeScopeResolverTest case to verify it works as expected.

@staabm
Copy link
Contributor Author

staabm commented Mar 21, 2022

Please add NodeScopeResolverTest case to verify it works as expected.

done

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.

Obviously the implementation in TypeNodeResolver needs to change. Please iterate over ClassReflection::getEnumCases() to get to actual scalar values.

@@ -800,6 +800,11 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6859.php');
}

if (PHP_VERSION_ID >= 80100) {
require_once __DIR__ . '/data/value-of-enum.php';
Copy link
Member

Choose a reason for hiding this comment

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

Require is not needed here, make sure to run composer dump locally first.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I checked it locally.. the tests do not work without this require line.

even if I run composer dump beforehand

Copy link
Contributor Author

@staabm staabm Mar 23, 2022

Choose a reason for hiding this comment

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

ahh.. I need to /my/php8.1 composer dump and then it works

*/
function hello($countryName)
{
assertType('string', $countryName);
Copy link
Member

Choose a reason for hiding this comment

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

This isn't good enough, right? Should be 'The Netherlands'|'United States' really.

Copy link
Member

Choose a reason for hiding this comment

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

It's also why that bug isn't report in CallMethodsRuleTest.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed it. good catch.

function doFooArray() {
$this->hello(CountryNo::NL);

// 'abc' does not match value-of<Country>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

as expected, we now see errors here.

@ondrejmirtes ondrejmirtes merged commit 7171941 into phpstan:1.5.x Mar 23, 2022
@ondrejmirtes
Copy link
Member

Thank you.

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

Successfully merging this pull request may close these issues.

value-of<BackedEnum> would be cool to have
3 participants