Skip to content

Commit

Permalink
Throw on invalid UnionType with AccessoryTypes
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Sep 27, 2024
1 parent 7888327 commit d319850
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Type/UnionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Accessory\AccessoryType;
use PHPStan\Type\Generic\GenericClassStringType;
use PHPStan\Type\Generic\TemplateMixedType;
use PHPStan\Type\Generic\TemplateType;
Expand Down Expand Up @@ -67,6 +68,10 @@ public function __construct(private array $types, private bool $normalized = fal
$throwException();
}
foreach ($types as $type) {
if ($type instanceof AccessoryType) {
// accessory types need to be intersected with a main type
$throwException();
}
if (!($type instanceof UnionType)) {
continue;
}
Expand Down
29 changes: 29 additions & 0 deletions tests/PHPStan/Type/UnionTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
use Iterator;
use PHPStan\Reflection\Native\NativeParameterReflection;
use PHPStan\Reflection\PassedByReference;
use PHPStan\ShouldNotHappenException;
use PHPStan\Testing\PHPStanTestCase;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
use PHPStan\Type\Accessory\AccessoryNumericStringType;
use PHPStan\Type\Accessory\HasMethodType;
use PHPStan\Type\Accessory\HasOffsetType;
Expand Down Expand Up @@ -1640,4 +1643,30 @@ public function dataGetArrays(): iterable
];
}

/**
* @param Type[] $types
*
* @dataProvider dataUnionThrows
*/
public function testUnionThrows(array $types, string $message): void
{
$this->expectException(ShouldNotHappenException::class);
$this->expectExceptionMessage($message);

new UnionType($types);
}

public function dataUnionThrows(): array
{
return [
// union type requires at least 2 types
[[new AccessoryNonEmptyStringType()], 'Cannot create PHPStan\\Type\\UnionType with: non-empty-string'],
// test invalid combinations
[[new AccessoryNonFalsyStringType(), new AccessoryNumericStringType()], 'Cannot create PHPStan\\Type\\UnionType with: non-falsy-string, numeric-string'],
[[new IntegerType(), new AccessoryNumericStringType()], 'Cannot create PHPStan\\Type\\UnionType with: int, numeric-string'],
[[new ArrayType(new IntegerType(), new StringType()), new AccessoryNonEmptyStringType()], 'Cannot create PHPStan\\Type\\UnionType with: array<int, string>, non-empty-string'],
[[new IntegerType(), new NonEmptyArrayType()], 'Cannot create PHPStan\\Type\\UnionType with: int, non-empty-array'],
];
}

}

0 comments on commit d319850

Please sign in to comment.