1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #5211 - prevent infinite loop in template inference

This commit is contained in:
Matt Brown 2021-02-13 16:16:58 -05:00
parent 7e61012359
commit 6fb7423c68
3 changed files with 14 additions and 18 deletions

View File

@ -409,17 +409,13 @@ class NewAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\CallAna
$generic_param_types = null;
if ($storage->template_types) {
$declaring_fq_class_name = $declaring_method_id
? $declaring_method_id->fq_class_name
: $fq_class_name;
foreach ($storage->template_types as $template_name => $base_type) {
if (isset($template_result->upper_bounds[$template_name][$fq_class_name])) {
$generic_param_type
= $template_result->upper_bounds[$template_name][$fq_class_name]->type;
} elseif ($storage->template_extended_params && $template_result->upper_bounds) {
$generic_param_type = self::getGenericParamForOffset(
$declaring_fq_class_name,
$fq_class_name,
$template_name,
$storage->template_extended_params,
array_map(

View File

@ -440,28 +440,18 @@ class CallAnalyzer
bool $mapped = false
): Type\Union {
if (isset($found_generic_params[$template_name][$fq_class_name])) {
if (!$mapped && isset($template_extended_params[$fq_class_name][$template_name])) {
foreach ($template_extended_params[$fq_class_name][$template_name]->getAtomicTypes() as $t) {
if ($t instanceof Type\Atomic\TTemplateParam) {
if ($t->param_name !== $template_name) {
return $t->as;
}
}
}
}
return $found_generic_params[$template_name][$fq_class_name];
}
foreach ($template_extended_params as $type_map) {
foreach ($template_extended_params as $extended_class_name => $type_map) {
foreach ($type_map as $extended_template_name => $extended_type) {
foreach ($extended_type->getAtomicTypes() as $extended_atomic_type) {
if ($extended_atomic_type instanceof Type\Atomic\TTemplateParam
&& $extended_atomic_type->param_name === $template_name
&& $extended_template_name !== $template_name
&& $extended_atomic_type->defining_class === $fq_class_name
) {
return self::getGenericParamForOffset(
$fq_class_name,
$extended_class_name,
$extended_template_name,
$template_extended_params,
$found_generic_params,

View File

@ -4372,6 +4372,16 @@ class ClassTemplateExtendsTest extends TestCase
/** @extends Collection<string> */
class StringCollection extends Collection {}',
],
'noInfiniteLoop' => [
'<?php
/**
* @template TValue
* @template-extends SplObjectStorage<object, TValue>
*/
class ObjectStorage extends SplObjectStorage {}
$foo = new ObjectStorage();'
],
];
}