← All results

Template variance: covariant type parameters

Group: PHPDoc generics · Category: phpdoc · File: generics_template_covariant.php

A producer annotated @template-covariant T may accept Producer<Child> where Producer<Parent> is required. Without covariance, many tools reject the same assignment. This case checks the *covariant* direction: Child producer used as Parent producer should be accepted when variance is modeled (no diagnostic). References: - PHPStan: template-covariant / call-site variance - Psalm: templated_annotations / variance

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.7Phan 6.0.7 php-ast version 1.1.3 PHP version used to run Phan: 8.5.9 Pass

No diagnostics reported.

phpstan 2.2.15PHPStan - PHP Static Analysis Tool 2.2.15 Pass

No diagnostics reported.

psalm 6.18.0Psalm 6.18.0@536dd6236b39a5115385b0307b42d6d1ad431a02
next: 7.0.0-beta22
Pass

No diagnostics reported.

mago 1.50.0mago 1.50.0 Pass

No diagnostics reported.

mir 0.78.0mir 0.78.0 Pass

No diagnostics reported.

phpantom 0.10.0phpantom_lsp 0.10.0 Pass

No diagnostics reported.

intelephense 1.18.5intelephense 1.18.5 Pass

No diagnostics reported.

phpactor 2026.06.23.0Phpactor 2026.06.23.0 Pass

No diagnostics reported.

phpy 1.0.19274phpy 1.0.19274 Pass

No diagnostics reported.

qodana 262.9437.196Qodana 262.9437.196 Pass

No diagnostics reported.

noverify 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 Pass
generics_template_covariant.php:56: param $producer miss matched with phpdoc type <<Producer<Animal>>> [funcParamTypeMissMatch]
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Pass

No diagnostics reported.

phpstan-strict 2.2.15PHPStan - PHP Static Analysis Tool 2.2.15 Pass

No diagnostics reported.

psalm-next 7.0.0-beta22Psalm 7.0.0-beta22@de27e5724ee5997a1e3baee4d394ca6f4e46eba0 Pass

No diagnostics reported.

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\GenericsTemplateCovariant;

/**
 * Template variance: covariant type parameters.
 *
 * A producer annotated `@template-covariant T` may accept `Producer<Child>`
 * where `Producer<Parent>` is required. Without covariance, many tools reject
 * the same assignment.
 *
 * This case checks the *covariant* direction: Child producer used as Parent
 * producer should be accepted when variance is modeled (no diagnostic).
 *
 * References:
 * - PHPStan: template-covariant / call-site variance
 * - Psalm: templated_annotations / variance
 */

class Animal
{
}

class Dog extends Animal
{
}

/**
 * @template-covariant T
 */
interface Producer
{
    /**
     * @return T
     */
    public function get(): mixed;
}

/**
 * @implements Producer<Dog>
 */
final class DogProducer implements Producer
{
    #[\Override]
    public function get(): Dog
    {
        return new Dog();
    }
}

/**
 * @param Producer<Animal> $producer
 */
function takesAnimalProducer(Producer $producer): void // E<noverify>: NoVerify does not accept generic parameter annotations
{
}

// Dog is a subtype of Animal; covariant T allows Producer<Dog> here.
// A diagnostic here would mean the tool lacks covariant template support
// (or treats Producer as invariant). Optional so non-modeling tools may fail
// silently or warn without failing the suite.
takesAnimalProducer(new DogProducer()); // E?: invariant tools may reject Producer<Dog> as Producer<Animal>