-
Notifications
You must be signed in to change notification settings - Fork 507
More precise types after assignment when strict-types=0 #3965
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
base: 2.1.x
Are you sure you want to change the base?
Conversation
This pull request has been marked as ready for review. |
I don't get why this is needed and why the current logic from #3945 doesn't already work for that. Can you explain please? |
|
This pull request has been marked as ready for review. |
@@ -5641,15 +5641,15 @@ static function (): void { | |||
|
|||
if ($assignedTypeIsCompatible) { | |||
$scope = $scope->assignExpression($var, $assignedExprType, $assignedNativeType); | |||
} elseif ($scope->isDeclareStrictTypes()) { |
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.
with the last commit I made PHPStan always do type-coersion, even if non-strict-types are used.
I think we can do that in the changed areas, because we are working on natively typed properties and these always convert whatever you assign to them (independent from strict-types=0/1)
see e.g. https://3v4l.org/qnsMN
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.
See the reason why we can't simply do this:
class Foo
{
public int $foo;
public function doFoo(string $s): void
{
$this->foo = $s;
assertType('int', $this->foo);
}
public function doBar(): void
{
$this->foo = 'foo';
assertType('int', $this->foo);
}
}
Reports:
15 Expected type int, actual: *NEVER*¨
21 Expected type int, actual: *NEVER*
On your PR.
I'm fine with the state of assigning from before all the toCoercedArgumentType
changes when strict_types is 0. It simply looked like this:
phpstan-src/src/Analyser/NodeScopeResolver.php
Line 5215 in e6dc705
$scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr)); |
But ->toCoercedArgumentType(true)
should only be called and assigned with strict_types = 1.
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.
thanks for the pointer. just to double check: in PHPStan 2.0.12 we get this results for your test:
class Foo
{
public int $foo;
public function doFoo(string $s): void
{
$this->foo = $s;
assertType('string', $this->foo); // should be int
}
public function doBar(): void
{
$this->foo = 'foo';
assertType("'foo'", $this->foo); // should be int
}
}
and this is good enough to get back to, even though its wrong for now, right?
@@ -0,0 +1,145 @@ | |||
<?php declare(strict_types = 0); |
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.
copied the test 12393 and changed only the strict_types to 0
@@ -5641,15 +5641,15 @@ static function (): void { | |||
|
|||
if ($assignedTypeIsCompatible) { | |||
$scope = $scope->assignExpression($var, $assignedExprType, $assignedNativeType); | |||
} elseif ($scope->isDeclareStrictTypes()) { |
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.
See the reason why we can't simply do this:
class Foo
{
public int $foo;
public function doFoo(string $s): void
{
$this->foo = $s;
assertType('int', $this->foo);
}
public function doBar(): void
{
$this->foo = 'foo';
assertType('int', $this->foo);
}
}
Reports:
15 Expected type int, actual: *NEVER*¨
21 Expected type int, actual: *NEVER*
On your PR.
I'm fine with the state of assigning from before all the toCoercedArgumentType
changes when strict_types is 0. It simply looked like this:
phpstan-src/src/Analyser/NodeScopeResolver.php
Line 5215 in e6dc705
$scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr)); |
But ->toCoercedArgumentType(true)
should only be called and assigned with strict_types = 1.
I just forcepushed here how the code makes sense to me. We just need to fix the failing tests 😂 |
thanks for the hints.. I will look into the errors after a lunch break |
do you mean adjusting test expectations or fixing the underlying bugs? |
Fix the bugs |
ready for another review. added loads of new tests |
I didn't mean you to start changing the toCoerced... method. It we do that, we need to do it right. What I meant right now is to slightly adjust what the "else" branch in NodeScopeResolver does after my force-push. It's up to you 😊 |
I don't see a way how a slight change can fullfill the tests
could you give me an idea whats "wrong" in the current PR? |
Improve types on top of #3945 but for the non-strict-types case.
see https://phpstan.org/r/aa5d5753-eca2-4735-bebf-6479e1ab1f42
do you think we could remove nullability from the property-type in scope, as the method we call returns a native non-nullable type, even ifstrict-types=0
...?closes phpstan/phpstan#12946