Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1513,12 +1513,6 @@ parameters:
count: 1
path: src/Type/OperatorTypeHelper.php

-
rawMessage: PHPDoc tag @var with type float|int|null is not subtype of type int|null.
identifier: varTag.type
count: 6
path: src/Type/OperatorTypeHelper.php

-
rawMessage: Creating new ReflectionClass is a runtime reflection concept that might not work in PHPStan because it uses fully static reflection engine. Use objects retrieved from ReflectionProvider instead.
identifier: phpstanApi.runtimeReflection
Expand Down
10 changes: 10 additions & 0 deletions src/Type/Constant/ConstantFloatType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use PHPStan\Type\FloatType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\IsSuperTypeOfResult;
use PHPStan\Type\NumberSet;
use PHPStan\Type\Traits\ConstantNumericComparisonTypeTrait;
use PHPStan\Type\Traits\ConstantScalarTypeTrait;
use PHPStan\Type\Type;
Expand Down Expand Up @@ -122,6 +123,15 @@ private function toIntegerValue(): int
return is_finite($this->value) ? (int) $this->value : 0;
}

public function toNumberSet(): NumberSet
{
if (is_nan($this->value)) {
return new NumberSet([], [], true);
}

return new NumberSet([], [[$this->value, $this->value]], false);
}

public function toInteger(): Type
{
return new ConstantIntegerType($this->toIntegerValue());
Expand Down
6 changes: 6 additions & 0 deletions src/Type/Constant/ConstantIntegerType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IsSuperTypeOfResult;
use PHPStan\Type\NumberSet;
use PHPStan\Type\Traits\ConstantNumericComparisonTypeTrait;
use PHPStan\Type\Traits\ConstantScalarTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -36,6 +37,11 @@ public function __construct(private int $value)
parent::__construct();
}

public function toNumberSet(): NumberSet
{
return new NumberSet([[$this->value, $this->value]], [], false);
}

public function getValue(): int
{
return $this->value;
Expand Down
15 changes: 9 additions & 6 deletions src/Type/ExponentiateHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,19 @@ private static function exponentiateConstantScalar(ConstantScalarType $base, Typ
*/
private static function getIntegerBounds(Type $type): ?array
{
if ($type instanceof IntegerRangeType) {
return [$type->getMin(), $type->getMax()];
$numberSet = $type->toNumberSet();
if ($numberSet === null || $numberSet->getFloatIntervals() !== [] || $numberSet->hasNan()) {
return null;
}

$values = $type->getConstantScalarValues();
if (count($values) === 1 && is_int($values[0])) {
return [$values[0], $values[0]];
// plain int stays (float|int): the intervals read an open end as no bound
// at all, not as PHP_INT_MIN or PHP_INT_MAX, whose powers overflow
$intervals = $numberSet->getIntegerIntervals();
if ($intervals === [[null, null]] || count($intervals) !== 1) {
return null;
}

return null;
return $intervals[0];
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/Type/FloatRangeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,11 @@ public function toBoolean(): BooleanType
return new BooleanType();
}

public function toNumberSet(): NumberSet
{
return new NumberSet([], [[$this->min, $this->max]], false);
}

public function toInteger(): Type
{
// casting a float outside of the int range is undefined
Expand Down
5 changes: 5 additions & 0 deletions src/Type/FloatType.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ public function toNumber(): Type
return $this;
}

public function toNumberSet(): NumberSet
{
return new NumberSet([], [[-INF, INF]], true);
}

public function toBitwiseNotType(): Type
{
return new IntegerType();
Expand Down
5 changes: 5 additions & 0 deletions src/Type/IntegerRangeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ public static function createAllGreaterThanOrEqualTo($value): Type
return self::fromInterval(is_nan($value) ? 0 : (int) ceil($value), null);
}

public function toNumberSet(): NumberSet
{
return new NumberSet([[$this->min, $this->max]], [], false);
}

public function getMin(): ?int
{
return $this->min;
Expand Down
5 changes: 5 additions & 0 deletions src/Type/IntegerType.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public function toNumber(): Type
return $this;
}

public function toNumberSet(): NumberSet
{
return new NumberSet([[null, null]], [], false);
}

public function toBitwiseNotType(): Type
{
return new IntegerType();
Expand Down
Loading
Loading