Skip to content

Commit

Permalink
ForbidVariableTypeOverwriting: fix int-range and enum-case issues (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
janedbal committed Apr 5, 2023
1 parent 7d51a4e commit e07867c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
8 changes: 7 additions & 1 deletion src/Rule/ForbidVariableTypeOverwritingRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Type\Accessory\AccessoryType;
use PHPStan\Type\Enum\EnumCaseObjectType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
use PHPStan\Type\SubtractableType;
Expand Down Expand Up @@ -75,7 +77,11 @@ private function generalizeDeeply(Type $type): Type

private function generalize(Type $type): Type
{
if ($type->isConstantValue()->yes()) {
if (
$type->isConstantValue()->yes()
|| $type instanceof IntegerRangeType
|| $type instanceof EnumCaseObjectType // @phpstan-ignore-line ignore instanceof warning
) {
$type = $type->generalize(GeneralizePrecision::lessSpecific());
}

Expand Down
26 changes: 23 additions & 3 deletions tests/Rule/data/ForbidVariableTypeOverwritingRule/code.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class AnotherClassWithInterface implements SomeInterface {

}

enum FooEnum {
case One;
case Two;
}

function testGeneralizationAndNarrowing(
object $object,
SomeInterface $interface,
Expand Down Expand Up @@ -60,12 +65,12 @@ function testBasics(
array $map,
array $intList = [1],
): void {
$intList = ['string']; // error: Overwriting variable $intList while changing its type from array<int<0, max>, int> to array<int<0, max>, string>
$intList = ['string']; // error: Overwriting variable $intList while changing its type from array<int, int> to array<int, string>
$array = 1; // error: Overwriting variable $array while changing its type from array to int
$string = 1; // error: Overwriting variable $string while changing its type from string to int
$objectList = ['foo']; // error: Overwriting variable $objectList while changing its type from array<int<0, max>, ForbidVariableTypeOverwritingRule\ParentClass> to array<int<0, max>, string>
$objectList = ['foo']; // error: Overwriting variable $objectList while changing its type from array<int, ForbidVariableTypeOverwritingRule\ParentClass> to array<int, string>
$class = new \stdClass(); // error: Overwriting variable $class while changing its type from ForbidVariableTypeOverwritingRule\ParentClass to stdClass
$map = [1]; // error: Overwriting variable $map while changing its type from array<string, string> to array<int<0, max>, int>
$map = [1]; // error: Overwriting variable $map while changing its type from array<string, string> to array<int, int>
}

function testIgnoredTypes(
Expand Down Expand Up @@ -131,3 +136,18 @@ function testSubtractedTypeNotKept(ParentClass $someClass, array $strings) {
unset($strings[0]);
$strings = array_values($strings);
}

function testEnumCaseChange() {
$case1 = FooEnum::One;
$case1 = FooEnum::Two;
}

/**
* @param positive-int $positive
* @param negative-int $negative
*
* @return void
*/
function testIntToInt(int $positive, int $negative) {
$positive = $negative;
}

0 comments on commit e07867c

Please sign in to comment.