Bug report
Using v0.12.31
When declaring type implementing or extending a generic type, when this type is passed as a parameter or as a return, it is not considered a subclass of the generic type it implements or extend.
Code snippet that reproduces the problem
<?php
declare(strict_types=1);
interface Entity{}
final class Dish implements Entity
{
}
/**
* @template T of Entity
*/
interface Filter {}
/**
* @extends Filter<Dish>
*/
interface DishFilter extends Filter {}
/**
* @extends SearchDoctrineRepository<Dish>
*/
final class DishDoctrineRepository extends SearchDoctrineRepository
{
/**
* @return array<Dish>
*/
public function filter(DishFilter $filter): array
{
return parent::filterEntities($filter);
}
}
/**
* @template T of Entity
*/
abstract class SearchDoctrineRepository
{
/**
* @param Filter<T> $filter
*
* @return array<T>
*/
public function filterEntities(Filter $filter): array
{
return [];
}
}
This code raises the following errors:
Method DishDoctrineRepository::filter() should return array<Dish> but returns array<Entity>.
Parameter #1 $filter of method SearchDoctrineRepository<Entity>::filterEntities() expects Filter<Entity>, DishFilter given.
It can be found here https://phpstan.org/r/5200477a-9300-454d-bca8-59511b8c51d3
Expected output
Given that DishDoctrineRepository extends SearchDoctrineRepository<Dish> I expect the return type of filterEntities() to be array<Dish> and not array<Entity> as it is detected.
And because DishFilter extends Filter<Dish>, when the method expects Filter<Dish>, it should allow to get a DishFilter.
Am I doing something wrong here?
Bug report
Using v0.12.31
When declaring type implementing or extending a generic type, when this type is passed as a parameter or as a return, it is not considered a subclass of the generic type it implements or extend.
Code snippet that reproduces the problem
This code raises the following errors:
Method DishDoctrineRepository::filter() should return array<Dish> but returns array<Entity>.Parameter #1 $filter of method SearchDoctrineRepository<Entity>::filterEntities() expects Filter<Entity>, DishFilter given.It can be found here https://phpstan.org/r/5200477a-9300-454d-bca8-59511b8c51d3
Expected output
Given that
DishDoctrineRepositoryextendsSearchDoctrineRepository<Dish>I expect the return type offilterEntities()to bearray<Dish>and notarray<Entity>as it is detected.And because
DishFilterextendsFilter<Dish>, when the method expectsFilter<Dish>, it should allow to get aDishFilter.Am I doing something wrong here?