Skip to content

Commit

Permalink
add failing tests for wrong union result type
Browse files Browse the repository at this point in the history
  • Loading branch information
rajyan committed Dec 18, 2022
1 parent b4719b8 commit 3ed21be
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
@@ -0,0 +1,60 @@
<?php

namespace FilterVarDynamicReturnTypeExtensionRegression;

use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use function PHPStan\Testing\assertType;

class Test {

/**
* @return array{default: Type, range?: Type}
*/
public function getOtherTypes()
{

}

public function determineExactType(): ?Type
{

}

public function test()
{

$exactType = $this->determineExactType();
$type = $exactType ?? new MixedType();
$otherTypes = $this->getOtherTypes();

assertType('array{default: PHPStan\Type\Type, range?: PHPStan\Type\Type}', $otherTypes);
if (isset($otherTypes['range'])) {
assertType('array{default: PHPStan\Type\Type, range: PHPStan\Type\Type}', $otherTypes);
if ($type instanceof ConstantScalarType) {
if ($otherTypes['range']->isSuperTypeOf($type)->no()) {
$type = $otherTypes['default'];
}
assertType('array{default: PHPStan\Type\Type, range: PHPStan\Type\Type}', $otherTypes);
unset($otherTypes['default']);
assertType('array{range: PHPStan\Type\Type}', $otherTypes);
} else {
$type = $otherTypes['range'];
assertType('array{default: PHPStan\Type\Type, range: PHPStan\Type\Type}', $otherTypes);
}
assertType('array{default?: PHPStan\Type\Type, range: PHPStan\Type\Type}', $otherTypes);
}
assertType('array{default?: PHPStan\Type\Type, range?: PHPStan\Type\Type}&non-empty-array', $otherTypes);
if ($exactType !== null) {
assertType('array{default?: PHPStan\Type\Type, range?: PHPStan\Type\Type}&non-empty-array', $otherTypes);
unset($otherTypes['default']);
assertType('array{range?: PHPStan\Type\Type}', $otherTypes);
}
assertType('array{default?: PHPStan\Type\Type, range?: PHPStan\Type\Type}', $otherTypes);
if (isset($otherTypes['default']) && $otherTypes['default']->isSuperTypeOf($type)->no()) {
$type = TypeCombinator::union($type, $otherTypes['default']);
}
}
}
41 changes: 41 additions & 0 deletions tests/PHPStan/Type/TypeCombinatorTest.php
Expand Up @@ -2280,6 +2280,47 @@ public function dataUnion(): iterable
IntersectionType::class,
"array<int, array>&hasOffsetValue(0, array&hasOffsetValue('code', mixed))",
];

yield [
[
new ConstantArrayType(
[new ConstantStringType('default'), new ConstantStringType('range')],
[new ObjectType(Foo::class), new ObjectType(Foo::class)],
[0],
[0, 1]
),
new ConstantArrayType(
[new ConstantStringType('range')],
[new ObjectType(Foo::class)],
[0],
[0]
),
],
ConstantArrayType::class,
"array{default?: RecursionCallable\Foo, range?: RecursionCallable\Foo}",
];

yield [
[
new IntersectionType([
new ConstantArrayType(
[new ConstantStringType('default'), new ConstantStringType('range')],
[new ObjectType(Foo::class), new ObjectType(Foo::class)],
[0],
[0, 1]
),
new NonEmptyArrayType()
]),
new ConstantArrayType(
[new ConstantStringType('range')],
[new ObjectType(Foo::class)],
[0],
[0]
),
],
ConstantArrayType::class,
"array{default?: RecursionCallable\Foo, range?: RecursionCallable\Foo}",
];
}

/**
Expand Down

0 comments on commit 3ed21be

Please sign in to comment.