mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Allow more callable types as subtypes of callable
Fixes vimeo/psalm#10461
This commit is contained in:
parent
c511185fbe
commit
20c788911f
@ -8,6 +8,7 @@ use Psalm\Type\Atomic;
|
||||
use Psalm\Type\Atomic\Scalar;
|
||||
use Psalm\Type\Atomic\TArray;
|
||||
use Psalm\Type\Atomic\TCallable;
|
||||
use Psalm\Type\Atomic\TCallableArray;
|
||||
use Psalm\Type\Atomic\TCallableKeyedArray;
|
||||
use Psalm\Type\Atomic\TCallableObject;
|
||||
use Psalm\Type\Atomic\TCallableString;
|
||||
@ -191,7 +192,12 @@ final class AtomicTypeComparator
|
||||
}
|
||||
|
||||
if (($container_type_part instanceof TCallable
|
||||
&& $input_type_part instanceof TCallable)
|
||||
&& ($input_type_part instanceof TCallable
|
||||
|| $input_type_part instanceof TCallableArray
|
||||
|| $input_type_part instanceof TCallableObject
|
||||
|| $input_type_part instanceof TCallableString
|
||||
|| $input_type_part instanceof TCallableKeyedArray
|
||||
))
|
||||
|| ($container_type_part instanceof TClosure
|
||||
&& $input_type_part instanceof TClosure)
|
||||
) {
|
||||
|
@ -19,6 +19,9 @@ use Psalm\Type\Atomic;
|
||||
use Psalm\Type\Atomic\TArray;
|
||||
use Psalm\Type\Atomic\TCallable;
|
||||
use Psalm\Type\Atomic\TCallableArray;
|
||||
use Psalm\Type\Atomic\TCallableKeyedArray;
|
||||
use Psalm\Type\Atomic\TCallableObject;
|
||||
use Psalm\Type\Atomic\TCallableString;
|
||||
use Psalm\Type\Atomic\TClassString;
|
||||
use Psalm\Type\Atomic\TClosure;
|
||||
use Psalm\Type\Atomic\TKeyedArray;
|
||||
@ -41,7 +44,7 @@ use function substr;
|
||||
final class CallableTypeComparator
|
||||
{
|
||||
/**
|
||||
* @param TCallable|TClosure $input_type_part
|
||||
* @param TCallable|TClosure|TCallableArray|TCallableString|TCallableKeyedArray|TCallableObject $input_type_part
|
||||
* @param TCallable|TClosure $container_type_part
|
||||
*/
|
||||
public static function isContainedBy(
|
||||
@ -50,6 +53,26 @@ final class CallableTypeComparator
|
||||
Atomic $container_type_part,
|
||||
?TypeComparisonResult $atomic_comparison_result
|
||||
): bool {
|
||||
if ($container_type_part instanceof TClosure) {
|
||||
if ($input_type_part instanceof TCallableArray
|
||||
|| $input_type_part instanceof TCallableString
|
||||
|| $input_type_part instanceof TCallableKeyedArray
|
||||
|| $input_type_part instanceof TCallableObject
|
||||
) {
|
||||
if ($atomic_comparison_result) {
|
||||
$atomic_comparison_result->type_coerced = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($input_type_part instanceof TCallableArray
|
||||
|| $input_type_part instanceof TCallableString
|
||||
|| $input_type_part instanceof TCallableKeyedArray
|
||||
|| $input_type_part instanceof TCallableObject
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($container_type_part->is_pure && !$input_type_part->is_pure) {
|
||||
if ($atomic_comparison_result) {
|
||||
$atomic_comparison_result->type_coerced = $input_type_part->is_pure === null;
|
||||
|
@ -1920,6 +1920,21 @@ class CallableTest extends TestCase
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '8.0',
|
||||
],
|
||||
'callableArrayPassedAsCallable' => [
|
||||
'code' => <<<'PHP'
|
||||
<?php
|
||||
function f(callable $c): void {
|
||||
$c();
|
||||
}
|
||||
/** @var object $o */;
|
||||
|
||||
$ca = [$o::class, 'createFromFormat'];
|
||||
if (!is_callable($ca)) {
|
||||
exit;
|
||||
}
|
||||
f($ca);
|
||||
PHP,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -163,6 +163,22 @@ class TypeComparatorTest extends TestCase
|
||||
'(callable(int,string[]): void)|(callable(int): void)',
|
||||
'(callable(int): void)|(callable(int,string[]): void)',
|
||||
],
|
||||
'callableAcceptsCallableArray' => [
|
||||
'callable',
|
||||
"callable-array{0: class-string, 1: 'from'}",
|
||||
],
|
||||
'callableAcceptsCallableObject' => [
|
||||
'callable',
|
||||
"callable-object",
|
||||
],
|
||||
'callableAcceptsCallableString' => [
|
||||
'callable',
|
||||
'callable-string',
|
||||
],
|
||||
'callableAcceptsCallableKeyedList' => [
|
||||
'callable',
|
||||
"callable-list{class-string, 'from'}",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user