diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php index 27b4bc448..3620c1520 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php @@ -235,6 +235,7 @@ class ClassTemplateParamCollector } } else { if ($template_result !== null) { + $type_extends_atomic = clone $type_extends_atomic; $type_extends_atomic->replaceTemplateTypesWithArgTypes( $template_result, $codebase diff --git a/tests/Template/ClassTemplateTest.php b/tests/Template/ClassTemplateTest.php index ef1cda7ba..91c733e18 100644 --- a/tests/Template/ClassTemplateTest.php +++ b/tests/Template/ClassTemplateTest.php @@ -3764,6 +3764,40 @@ class ClassTemplateTest extends TestCase } }', ], + 'complexTypes' => [ + 'code' => 'v; } + } + + + /** + * @template TTObject + * + * @extends Future> + */ + class FutureB extends Future { + /** @param TTObject $data */ + public function __construct($data) { parent::__construct(new ArrayObject([$data])); } + } + + $a = new FutureB(123); + + $r = $a->get();', + 'assertions' => [ + '$a===' => 'FutureB<123>', + '$r===' => 'ArrayObject' + ] + ] ]; }