diff --git a/src/Psalm/Internal/Codebase/Methods.php b/src/Psalm/Internal/Codebase/Methods.php index 940edc9c472..459f8496e3e 100644 --- a/src/Psalm/Internal/Codebase/Methods.php +++ b/src/Psalm/Internal/Codebase/Methods.php @@ -768,8 +768,10 @@ public function getMethodReturnType( $candidate_type ); - if ((!$old_contained_by_new && !$new_contained_by_old) - || ($old_contained_by_new && $new_contained_by_old) + if (((!$old_contained_by_new && !$new_contained_by_old) + || ($old_contained_by_new && $new_contained_by_old)) + && !$candidate_type->hasTemplate() + && !$overridden_storage->return_type->hasTemplate() ) { $attempted_intersection = null; if ($old_contained_by_new) { //implicitly $new_contained_by_old as well diff --git a/tests/Template/ClassTemplateTest.php b/tests/Template/ClassTemplateTest.php index f447f8d8c00..6c40d7a031b 100644 --- a/tests/Template/ClassTemplateTest.php +++ b/tests/Template/ClassTemplateTest.php @@ -16,6 +16,49 @@ class ClassTemplateTest extends TestCase public function providerValidCodeParse(): iterable { return [ + 'templateIntersection' => [ + 'code' => ' + */ + final class FooRepository implements RepositoryInterface + { + /** + * @var Foo[] + */ + public array $elements = []; + + public function byId(string $id): ?Foo + { + return $this->elements[$id] ?? null; + } + } + ' + ], 'cachingIterator' => [ 'code' => '