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
Fix native types2 #1802
Fix native types2 #1802
Conversation
I think it’s almost done. Several native type specification are missing. |
47f6b2e
to
2d311e8
Compare
Finally done it? |
I prefer heading to 1.9.x because it's gonna be a huge change for |
The failing tests are from |
I don't want to disturb the discussion here too much, so it's not important, but do you maybe know how this relates to #1781 (review)? Would there be more changes needed or should that work already then? |
@herndlm |
I’ll add some regression tests tomorrow:) |
I'm looking forward to review this, looks promising 😊 |
Alright, I like some parts but don't like some others :) I'd like to establish some ground rules that should be true when this PR is in progress and after it's merged:
/**
* @param positive-int|non-empty-string $a
*/
function foo(int|string $a): void
{
assertType('positive-int|non-empty-string', $a);
assertNativeType('int|string', $a);
if (is_string($a)) {
assertType('non-empty-string', $a);
assertNativeType('string', $a);
}
} The implementation of if ($node instanceof Expr\BinaryOp\Smaller) {
return $this->getNativeType($node->left)->isSmallerThan($this->getNativeType($node->right))->toBooleanType();
} if ($node instanceof Node\Expr\BitwiseNot) {
return $this->initializerExprTypeResolver->getBitwiseNotType($node->expr, fn (Expr $expr): Type => $this->getNativeType($expr));
}
|
$this->analyse([__DIR__ . '/data/bug-7622.php'], [ | ||
[ | ||
'Match expression does not handle remaining value: string', | ||
21, |
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.
This is wrong
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.
Is this? I'm not sure if native type can know that the match is exhaustive.
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.
But the rule always asks getType, not getNativeType. The pupose of the setting treat...
to false is to remove errors like "this if is always false" (when code checks again something that's only expressed in PHPDocs and not checked at runtime), not add new errors.
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.
ok, I think
The pupose of the setting treat... to false is to remove errors like "this if is always false"
was what I was totally misunderstanding.
My thinking was to switch between native types
and full types
by treatPhpDocTypesAsCertain
like,
treatPhpDocTypesAsCertain: true
getNativeType() => native type
getType() => full types
treatPhpDocTypesAsCertain: false
getNativeType() = getType() => native type
I now understood that when a rule error is
- | full type | native type |
---|---|---|
1 | no error | no error |
2 | error | no error |
3 | no error | error |
4 | error | error |
purpose of treatPhpDocTypesAsCertain
is to relax cases like 2.
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.
I think the docs are clear on this 😊 "relaxes" https://phpstan.org/config-reference#treatphpdoctypesascertain
@@ -123,89 +114,8 @@ public function testRule(): void | |||
]); | |||
} | |||
|
|||
public function testRuleWithoutTreatPhpDocTypesAsCertain(): void |
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.
Deleting a test is a no-go :) It should continue working as before.
It's interesting to know that the example with type narrowing on variables already works: https://phpstan.org/r/59b890fb-466d-4926-b060-15859b520c63 That's because today there's The test wouldn't work for other expressions like property fetches and array dim fetches. That's why we need |
memo |
@ondrejmirtes
You mean that Scope always have both native and phpdoc type, and treatPhpDocTypesAsCertain should be handled in the Rule side to switch between |
Yes 😊 |
Another important test is this: function doFoo(): string
{
}
function (): void {
/** @var non-empty-string $a */
$a = doFoo();
assertType('non-empty-string', $a);
assertNativeType('string', $a);
}; Meaning that everything around |
e5f543c
to
2744c22
Compare
adea623
to
158319e
Compare
158319e
to
32861a0
Compare
@ondrejmirtes i'm going to fix the comments in |
To give you a bit more context, thanks to more precise Validate inline
|
One thing I can suggest here: We can finish the current impact of this PR once we're happy with it and it's tested in sufficient manner. And merge it. We don't have to implement every Expr type in getNativeType() right now, it's a lot of code and I worry it would become unmanagable. That can be done in the next PRs. |
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.
I'm quite happy with this PR already. These few comments resolved + green build is all it takes for me to merge it 😊 And we can continue the work in further PRs, like moreSpecificNativeTypes, and fully implementing getNativeType for all exprs.
src/Analyser/MutatingScope.php
Outdated
@@ -506,6 +506,13 @@ public function hasVariableType(string $variableName): TrinaryLogic | |||
/** @api */ | |||
public function getVariableType(string $variableName): Type | |||
{ | |||
if (!$this->treatPhpDocTypesAsCertain) { |
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.
The behaviour shouldn't change here - MutatingScope shouldn't be interested in the treat option.
There could be getVariableNativeType method, but I don't think we need it.
src/Analyser/MutatingScope.php
Outdated
@@ -2147,7 +2113,7 @@ public function getNativeType(Expr $expr): Type | |||
); | |||
} | |||
|
|||
return $this->getType($expr); | |||
return $this->doNotTreatPhpDocTypesAsCertain()->getType($expr); |
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.
This lind should just return new MixedType.
cases from * #1802 (comment) * #1802 (comment) * phpstan/phpstan#6260
Co-authored-by: Brad Miller <28307684+mad-briller@users.noreply.github.com>
05aae3e
to
83c207f
Compare
Totally agreed. |
I've written down some context about this and my plan: phpstan/phpstan#8191 |
Everything from this PR is either already in 1.9.x or in #1943 :) |
closes #1535
closes #1627
and a lot of native type related issues!
Native types should always be specified along phpdoc types.
Also, there should be only a single
treatPhpDocTypesAsCertain
handling to switch betweenvariableTypes
andnativeTypeExpression
phpstan-src/src/Analyser/MutatingScope.php
Lines 506 to 511 in b2bf589
With this pull request, native types and phpdoc types are completely separated by
treatPhpDocTypesAsCertain
.I hope I've understood
#1372 (comment)
this correctly...