More precise types after assignment when strict-types=0#3965
More precise types after assignment when strict-types=0#3965ondrejmirtes merged 38 commits intophpstan:2.1.xfrom
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. |
| @@ -0,0 +1,145 @@ | |||
| <?php declare(strict_types = 0); | |||
There was a problem hiding this comment.
copied the test 12393 and changed only the strict_types to 0
|
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? |
ondrejmirtes
left a comment
There was a problem hiding this comment.
This looks promising. But you haven't touched toCoercedArgumentType in some types. For example in ArrayTypeTrait, HasOffset*Type, accessory array types, NullType, ObjectType (Stringable object can be passed to string imho), ObjectTypeTrait.
For example VoidType should do (new NullType)->toCoercedArgumentType($strictTypes).
|
thanks for the hints. I have added support for Stringable objects and callable types. intentionally I did not add array types, as I don't find a example in which they can be coerced. I have also added tests for void type and these also did not need adjustments in |
|
@staabm These coercions are described on PHP website. See the links near the bottom at https://www.php.net/manual/en/language.types.type-juggling.php Converting to boolean I'm especially worried about those array accessory types because they just return this, I'm not sure what would happen for example when you have non-empty-array and try to assign it into integer, whethey it'd work properly or not. |
|
I think the conversion rules on these manual pages describe what happens on explicit casts. see e.g. https://3v4l.org/H5XnR while you can cast a
just added tests for the mentioned cases |
| assertType('null', $this->foo); | ||
|
|
||
| $this->fooNonNull = $this->returnVoid(); | ||
| assertType('int|null', $this->foo); // should be *ERROR* |
There was a problem hiding this comment.
I think this is a bug regarding void-to-null transformation which should be fixed in a followup PR
its a rare edge case
|
Oh interesting, didn't know about that. |
| private string $foo; | ||
|
|
||
| public function doFoo(callable $foo): void { | ||
| $this->foo = $foo; // PHPStorm wrongly reports an error on this line |
There was a problem hiding this comment.
There was a problem hiding this comment.
To be fair PHPStan also reports an error for that (which is correct, we mostly don't differentiate between strict_types 1 or 0 in Type::accepts().
| public function toCoercedArgumentType(bool $strictTypes): Type | ||
| { | ||
| if (!$strictTypes) { | ||
| return TypeCombinator::union($this, $this->toString()); |
There was a problem hiding this comment.
If the object isn't a Stringable, this should just return $this. But instead it will return ErrorType.
Also I'm not sure what happens with BcMath\Number in strict_types=1 or 0.
There was a problem hiding this comment.
added tests with links to 3v4l.org
|
Alright, I'm really excited about this, let's try it out! |
|
Hi @staabm, I just saw this and I have some question about this change.
|
|
Huhu The PR is about type inference, meaning PHPStan better know when/which types flow thru the code. It does not change the rules when errors are reported. Regarding BcMath\Number. it behaves like that because the php runtime only errors when strict_types=1, but for strict_types=0 it's legale to assign a object which implements __toString to a string. I don't know whether this makes sense. In case you want strict_types=1 you can declare it and work on the errors. ondrey might have a clear opinion on it |
|
The 2 different modes have different characteristics and not necessarily everyone want to migrate from weak to strict. I have recently seen discussions of php-src devs whether a new mode should be implemented which is a mix of the 2 existing ones, as both have some advantages |
|
@VincentLanglet This behaviour didn't change with this PR. If PHPStan reports errors in the same situations where PHP reports TypeError, it's correct. |

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
closes phpstan/phpstan#12940
closes phpstan/phpstan#12950
closes phpstan/phpstan#12947