diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php index 007d1a6cd..9167c24e0 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php @@ -2129,8 +2129,10 @@ class CallAnalyzer } } } elseif ($class_storage->template_types) { - foreach ($class_storage->template_types as $template_name => $type) { - $template_types[$template_name] = $type; + foreach ($class_storage->template_types as $template_name => $type_map) { + foreach ($type_map as $key => list($type)) { + $template_types[$template_name][$key] = [$type]; + } } } } diff --git a/tests/Template/ClassTemplateExtendsTest.php b/tests/Template/ClassTemplateExtendsTest.php index 5e8637192..8aef9cb36 100644 --- a/tests/Template/ClassTemplateExtendsTest.php +++ b/tests/Template/ClassTemplateExtendsTest.php @@ -3329,6 +3329,56 @@ class ClassTemplateExtendsTest extends TestCase } }' ], + 'sameNamedTemplateDefinedInParentFunction' => [ + 'value = $value; + } + } + + interface Temporal { + /** + * @template T + * @param Query $query + */ + public function execute(Query $query) : void; + } + + /** + * @template T + */ + class Result implements Temporal { + /** @var T **/ + private $value; + + /** + * @param T $value + */ + public function __construct($value) { + $this->value = $value; + } + + public function execute(Query $query) : void {} + } + + /** + * @param Result $result + * @param Query $query + */ + function takesArgs(Result $result, Query $query) : void { + $result->execute($query); + }' + ], ]; }