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
support integer-ranges in pow() #1904
Conversation
//cc @orklah |
24d9810
to
f94aa04
Compare
This pull request has been marked as ready for review. |
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 doesn't handle unions of integer ranges on both sides. Instead of instanceof *Type
, it'd be better to handle this with a new method on Type. But of course that needs to be designed in order to be useful, ideally to replace other instances of instancoef IntegerRangeType
and even maybe TypeUtils::getConstantIntegers()
.
if I get you right we are talking about methods such as the following, right? diff --git a/src/Type/Type.php b/src/Type/Type.php
index f02971559..5a00d7f1c 100644
--- a/src/Type/Type.php
+++ b/src/Type/Type.php
@@ -112,6 +112,16 @@ interface Type
public function shuffleArray(): Type;
+ public function subtract(Type $subtrahend): Type;
+
+ public function sum(Type $summand): Type;
+
+ public function multiply(Type $multiplicand): Type;
+
+ public function divide(Type $divisor): Type;
+
+ public function pow(Type $exponent): Type;
+ or do you have somthing different in mind? |
Yeah, that would be great, although "pow" isn't a word unlike the others, should be "exponentiate" probably. |
We'll be able to get rid of a lot of code in InitializerExprTypeResolver :) |
1b6b658
to
47d98bf
Compare
This pull request has been marked as ready for review. |
implemented |
47d98bf
to
44030cd
Compare
return TypeCombinator::union(...$resultTypes); | ||
$exponentiatedTyped = $leftType->exponentiate($rightType); | ||
if (!$exponentiatedTyped instanceof ErrorType) { | ||
return $exponentiatedTyped; | ||
} | ||
|
||
return $this->resolveCommonMath(new BinaryOp\Pow($left, $right), $leftType, $rightType); |
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 kept this pass thru resolveCommonMath
because otherwise we would loose support for operator-type specifiying extensions (even though atm, there is no test-coverage for using it with pow
).
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.
test added with #1933
0ca4bbe
to
7cc6be5
Compare
@@ -685,6 +685,14 @@ public function tryRemove(Type $typeToRemove): ?Type | |||
return null; | |||
} | |||
|
|||
public function exponentiate(Type $exponent): Type | |||
{ | |||
return new BenevolentUnionType([ |
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.
What if all numeric types are subtracted?
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.
pow() supports a lot of types as exponent, see e.g. https://3v4l.org/ZtZVc
we would need a big union, which might not be really useful?
per https://www.php.net/manual/en/function.pow.php it supports mixed
args, while phpstan only accepts int|float
per functionMap.
public function exponentiate(Type $exponent): Type | ||
{ | ||
$object = new ObjectWithoutClassType(); | ||
if (!$exponent instanceof NeverType && !$object->isSuperTypeOf($this)->no() && !$object->isSuperTypeOf($exponent)->no()) { |
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.
Objects can be exponentiated? Huh?
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.
yep, see
phpstan-src/tests/PHPStan/Analyser/data/pow.php
Lines 17 to 25 in 285b49f
function (\GMP $a, \GMP $b): void { | |
assertType('GMP', pow($a, $b)); | |
assertType('GMP', $a ** $b); | |
}; | |
function (\stdClass $a, \GMP $b): void { | |
assertType('GMP|stdClass', pow($a, $b)); | |
assertType('GMP|stdClass', $a ** $b); | |
}; |
I moved this pre-exisiting logic from InitializerExprTypeResolver
src/Type/FloatType.php
Outdated
} | ||
|
||
if ($exponent instanceof ConstantScalarType) { | ||
if ($exponent->getValue() == 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.
the cs-fixer will turn these into strict comparisons, which in turn breaks a lot of tests.
I think we should ignore these from the cs fixer
7ca9ef5
to
8cdf131
Compare
7595c93
to
2319a8f
Compare
There are some conflicts. |
resolved |
568f510
to
a760a3c
Compare
7a54fe3
to
18945c6
Compare
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.
Otherwise 👍
src/Type/FloatType.php
Outdated
public function exponentiate(Type $exponent): Type | ||
{ | ||
$helper = new ExponentiateHelper(); | ||
return $helper->exponentiate($this, $exponent); |
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.
It's weird to new
this. Typically we inject these services through DI. But I understand that we're in a value object where DI is not accessible. In these cases I'd write this as a static method: ExponentiateHelper::exponentiate
. Thanks.
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.
good point, fixed.
afe0b90
to
33c011a
Compare
Thank you. |
closes the last remaining todo of #5614
fixes phpstan/phpstan#5614