Skip to content
Open
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
9 changes: 2 additions & 7 deletions src/Type/TypeCombinator.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ public static function doUnion(Type ...$types): Type
$alreadyNormalizedCounter = 0;

$benevolentTypes = [];
$benevolentUnionObject = null;
$neverCount = 0;
// transform A | (B | C) to A | B | C
for ($i = 0; $i < $typesCount; $i++) {
Expand All @@ -273,8 +272,8 @@ public static function doUnion(Type ...$types): Type
continue;
}
if ($types[$i] instanceof BenevolentUnionType) {
if ($types[$i] instanceof TemplateBenevolentUnionType && $benevolentUnionObject === null) {
$benevolentUnionObject = $types[$i];
if ($types[$i] instanceof TemplateType) {
continue;
}
$benevolentTypesCount = 0;
$typesInner = $types[$i]->getTypes();
Expand Down Expand Up @@ -528,10 +527,6 @@ public static function doUnion(Type ...$types): Type
}

if ($tempTypes === []) {
if ($benevolentUnionObject instanceof TemplateBenevolentUnionType) {
return $benevolentUnionObject->withTypes(array_values($types));
}

return new BenevolentUnionType(array_values($types), true);
}
}
Expand Down
35 changes: 35 additions & 0 deletions tests/PHPStan/Analyser/nsrt/template-array-key-union-false.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace TemplateArrayKeyUnionFalse;

use function PHPStan\Testing\assertType;

/**
* @template TKey of array-key
* @template TValue
*/
class Collection
{

/**
* @param TValue|callable(TValue, TKey): bool $value
* @return TKey|false
*/
public function search($value, bool $strict = false)
{
return false;
}

}

/**
* @param Collection<int, string> $ints
* @param Collection<string, string> $strings
* @param Collection<int|string, string> $keys
*/
function test(Collection $ints, Collection $strings, Collection $keys): void
{
assertType('int|false', $ints->search('foo'));
assertType('string|false', $strings->search('foo'));
assertType('int|string|false', $keys->search('foo'));
}
8 changes: 8 additions & 0 deletions tests/PHPStan/Type/TypeCombinatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1982,6 +1982,14 @@ public static function dataUnion(): iterable
TemplateBenevolentUnionType::class,
'T of (int|string) (function foo(), parameter)',
],
[
[
TemplateTypeFactory::create(TemplateTypeScope::createWithFunction('foo'), 'T', new BenevolentUnionType([new IntegerType(), new StringType()]), TemplateTypeVariance::createInvariant()),
new ConstantBooleanType(false),
],
UnionType::class,
'T of (int|string) (function foo(), parameter)|false',
],
[
[
new ConstantStringType(''),
Expand Down
Loading