Skip to content

Inherited templates are not calculated from constructor args #2735

@muglug

Description

@muglug
class Dog {}

/**
 * @template T
 */
class Collection {
    /** @var array<T> */
    protected $arr = [];

    /**
      * @param array<T> $arr
      */
    public function __construct(array $arr) {
        $this->arr = $arr;
    }
	
    /**
     * @return T
     */
    public function last()
    {
        if (!$this->arr) {
            throw new \Exception('bad');
        }
        return end($this->arr);
    }
}

/**
 * @template T
 * @extends Collection<T>
 */
class CollectionChild extends Collection {
}

// inferred as Collection<Dog>
$dogs = new Collection([new Dog(), new Dog()]);

echo $dogs->last(); // error

// inferred as CollectionChild<mixed>
$dogs = new CollectionChild([new Dog(), new Dog()]);

echo $dogs->last(); // no error

Related to #845, as this would be more obvious (without need for echo)

https://phpstan.org/r/68127b38-7e7f-4512-8e18-506d4bec3f09

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions