Skip to content

Commit d319850

Browse files
committed
Throw on invalid UnionType with AccessoryTypes
1 parent 7888327 commit d319850

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/Type/UnionType.php

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
2020
use PHPStan\ShouldNotHappenException;
2121
use PHPStan\TrinaryLogic;
22+
use PHPStan\Type\Accessory\AccessoryType;
2223
use PHPStan\Type\Generic\GenericClassStringType;
2324
use PHPStan\Type\Generic\TemplateMixedType;
2425
use PHPStan\Type\Generic\TemplateType;
@@ -67,6 +68,10 @@ public function __construct(private array $types, private bool $normalized = fal
6768
$throwException();
6869
}
6970
foreach ($types as $type) {
71+
if ($type instanceof AccessoryType) {
72+
// accessory types need to be intersected with a main type
73+
$throwException();
74+
}
7075
if (!($type instanceof UnionType)) {
7176
continue;
7277
}

tests/PHPStan/Type/UnionTypeTest.php

+29
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
use Iterator;
99
use PHPStan\Reflection\Native\NativeParameterReflection;
1010
use PHPStan\Reflection\PassedByReference;
11+
use PHPStan\ShouldNotHappenException;
1112
use PHPStan\Testing\PHPStanTestCase;
1213
use PHPStan\TrinaryLogic;
1314
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
15+
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
16+
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
1417
use PHPStan\Type\Accessory\AccessoryNumericStringType;
1518
use PHPStan\Type\Accessory\HasMethodType;
1619
use PHPStan\Type\Accessory\HasOffsetType;
@@ -1640,4 +1643,30 @@ public function dataGetArrays(): iterable
16401643
];
16411644
}
16421645

1646+
/**
1647+
* @param Type[] $types
1648+
*
1649+
* @dataProvider dataUnionThrows
1650+
*/
1651+
public function testUnionThrows(array $types, string $message): void
1652+
{
1653+
$this->expectException(ShouldNotHappenException::class);
1654+
$this->expectExceptionMessage($message);
1655+
1656+
new UnionType($types);
1657+
}
1658+
1659+
public function dataUnionThrows(): array
1660+
{
1661+
return [
1662+
// union type requires at least 2 types
1663+
[[new AccessoryNonEmptyStringType()], 'Cannot create PHPStan\\Type\\UnionType with: non-empty-string'],
1664+
// test invalid combinations
1665+
[[new AccessoryNonFalsyStringType(), new AccessoryNumericStringType()], 'Cannot create PHPStan\\Type\\UnionType with: non-falsy-string, numeric-string'],
1666+
[[new IntegerType(), new AccessoryNumericStringType()], 'Cannot create PHPStan\\Type\\UnionType with: int, numeric-string'],
1667+
[[new ArrayType(new IntegerType(), new StringType()), new AccessoryNonEmptyStringType()], 'Cannot create PHPStan\\Type\\UnionType with: array<int, string>, non-empty-string'],
1668+
[[new IntegerType(), new NonEmptyArrayType()], 'Cannot create PHPStan\\Type\\UnionType with: int, non-empty-array'],
1669+
];
1670+
}
1671+
16431672
}

0 commit comments

Comments
 (0)