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
2 changes: 1 addition & 1 deletion src/Type/CallableTypeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static function isParametersAcceptorSuperTypeOf(
if ($treatMixedAsAny) {
$isSuperType = $theirParameter->getType()->acceptsWithReason($ourParameterType, true);
} else {
$isSuperType = new AcceptsResult($theirParameter->getType()->isSuperTypeOf($ourParameterType), []);
$isSuperType = new AcceptsResult($ourParameterType->isSuperTypeOf($theirParameter->getType()), []);
}

if ($isSuperType->maybe()) {
Expand Down
58 changes: 58 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-11285.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php // lint >= 8.0

declare(strict_types = 1);

namespace Bug11285;

use function PHPStan\Testing\assertType;

/**
* @template T
* @template U
*/
class Templated
{

/**
* @param callable(T|U): void $callback
*/
public function compare(callable $callback): void {

}
}

class ClassA {}
class ClassB {}


class Test
{
/**
* @param Templated<ClassA, ClassB>|Templated<ClassA, ClassA> $t
*/
public function broken(
Templated $t,
): void
{
$t->compare(
static function (ClassA|ClassB $crate): void {
assertType('Bug11285\\ClassA|Bug11285\\ClassB', $crate);
}
);
}

/**
* @param Templated<ClassA, ClassB> $t
*/
public function working(
Templated $t,
): void
{
$t->compare(
static function (ClassA|ClassB $crate): void {
assertType('Bug11285\\ClassA|Bug11285\\ClassB', $crate);
}
);
}

}
4 changes: 2 additions & 2 deletions tests/PHPStan/Type/CallableTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ public function dataIsSuperTypeOf(): array
[
new CallableType([new NativeParameterReflection('foo', false, new MixedType(), PassedByReference::createNo(), false, null)], new MixedType(), false),
new CallableType([new NativeParameterReflection('foo', false, new IntegerType(), PassedByReference::createNo(), false, null)], new MixedType(), false),
TrinaryLogic::createMaybe(),
TrinaryLogic::createYes(),
],
[
new CallableType([new NativeParameterReflection('foo', false, new IntegerType(), PassedByReference::createNo(), false, null)], new MixedType(), false),
new CallableType([new NativeParameterReflection('foo', false, new MixedType(), PassedByReference::createNo(), false, null)], new MixedType(), false),
TrinaryLogic::createYes(),
TrinaryLogic::createMaybe(),
],
[
new CallableType([
Expand Down
31 changes: 31 additions & 0 deletions tests/PHPStan/Type/TypeCombinatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use ObjectShapesAcceptance\ClassWithFooIntProperty;
use PHPStan\Fixture\FinalClass;
use PHPStan\Reflection\Callables\SimpleImpurePoint;
use PHPStan\Reflection\Php\DummyParameter;
use PHPStan\Testing\PHPStanTestCase;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
Expand Down Expand Up @@ -2568,6 +2569,36 @@ public function dataUnion(): iterable
ClosureType::class,
'Closure(): mixed',
];
yield [
[
new CallableType([
new DummyParameter('callback', new ObjectType('stdClass'), false, null, false, null),
], new VoidType(), false),
new CallableType([
new DummyParameter('callback', new UnionType([
new ObjectType('stdClass'),
new ObjectType('Exception'),
]), false, null, false, null),
], new VoidType(), false),
],
CallableType::class,
'callable(Exception|stdClass): void',
];
yield [
[
new CallableType([
new DummyParameter('callback', new ObjectType('stdClass'), false, null, false, null),
], new VoidType(), false),
new CallableType([
new DummyParameter('callback', new UnionType([
new IntegerType(),
new ObjectType('Exception'),
]), false, null, false, null),
], new VoidType(), false),
],
UnionType::class,
'(callable(Exception|int): void)|(callable(stdClass): void)',
];
}

/**
Expand Down