|
19 | 19 | use Psalm\Type\Atomic\TArray;
|
20 | 20 | use Psalm\Type\Atomic\TCallable;
|
21 | 21 | use Psalm\Type\Atomic\TCallableArray;
|
| 22 | +use Psalm\Type\Atomic\TCallableInterface; |
22 | 23 | use Psalm\Type\Atomic\TClassString;
|
23 | 24 | use Psalm\Type\Atomic\TClosure;
|
24 | 25 | use Psalm\Type\Atomic\TKeyedArray;
|
|
41 | 42 | final class CallableTypeComparator
|
42 | 43 | {
|
43 | 44 | /**
|
44 |
| - * @param TCallable|TClosure $input_type_part |
| 45 | + * @param TClosure|TCallableInterface $input_type_part |
45 | 46 | * @param TCallable|TClosure $container_type_part
|
46 | 47 | */
|
47 | 48 | public static function isContainedBy(
|
48 | 49 | Codebase $codebase,
|
49 |
| - Atomic $input_type_part, |
| 50 | + $input_type_part, |
50 | 51 | Atomic $container_type_part,
|
51 | 52 | ?TypeComparisonResult $atomic_comparison_result
|
52 | 53 | ): bool {
|
| 54 | + if ($container_type_part instanceof TClosure) { |
| 55 | + if ($input_type_part instanceof TCallableInterface |
| 56 | + && !$input_type_part instanceof TCallable // it has stricter checks below |
| 57 | + ) { |
| 58 | + if ($atomic_comparison_result) { |
| 59 | + $atomic_comparison_result->type_coerced = true; |
| 60 | + } |
| 61 | + return false; |
| 62 | + } |
| 63 | + } |
| 64 | + if ($input_type_part instanceof TCallableInterface |
| 65 | + && !$input_type_part instanceof TCallable // it has stricter checks below |
| 66 | + ) { |
| 67 | + return true; |
| 68 | + } |
| 69 | + |
53 | 70 | if ($container_type_part->is_pure && !$input_type_part->is_pure) {
|
54 | 71 | if ($atomic_comparison_result) {
|
55 | 72 | $atomic_comparison_result->type_coerced = $input_type_part->is_pure === null;
|
|
0 commit comments