mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix #4731 - expand out class-bound generic types when evaluating instance method
This commit is contained in:
parent
1f8e80e820
commit
9789b53617
@ -570,7 +570,8 @@ class ArgumentsAnalyzer
|
|||||||
$class_storage,
|
$class_storage,
|
||||||
$self_fq_class_name,
|
$self_fq_class_name,
|
||||||
$calling_class_storage,
|
$calling_class_storage,
|
||||||
$function_storage->template_types ?: []
|
$function_storage->template_types ?: [],
|
||||||
|
$class_generic_params
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($template_types) {
|
if ($template_types) {
|
||||||
|
@ -341,15 +341,20 @@ class CallAnalyzer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This gets all the template params (and their types) that we think
|
||||||
|
* we'll need to know about
|
||||||
|
*
|
||||||
* @return array<string, array<string, Type\Union>>
|
* @return array<string, array<string, Type\Union>>
|
||||||
* @param array<string, non-empty-array<string, Type\Union>> $existing_template_types
|
* @param array<string, non-empty-array<string, Type\Union>> $existing_template_types
|
||||||
|
* @param array<string, array<string, Type\Union>> $class_template_params
|
||||||
*/
|
*/
|
||||||
public static function getTemplateTypesForCall(
|
public static function getTemplateTypesForCall(
|
||||||
\Psalm\Codebase $codebase,
|
\Psalm\Codebase $codebase,
|
||||||
?ClassLikeStorage $declaring_class_storage,
|
?ClassLikeStorage $declaring_class_storage,
|
||||||
?string $appearing_class_name,
|
?string $appearing_class_name,
|
||||||
?ClassLikeStorage $calling_class_storage,
|
?ClassLikeStorage $calling_class_storage,
|
||||||
array $existing_template_types = []
|
array $existing_template_types = [],
|
||||||
|
array $class_template_params = []
|
||||||
) : array {
|
) : array {
|
||||||
$template_types = $existing_template_types;
|
$template_types = $existing_template_types;
|
||||||
|
|
||||||
@ -369,7 +374,7 @@ class CallAnalyzer
|
|||||||
$atomic_type->defining_class,
|
$atomic_type->defining_class,
|
||||||
$atomic_type->param_name,
|
$atomic_type->param_name,
|
||||||
$calling_class_storage->template_extended_params,
|
$calling_class_storage->template_extended_params,
|
||||||
$template_types
|
$class_template_params + $template_types
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$output_type_candidate = new Type\Union([$atomic_type]);
|
$output_type_candidate = new Type\Union([$atomic_type]);
|
||||||
@ -392,7 +397,8 @@ class CallAnalyzer
|
|||||||
} elseif ($declaring_class_storage->template_types) {
|
} elseif ($declaring_class_storage->template_types) {
|
||||||
foreach ($declaring_class_storage->template_types as $template_name => $type_map) {
|
foreach ($declaring_class_storage->template_types as $template_name => $type_map) {
|
||||||
foreach ($type_map as $key => $type) {
|
foreach ($type_map as $key => $type) {
|
||||||
$template_types[$template_name][$key] = $type;
|
$template_types[$template_name][$key]
|
||||||
|
= $class_template_params[$template_name][$key] ?? $type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3770,6 +3770,37 @@ class ClassTemplateTest extends TestCase
|
|||||||
}',
|
}',
|
||||||
'error_message' => 'InvalidArgument',
|
'error_message' => 'InvalidArgument',
|
||||||
],
|
],
|
||||||
|
'bindRedirectedTemplate' => [
|
||||||
|
'<?php
|
||||||
|
/**
|
||||||
|
* @template TIn
|
||||||
|
* @template TOut
|
||||||
|
*/
|
||||||
|
final class Map
|
||||||
|
{
|
||||||
|
/** @param Closure(TIn): TOut $c */
|
||||||
|
public function __construct(private Closure $c) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template TIn2 as list<TIn>
|
||||||
|
* @param TIn2 $in
|
||||||
|
* @return list<TOut>
|
||||||
|
*/
|
||||||
|
public function __invoke(array $in) : array {
|
||||||
|
return array_map(
|
||||||
|
$this->c,
|
||||||
|
$in
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$m = new Map(fn(int $num) => (string) $num);
|
||||||
|
$m(["a"]);',
|
||||||
|
'error_message' => 'InvalidScalarArgument',
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
'8.0'
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user